diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2011-04-27 13:29:15 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@de.ibm.com> | 2011-04-27 13:29:15 +0000 |
commit | 2455069d930b37918b92281be109444d1e38dc6d (patch) | |
tree | 1dede0ae37934adb93839c5dbe7d705198704b2b /gdb/infrun.c | |
parent | 46c6471b0a591c6a53cf9bacdee6663cc63cd588 (diff) | |
download | gdb-2455069d930b37918b92281be109444d1e38dc6d.zip gdb-2455069d930b37918b92281be109444d1e38dc6d.tar.gz gdb-2455069d930b37918b92281be109444d1e38dc6d.tar.bz2 |
* 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.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r-- | gdb/infrun.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c index 8eccb60..67381fa 100644 --- a/gdb/infrun.c +++ b/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 (); + { + 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."), _("\ |