[rfc][rft (procfs, nto-procfs)] Fix signal bypass heuristic with software single-step

Ulrich Weigand
2011-03-18T20:21:19Z

Hello,

several targets today implement a performance optimization where some signals
are not reported back to the GDB core, but instead are directly delivered to
the target; this can be done either by not even trapping those signals (e.g.
procfs targets), by restarting the inferior directly in target code (e.g.
linux-nat), or by restarting the inferior in the remote stub.

This works via a target callback to_notice_signal, which is called whenever
the list of signals to be handled by GDB changes. Target code is then
expected to itself detect which signals are safe to short-circuit (by calling
signal_pass_state) etc. Target code must also handle (implicitly defined)
special cases, e.g. that signals must always be reported during startup
or when single-stepping.

It is this last condition that causes problems on architectures that use
software single-step, because target code isn't even aware of that
condition in general. This causes failures on ARM, see the discussion here:
http://sourceware.org/ml/gdb-patches/2011-01/msg00398.html

The solution that was discussed there is basically to make the implicit
rules of signal passing shortcuts explicit. The patch below is an
attempt to implement this idea. The basic concept is to remove the
to_notice_signals callback and replace it by a to_pass_signals callback,
which explicitly gets a list of signals that can be safely bypassed
at this point.

Common code then calls this new target callback as appropriate, in
particular to mark all signals non-bypassable when single-stepping.

All platforms using to_notice_signals (procfs, nto-procfs, remote)
or directly accessing signal_pass_state etc (linux-nat) are updated
to instead use the to_pass_signals callback.

Tested on i386-linux, both native and gdbserver, with no regressions.
Fixes the same set of failures on ARM as the original patch.

Any thoughts on this approach?

I'm unable to test on any procfs or nto-procfs target; I'd much
appreciate if anyone with access to those targets could help me out here ...

Thanks,
Ulrich

ChangeLog:

* target.h (struct target_ops): Remove to_notice_signals;
add to_pass_signals.
(target_notice_signals): Remove.
(target_pass_signals): Add prototype.
* target.c (update_current_target): Remove to_notice_signals;
mention to_pass_signals.
(target_pass_signals): New function.
(debug_to_notice_signals): Remove.
(setup_target_debug): Do not install debug_to_notice_signals.

* infrun.c (signal_pass): New global.
(resume): Call target_pass_signals.
(signal_cache_update): New function.
(signal_stop_update): Call it.
(signal_print_update): Likewise.
(signal_pass_update): Likewise.
(handle_command): Call signal_cache_update and target_pass_signals
instead of target_notice_signals.
(_initialize_infrun): Initialize signal_pass.

* linux-nat.c (pass_mask): New global.
(linux_nat_pass_signals): New function.
(linux_nat_create_inferior): Report all signals initially.
(linux_nat_attach): Likewise.
(linux_nat_resume): Use pass_mask to decide whether to directly
handle an inferior signal.
(linux_nat_wait_1): Likewise.
(linux_nat_add_target): Install to_pass_signals callback.

* nto-procfs.c (notice_signals): Remove.
(procfs_resume): Do not call notice_signals.
(procfs_notice_signals): Remove.
(procfs_pass_signals): New function.
(init_procfs_ops): Install to_pass_signals callback instead of
to_notice_signals callback.
(_initialize_procfs): Report all signals initially.

* procfs.c (procfs_notice_signals): Remove.
(procfs_pass_signals): New function.
(procfs_target): Install to_pass_signals callback instead of
to_notice_signals callback.
(register_gdb_signals): Remove.
(procfs_debug_inferior): Report all signals initially.
(procfs_init_inferior): Remove redundant register_gdb_signals call.

* remote.c (remote_pass_signals): Add numsigs and pass_signals
parameters; use them instead of calling signal_..._state routines.
(remote_notice_signals): Remove.
(remote_start_remote): Report all signals initially.
(remote_resume): Do not call remote_pass_signals.
(_initialize_remote): Install to_pass_signals callback instead of
to_notice_signals callback.

Index: gdb/infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.472
diff -u -p -r1.472 infrun.c
--- gdb/infrun.c 7 Mar 2011 16:03:00 -0000 1.472
+++ gdb/infrun.c 18 Mar 2011 17:23:18 -0000
@@ -276,6 +276,11 @@ static unsigned char *signal_stop;
static unsigned char *signal_print;
static unsigned char *signal_program;

+/* Table of signals that the target may silently handle.
+ This is automatically determined from the flags above,
+ and simply cached here. */
+static unsigned char *signal_pass;
+
#define SET_SIGS(nsigs,sigs,flags) \
do { \
int signum = (nsigs); \
@@ -1787,6 +1792,13 @@ a command like `return' or `jump' to con
happens to apply to another thread. */
tp->suspend.stop_signal = TARGET_SIGNAL_0;

+ /* Advise target which signals may be handled silently. If we are
+ currently stepping, we need to receive all signals. */
+ if (step || singlestep_breakpoints_inserted_p)
+ target_pass_signals (0, NULL);
+ else
+ target_pass_signals ((int) TARGET_SIGNAL_LAST, signal_pass);
+
target_resume (resume_ptid, step, sig);
}

@@ -5853,12 +5865,29 @@ signal_pass_state (int signo)
return signal_program[signo];
}

+static void
+signal_cache_update (int signo)
+{
+ if (signo == -1)
+ {
+ for (signo = 0; signo < (int) TARGET_SIGNAL_LAST; signo++)
+ signal_cache_update (signo);
+
+ return;
+ }
+
+ signal_pass[signo] = (signal_stop[signo] == 0
+ && signal_print[signo] == 0
+ && signal_program[signo] == 1);
+}
+
int
signal_stop_update (int signo, int state)
{
int ret = signal_stop[signo];

signal_stop[signo] = state;
+ signal_cache_update (signo);
return ret;
}

@@ -5868,6 +5897,7 @@ signal_print_update (int signo, int stat
int ret = signal_print[signo];

signal_print[signo] = state;
+ signal_cache_update (signo);
return ret;
}

@@ -5877,6 +5907,7 @@ signal_pass_update (int signo, int state
int ret = signal_program[signo];

signal_program[signo] = state;
+ signal_cache_update (signo);
return ret;
}

@@ -6068,7 +6099,8 @@ Are you sure you want to change it? "),
for (signum = 0; signum < nsigs; signum++)
if (sigs[signum])
{
- target_notice_signals (inferior_ptid);
+ signal_cache_update (-1);
+ target_pass_signals ((int) TARGET_SIGNAL_LAST, signal_pass);

if (from_tty)
{
@@ -6925,6 +6957,8 @@ leave it stopped or free to run as neede
xmalloc (sizeof (signal_print[0]) * numsigs);
signal_program = (unsigned char *)
xmalloc (sizeof (signal_program[0]) * numsigs);
+ signal_pass = (unsigned char *)
+ xmalloc (sizeof (signal_program[0]) * numsigs);
for (i = 0; i < numsigs; i++)
{
signal_stop[i] = 1;
@@ -6968,6 +7002,9 @@ leave it stopped or free to run as neede
signal_stop[TARGET_SIGNAL_CANCEL] = 0;
signal_print[TARGET_SIGNAL_CANCEL] = 0;

+ /* Update cached state. */
+ signal_cache_update (-1);
+
add_setshow_zinteger_cmd ("stop-on-solib-events", class_support,
&stop_on_solib_events, _("\
Set stopping for shared library events."), _("\
Index: gdb/linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-nat.c,v
retrieving revision 1.199
diff -u -p -r1.199 linux-nat.c
--- gdb/linux-nat.c 9 Mar 2011 12:48:55 -0000 1.199
+++ gdb/linux-nat.c 18 Mar 2011 17:23:19 -0000
@@ -1078,6 +1078,26 @@ restore_child_signals_mask (sigset_t *pr
{
sigprocmask (SIG_SETMASK, prev_mask, NULL);
}
+
+/* Mask of signals to pass directly to the inferior. */
+static sigset_t pass_mask;
+
+/* Update signals to pass to the inferior. */
+static void
+linux_nat_pass_signals (int numsigs, unsigned char *pass_signals)
+{
+ int signo;
+
+ sigemptyset (&pass_mask);
+
+ for (signo = 1; signo < NSIG; signo++)
+ {
+ int target_signo = target_signal_from_host (signo);
+ if (target_signo < numsigs && pass_signals[target_signo])
+ sigaddset (&pass_mask, signo);
+ }
+}
+
\f

/* Prototypes for local functions. */
@@ -1543,6 +1563,9 @@ linux_nat_create_inferior (struct target
}
#endif /* HAVE_PERSONALITY */

+ /* Make sure we report all signals during startup. */
+ linux_nat_pass_signals (0, NULL);
+
linux_ops->to_create_inferior (ops, exec_file, allargs, env, from_tty);

#ifdef HAVE_PERSONALITY
@@ -1564,6 +1587,9 @@ linux_nat_attach (struct target_ops *ops
int status;
ptid_t ptid;

+ /* Make sure we report all signals during attach. */
+ linux_nat_pass_signals (0, NULL);
+
linux_ops->to_attach (ops, args, from_tty);

/* The ptrace base target adds the main thread with (pid,0,0)
@@ -1922,19 +1948,8 @@ linux_nat_resume (struct target_ops *ops

if (lp->status && WIFSTOPPED (lp->status))
{
- enum target_signal saved_signo;
- struct inferior *inf;
-
- inf = find_inferior_pid (ptid_get_pid (lp->ptid));
- gdb_assert (inf);
- saved_signo = target_signal_from_host (WSTOPSIG (lp->status));
-
- /* Defer to common code if we're gaining control of the
- inferior. */
- if (inf->control.stop_soon == NO_STOP_QUIETLY
- && signal_stop_state (saved_signo) == 0
- && signal_print_state (saved_signo) == 0
- && signal_pass_state (saved_signo) == 1)
+ if (WSTOPSIG (lp->status)
+ && sigismember (&pass_mask, WSTOPSIG (lp->status)))
{
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
@@ -1944,7 +1959,7 @@ linux_nat_resume (struct target_ops *ops
/* FIXME: What should we do if we are supposed to continue
this thread with a signal? */
gdb_assert (signo == TARGET_SIGNAL_0);
- signo = saved_signo;
+ signo = target_signal_from_host (WSTOPSIG (lp->status));
lp->status = 0;
}
}
@@ -3590,20 +3605,8 @@ retry:
if (WIFSTOPPED (status))
{
enum target_signal signo = target_signal_from_host (WSTOPSIG (status));
- struct inferior *inf;
-
- inf = find_inferior_pid (ptid_get_pid (lp->ptid));
- gdb_assert (inf);

- /* Defer to common code if we get a signal while
- single-stepping, since that may need special care, e.g. to
- skip the signal handler, or, if we're gaining control of the
- inferior. */
- if (!lp->step
- && inf->control.stop_soon == NO_STOP_QUIETLY
- && signal_stop_state (signo) == 0
- && signal_print_state (signo) == 0
- && signal_pass_state (signo) == 1)
+ if (WSTOPSIG (status) && sigismember (&pass_mask, WSTOPSIG (status)))
{
/* FIMXE: kettenis/2001-06-06: Should we resume all threads
here? It is not clear we should. GDB may not expect
@@ -5712,6 +5715,7 @@ linux_nat_add_target (struct target_ops
t->to_detach = linux_nat_detach;
t->to_resume = linux_nat_resume;
t->to_wait = linux_nat_wait;
+ t->to_pass_signals = linux_nat_pass_signals;
t->to_xfer_partial = linux_nat_xfer_partial;
t->to_kill = linux_nat_kill;
t->to_mourn_inferior = linux_nat_mourn_inferior;
Index: gdb/nto-procfs.c
===================================================================
RCS file: /cvs/src/src/gdb/nto-procfs.c,v
retrieving revision 1.57
diff -u -p -r1.57 nto-procfs.c
--- gdb/nto-procfs.c 11 Jan 2011 15:10:01 -0000 1.57
+++ gdb/nto-procfs.c 18 Mar 2011 17:23:19 -0000
@@ -64,8 +64,6 @@ static int procfs_xfer_memory (CORE_ADDR
struct mem_attrib *attrib,
struct target_ops *);

-static void notice_signals (void);
-
static void init_procfs_ops (void);

static ptid_t do_attach (ptid_t ptid);
@@ -983,8 +981,6 @@ procfs_resume (struct target_ops *ops,

run.flags |= _DEBUG_RUN_ARM;

- sigemptyset (&run.trace);
- notice_signals ();
signal_to_pass = target_signal_to_host (signo);

if (signal_to_pass)
@@ -1332,34 +1328,23 @@ procfs_store_registers (struct target_op
}
}

+/* Set list of signals to be handled in the target. */
+
static void
-notice_signals (void)
+procfs_pass_signals (int numsigs, unsigned char *pass_signals)
{
int signo;

+ sigfillset (&run.trace);
+
for (signo = 1; signo < NSIG; signo++)
{
- if (signal_stop_state (target_signal_from_host (signo)) == 0
- && signal_print_state (target_signal_from_host (signo)) == 0
- && signal_pass_state (target_signal_from_host (signo)) == 1)
- sigdelset (&run.trace, signo);
- else
- sigaddset (&run.trace, signo);
+ int target_signo = target_signal_from_host (signo);
+ if (target_signo < numsigs && pass_signals[target_signo])
+ sigdelset (&run.trace, signo);
}
}

-/* When the user changes the state of gdb's signal handling via the
- "handle" command, this function gets called to see if any change
- in the /proc interface is required. It is also called internally
- by other /proc interface functions to initialize the state of
- the traced signal set. */
-static void
-procfs_notice_signals (ptid_t ptid)
-{
- sigemptyset (&run.trace);
- notice_signals ();
-}
-
static struct tidinfo *
procfs_thread_info (pid_t pid, short tid)
{
@@ -1424,7 +1409,7 @@ init_procfs_ops (void)
procfs_ops.to_create_inferior = procfs_create_inferior;
procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
procfs_ops.to_can_run = procfs_can_run;
- procfs_ops.to_notice_signals = procfs_notice_signals;
+ procfs_ops.to_pass_signals = procfs_pass_signals;
procfs_ops.to_thread_alive = procfs_thread_alive;
procfs_ops.to_find_new_threads = procfs_find_new_threads;
procfs_ops.to_pid_to_str = procfs_pid_to_str;
@@ -1456,8 +1441,8 @@ _initialize_procfs (void)
sigaddset (&set, SIGUSR1);
sigprocmask (SIG_BLOCK, &set, NULL);

- /* Set up trace and fault sets, as gdb expects them. */
- sigemptyset (&run.trace);
+ /* Initially, make sure all signals are reported. */
+ sigfillset (&run.trace);

/* Stuff some information. */
nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags;
Index: gdb/procfs.c
===================================================================
RCS file: /cvs/src/src/gdb/procfs.c,v
retrieving revision 1.143
diff -u -p -r1.143 procfs.c
--- gdb/procfs.c 9 Mar 2011 12:48:55 -0000 1.143
+++ gdb/procfs.c 18 Mar 2011 17:23:20 -0000
@@ -120,7 +120,7 @@ static void procfs_fetch_registers (stru
struct regcache *, int);
static void procfs_store_registers (struct target_ops *,
struct regcache *, int);
-static void procfs_notice_signals (ptid_t);
+static void procfs_pass_signals (ptid_t, int, unsigned char *);
static void procfs_kill_inferior (struct target_ops *ops);
static void procfs_mourn_inferior (struct target_ops *ops);
static void procfs_create_inferior (struct target_ops *, char *,
@@ -201,7 +201,7 @@ procfs_target (void)
t->to_store_registers = procfs_store_registers;
t->to_xfer_partial = procfs_xfer_partial;
t->deprecated_xfer_memory = procfs_xfer_memory;
- t->to_notice_signals = procfs_notice_signals;
+ t->to_pass_signals = procfs_pass_signals;
t->to_files_info = procfs_files_info;
t->to_stop = procfs_stop;

@@ -3147,7 +3147,6 @@ proc_iterate_over_threads (procinfo *pi,

static ptid_t do_attach (ptid_t ptid);
static void do_detach (int signo);
-static int register_gdb_signals (procinfo *, gdb_sigset_t *);
static void proc_trace_syscalls_1 (procinfo *pi, int syscallnum,
int entry_or_exit, int mode, int from_tty);

@@ -3186,9 +3185,9 @@ procfs_debug_inferior (procinfo *pi)
if (!proc_set_traced_faults (pi, &traced_faults))
return __LINE__;

- /* Register to trace selected signals in the child. */
- premptyset (&traced_signals);
- if (!register_gdb_signals (pi, &traced_signals))
+ /* Initially, register to trace all signals in the child. */
+ prfillset (&traced_signals);
+ if (!proc_set_traced_signals (pi, &traced_signals))
return __LINE__;

@@ -4464,40 +4463,26 @@ procfs_resume (struct target_ops *ops,
}
}

-/* Traverse the list of signals that GDB knows about (see "handle"
- command), and arrange for the target to be stopped or not,
- according to these settings. Returns non-zero for success, zero
- for failure. */
-
-static int
-register_gdb_signals (procinfo *pi, gdb_sigset_t *signals)
-{
- int signo;
-
- for (signo = 0; signo < NSIG; signo ++)
- if (signal_stop_state (target_signal_from_host (signo)) == 0 &&
- signal_print_state (target_signal_from_host (signo)) == 0 &&
- signal_pass_state (target_signal_from_host (signo)) == 1)
- gdb_prdelset (signals, signo);
- else
- gdb_praddset (signals, signo);
-
- return proc_set_traced_signals (pi, signals);
-}
-
/* Set up to trace signals in the child process. */

static void
-procfs_notice_signals (ptid_t ptid)
+procfs_pass_signals (int numsigs, unsigned char *pass_signals)
{
gdb_sigset_t signals;
- procinfo *pi = find_procinfo_or_die (PIDGET (ptid), 0);
+ procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+ int signo;

- if (proc_get_traced_signals (pi, &signals) &&
- register_gdb_signals (pi, &signals))
- return;
- else
- proc_error (pi, "notice_signals", __LINE__);
+ prfillset (&signals);
+
+ for (signo = 0; signo < NSIG; signo++)
+ {
+ int target_signo = target_signal_from_host (signo);
+ if (target_signo < numsigs && pass_signals[target_signo])
+ gdb_prdelset (&signals, signo);
+ }
+
+ if (!proc_set_traced_signals (pi, &signals))
+ proc_error (pi, "pass_signals", __LINE__);
}

/* Print status information about the child process. */
@@ -4679,11 +4664,6 @@ procfs_init_inferior (struct target_ops
if (!proc_get_traced_sysexit (pi, pi->saved_exitset))
proc_error (pi, "init_inferior, get_traced_sysexit", __LINE__);

- /* Register to trace selected signals in the child. */
- prfillset (&signals);
- if (!register_gdb_signals (pi, &signals))
- proc_error (pi, "init_inferior, register_signals", __LINE__);
-
if ((fail = procfs_debug_inferior (pi)) != 0)
proc_error (pi, "init_inferior (procfs_debug_inferior)", fail);

Index: gdb/remote.c
===================================================================
RCS file: /cvs/src/src/gdb/remote.c,v
retrieving revision 1.440
diff -u -p -r1.440 remote.c
--- gdb/remote.c 16 Mar 2011 17:59:02 -0000 1.440
+++ gdb/remote.c 18 Mar 2011 17:23:21 -0000
@@ -1559,20 +1559,17 @@ static char *last_pass_packet;
it can simply pass through to the inferior without reporting. */

static void
-remote_pass_signals (void)
+remote_pass_signals (int numsigs, unsigned char *pass_signals)
{
if (remote_protocol_packets[PACKET_QPassSignals].support != PACKET_DISABLE)
{
char *pass_packet, *p;
- int numsigs = (int) TARGET_SIGNAL_LAST;
int count = 0, i;

gdb_assert (numsigs < 256);
for (i = 0; i < numsigs; i++)
{
- if (signal_stop_state (i) == 0
- && signal_print_state (i) == 0
- && signal_pass_state (i) == 1)
+ if (pass_signals[i])
count++;
}
pass_packet = xmalloc (count * 3 + strlen ("QPassSignals:") + 1);
@@ -1580,9 +1577,7 @@ remote_pass_signals (void)
p = pass_packet + strlen (pass_packet);
for (i = 0; i < numsigs; i++)
{
- if (signal_stop_state (i) == 0
- && signal_print_state (i) == 0
- && signal_pass_state (i) == 1)
+ if (pass_signals[i])
{
if (i >= 16)
*p++ = tohex (i >> 4);
@@ -1612,14 +1607,6 @@ remote_pass_signals (void)
}
}

-static void
-remote_notice_signals (ptid_t ptid)
-{
- /* Update the remote on signals to silently pass, if they've
- changed. */
- remote_pass_signals ();
-}
-
/* If PTID is MAGIC_NULL_PTID, don't set any thread. If PTID is
MINUS_ONE_PTID, set the thread to -1, so the stub returns the
thread. If GEN is set, set the general thread, if not, then set
@@ -3355,10 +3342,8 @@ remote_start_remote (struct ui_out *uiou
the stop reply queue. */
gdb_assert (wait_status == NULL);

- /* Update the remote on signals to silently pass, or more
- importantly, which to not ignore, in case a previous session
- had set some different set of signals to be ignored. */
- remote_pass_signals ();
+ /* Report all signals during attach/startup. */
+ remote_pass_signals (0, NULL);
}

/* If we connected to a live target, do some additional setup. */
@@ -4528,9 +4513,6 @@ remote_resume (struct target_ops *ops,
last_sent_signal = siggnal;
last_sent_step = step;

- /* Update the inferior on signals to silently pass, if they've changed. */
- remote_pass_signals ();
-
/* The vCont packet doesn't need to specify threads via Hc. */
/* No reverse support (yet) for vCont. */
if (execution_direction != EXEC_REVERSE)
@@ -10272,7 +10254,7 @@ Specify the serial device it is connecte
remote_ops.to_kill = remote_kill;
remote_ops.to_load = generic_load;
remote_ops.to_mourn_inferior = remote_mourn;
- remote_ops.to_notice_signals = remote_notice_signals;
+ remote_ops.to_pass_signals = remote_pass_signals;
remote_ops.to_thread_alive = remote_thread_alive;
remote_ops.to_find_new_threads = remote_threads_info;
remote_ops.to_pid_to_str = remote_pid_to_str;
Index: gdb/target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.279
diff -u -p -r1.279 target.c
--- gdb/target.c 17 Mar 2011 13:19:24 -0000 1.279
+++ gdb/target.c 18 Mar 2011 17:23:22 -0000
@@ -149,8 +149,6 @@ static void debug_to_load (char *, int);

static int debug_to_can_run (void);

-static void debug_to_notice_signals (ptid_t);
-
static void debug_to_stop (ptid_t);

/* Pointer to array of target architecture structures; the size of the
@@ -624,7 +622,7 @@ update_current_target (void)
INHERIT (to_has_exited, t);
/* Do not inherit to_mourn_inferior. */
INHERIT (to_can_run, t);
- INHERIT (to_notice_signals, t);
+ /* Do not inherit to_pass_signals. */
/* Do not inherit to_thread_alive. */
/* Do not inherit to_find_new_threads. */
/* Do not inherit to_pid_to_str. */
@@ -792,9 +790,6 @@ update_current_target (void)
return_zero);
de_fault (to_can_run,
return_zero);
- de_fault (to_notice_signals,
- (void (*) (ptid_t))
- target_ignore);
de_fault (to_extra_thread_info,
(char *(*) (struct thread_info *))
return_zero);
@@ -2586,6 +2581,37 @@ target_resume (ptid_t ptid, int step, en

noprocess ();
}
+
+void
+target_pass_signals (int numsigs, unsigned char *pass_signals)
+{
+ struct target_ops *t;
+
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ {
+ if (t->to_pass_signals != NULL)
+ {
+ if (targetdebug)
+ {
+ int i;
+
+ fprintf_unfiltered (gdb_stdlog, "target_pass_signals (%d, {",
+ numsigs);
+
+ for (i = 0; i < numsigs; i++)
+ if (pass_signals[i])
+ fprintf_unfiltered (gdb_stdlog, " %s",
+ target_signal_to_name (i));
+
+ fprintf_unfiltered (gdb_stdlog, " })\n");
+ }
+
+ (*t->to_pass_signals) (numsigs, pass_signals);
+ return;
+ }
+ }
+}
+
/* Look through the list of possible targets for a target that can
follow forks. */

@@ -3898,15 +3924,6 @@ debug_to_can_run (void)
return retval;
}

-static void
-debug_to_notice_signals (ptid_t ptid)
-{
- debug_target.to_notice_signals (ptid);
-
- fprintf_unfiltered (gdb_stdlog, "target_notice_signals (%d)\n",
- PIDGET (ptid));
-}
-
static struct gdbarch *
debug_to_thread_architecture (struct target_ops *ops, ptid_t ptid)
{
@@ -3994,7 +4011,6 @@ setup_target_debug (void)
current_target.to_remove_exec_catchpoint = debug_to_remove_exec_catchpoint;
current_target.to_has_exited = debug_to_has_exited;
current_target.to_can_run = debug_to_can_run;
- current_target.to_notice_signals = debug_to_notice_signals;
current_target.to_stop = debug_to_stop;
current_target.to_rcmd = debug_to_rcmd;
current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
Index: gdb/target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.202
diff -u -p -r1.202 target.h
--- gdb/target.h 17 Mar 2011 13:19:24 -0000 1.202
+++ gdb/target.h 18 Mar 2011 17:23:22 -0000
@@ -493,7 +493,7 @@ struct target_ops
int (*to_has_exited) (int, int, int *);
void (*to_mourn_inferior) (struct target_ops *);
int (*to_can_run) (void);
- void (*to_notice_signals) (ptid_t ptid);
+ void (*to_pass_signals) (int, unsigned char *);
int (*to_thread_alive) (struct target_ops *, ptid_t ptid);
void (*to_find_new_threads) (struct target_ops *);
char *(*to_pid_to_str) (struct target_ops *, ptid_t);
@@ -1119,10 +1119,9 @@ void target_mourn_inferior (void);
#define target_can_run(t) \
((t)->to_can_run) ()

-/* post process changes to signal handling in the inferior. */
+/* Set list of signals to be handled in the target. */

-#define target_notice_signals(ptid) \
- (*current_target.to_notice_signals) (ptid)
+extern void target_pass_signals (int nsig, unsigned char *pass_signals);

/* Check to see if a thread is still alive. */