mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 10:35:12 +08:00
* 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. (handle_inferior_event): Report all signals while stepping over non-steppable watchpoint. Reset trap_expected to ensure breakpoints are re-inserted when stepping over a signal handler. (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.
This commit is contained in:
parent
46c6471b0a
commit
2455069d93
@ -1,3 +1,61 @@
|
||||
2011-04-27 Ulrich Weigand <ulrich.weigand@linaro.org>
|
||||
|
||||
* 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.
|
||||
(handle_inferior_event): Report all signals while stepping over
|
||||
non-steppable watchpoint. Reset trap_expected to ensure breakpoints
|
||||
are re-inserted when stepping over a signal handler.
|
||||
(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.
|
||||
|
||||
2011-04-27 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* breakpoint.c (user_settable_breakpoint): Delete.
|
||||
|
53
gdb/infrun.c
53
gdb/infrun.c
@ -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,18 @@ a command like `return' or `jump' to continue execution."));
|
||||
happens to apply to another thread. */
|
||||
tp->suspend.stop_signal = TARGET_SIGNAL_0;
|
||||
|
||||
/* Advise target which signals may be handled silently. If we have
|
||||
removed breakpoints because we are stepping over one (which can
|
||||
happen only if we are not using displaced stepping), we need to
|
||||
receive all signals to avoid accidentally skipping a breakpoint
|
||||
during execution of a signal handler. */
|
||||
if ((step || singlestep_breakpoints_inserted_p)
|
||||
&& tp->control.trap_expected
|
||||
&& !use_displaced_stepping (gdbarch))
|
||||
target_pass_signals (0, NULL);
|
||||
else
|
||||
target_pass_signals ((int) TARGET_SIGNAL_LAST, signal_pass);
|
||||
|
||||
target_resume (resume_ptid, step, sig);
|
||||
}
|
||||
|
||||
@ -3818,7 +3835,12 @@ handle_inferior_event (struct execution_control_state *ecs)
|
||||
int hw_step = 1;
|
||||
|
||||
if (!target_have_steppable_watchpoint)
|
||||
{
|
||||
remove_breakpoints ();
|
||||
/* See comment in resume why we need to stop bypassing signals
|
||||
while breakpoints have been removed. */
|
||||
target_pass_signals (0, NULL);
|
||||
}
|
||||
/* Single step */
|
||||
hw_step = maybe_software_singlestep (gdbarch, stop_pc);
|
||||
target_resume (ecs->ptid, hw_step, TARGET_SIGNAL_0);
|
||||
@ -4090,6 +4112,8 @@ process_event_stop_test:
|
||||
|
||||
insert_step_resume_breakpoint_at_frame (frame);
|
||||
ecs->event_thread->step_after_step_resume_breakpoint = 1;
|
||||
/* Reset trap_expected to ensure breakpoints are re-inserted. */
|
||||
ecs->event_thread->control.trap_expected = 0;
|
||||
keep_going (ecs);
|
||||
return;
|
||||
}
|
||||
@ -4117,6 +4141,8 @@ process_event_stop_test:
|
||||
"single-step range\n");
|
||||
|
||||
insert_step_resume_breakpoint_at_frame (frame);
|
||||
/* Reset trap_expected to ensure breakpoints are re-inserted. */
|
||||
ecs->event_thread->control.trap_expected = 0;
|
||||
keep_going (ecs);
|
||||
return;
|
||||
}
|
||||
@ -5853,12 +5879,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 +5911,7 @@ signal_print_update (int signo, int state)
|
||||
int ret = signal_print[signo];
|
||||
|
||||
signal_print[signo] = state;
|
||||
signal_cache_update (signo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -5877,6 +5921,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 +6113,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)
|
||||
{
|
||||
@ -6920,6 +6966,8 @@ leave it stopped or free to run as needed."),
|
||||
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;
|
||||
@ -6963,6 +7011,9 @@ leave it stopped or free to run as needed."),
|
||||
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."), _("\
|
||||
|
@ -1041,6 +1041,26 @@ restore_child_signals_mask (sigset_t *prev_mask)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
@ -1506,6 +1526,9 @@ linux_nat_create_inferior (struct target_ops *ops,
|
||||
}
|
||||
#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
|
||||
@ -1527,6 +1550,9 @@ linux_nat_attach (struct target_ops *ops, char *args, int from_tty)
|
||||
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)
|
||||
@ -1885,19 +1911,9 @@ 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 (!lp->step
|
||||
&& WSTOPSIG (lp->status)
|
||||
&& sigismember (&pass_mask, WSTOPSIG (lp->status)))
|
||||
{
|
||||
if (debug_linux_nat)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
@ -1907,7 +1923,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;
|
||||
}
|
||||
}
|
||||
@ -3553,20 +3569,11 @@ 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. */
|
||||
/* When using hardware single-step, we need to report every signal.
|
||||
Otherwise, signals in pass_mask may be short-circuited. */
|
||||
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)
|
||||
&& 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
|
||||
@ -5675,6 +5682,7 @@ linux_nat_add_target (struct target_ops *t)
|
||||
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;
|
||||
|
@ -64,8 +64,6 @@ static int procfs_xfer_memory (CORE_ADDR, gdb_byte *, int, int,
|
||||
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);
|
||||
@ -985,8 +983,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)
|
||||
@ -1334,34 +1330,23 @@ procfs_store_registers (struct target_ops *ops,
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
int target_signo = target_signal_from_host (signo);
|
||||
if (target_signo < numsigs && pass_signals[target_signo])
|
||||
sigdelset (&run.trace, signo);
|
||||
else
|
||||
sigaddset (&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)
|
||||
{
|
||||
@ -1426,7 +1411,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;
|
||||
@ -1458,8 +1443,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;
|
||||
|
58
gdb/procfs.c
58
gdb/procfs.c
@ -120,7 +120,7 @@ static void procfs_fetch_registers (struct target_ops *,
|
||||
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 *ops, int pid)
|
||||
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);
|
||||
|
||||
|
30
gdb/remote.c
30
gdb/remote.c
@ -1596,20 +1596,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);
|
||||
@ -1617,9 +1614,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);
|
||||
@ -1649,14 +1644,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
|
||||
@ -3378,10 +3365,8 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
|
||||
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. */
|
||||
@ -4549,9 +4534,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)
|
||||
@ -10293,7 +10275,7 @@ Specify the serial device it is connected to\n\
|
||||
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;
|
||||
|
48
gdb/target.c
48
gdb/target.c
@ -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
|
||||
@ -625,7 +623,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. */
|
||||
@ -793,9 +791,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);
|
||||
@ -2587,6 +2582,37 @@ target_resume (ptid_t ptid, int step, enum target_signal signal)
|
||||
|
||||
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. */
|
||||
|
||||
@ -3914,15 +3940,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)
|
||||
{
|
||||
@ -4010,7 +4027,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;
|
||||
|
21
gdb/target.h
21
gdb/target.h
@ -494,7 +494,11 @@ 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);
|
||||
|
||||
/* Documentation of this routine is provided with the corresponding
|
||||
target_* macro. */
|
||||
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);
|
||||
@ -1120,10 +1124,19 @@ 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)
|
||||
PASS_SIGNALS is an array of size NSIG, indexed by target signal number
|
||||
(enum target_signal). For every signal whose entry in this array is
|
||||
non-zero, the target is allowed -but not required- to skip reporting
|
||||
arrival of the signal to the GDB core by returning from target_wait,
|
||||
and to pass the signal directly to the inferior instead.
|
||||
|
||||
However, if the target is hardware single-stepping a thread that is
|
||||
about to receive a signal, it needs to be reported in any case, even
|
||||
if mentioned in a previous target_pass_signals call. */
|
||||
|
||||
extern void target_pass_signals (int nsig, unsigned char *pass_signals);
|
||||
|
||||
/* Check to see if a thread is still alive. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user