From patchwork Thu Apr 28 16:44:45 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulrich Weigand X-Patchwork-Id: 1220 Return-Path: Delivered-To: unknown Received: from imap.gmail.com (74.125.159.109) by localhost6.localdomain6 with IMAP4-SSL; 08 Jun 2011 14:50:16 -0000 Delivered-To: patches@linaro.org Received: by 10.224.2.73 with SMTP id 9cs153844qai; Thu, 28 Apr 2011 09:44:49 -0700 (PDT) Received: by 10.227.60.194 with SMTP id q2mr3767113wbh.63.1304009088054; Thu, 28 Apr 2011 09:44:48 -0700 (PDT) Received: from mtagate6.uk.ibm.com (mtagate6.uk.ibm.com [194.196.100.166]) by mx.google.com with ESMTPS id m10si5768163wbm.53.2011.04.28.09.44.47 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 28 Apr 2011 09:44:48 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning uweigand@de.ibm.com does not designate 194.196.100.166 as permitted sender) client-ip=194.196.100.166; Authentication-Results: mx.google.com; spf=softfail (google.com: domain of transitioning uweigand@de.ibm.com does not designate 194.196.100.166 as permitted sender) smtp.mail=uweigand@de.ibm.com Received: from d06nrmr1307.portsmouth.uk.ibm.com (d06nrmr1307.portsmouth.uk.ibm.com [9.149.38.129]) by mtagate6.uk.ibm.com (8.13.1/8.13.1) with ESMTP id p3SGikII031283 for ; Thu, 28 Apr 2011 16:44:46 GMT Received: from d06av02.portsmouth.uk.ibm.com (d06av02.portsmouth.uk.ibm.com [9.149.37.228]) by d06nrmr1307.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p3SGjqmF1724484 for ; Thu, 28 Apr 2011 17:45:52 +0100 Received: from d06av02.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p3SGikei022145 for ; Thu, 28 Apr 2011 10:44:46 -0600 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with SMTP id p3SGijwt022131 for ; Thu, 28 Apr 2011 10:44:45 -0600 Message-Id: <201104281644.p3SGijwt022131@d06av02.portsmouth.uk.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Thu, 28 Apr 2011 18:44:45 +0200 Subject: [rfc v2][rft (procfs, nto-procfs)] Fix signal bypass heuristic with software single-step To: patches@linaro.org Date: Thu, 28 Apr 2011 18:44:45 +0200 (CEST) From: "Ulrich Weigand" X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 http://sourceware.org/ml/gdb-patches/2011-03/msg01223.html 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. (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. 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 31 Mar 2011 16:31:06 -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,18 @@ 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 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_ 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 stat 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) { @@ -6925,6 +6971,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 +7016,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 31 Mar 2011 16:31:08 -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); + } +} + /* 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,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, @@ -1944,7 +1960,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 +3606,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 @@ -5712,6 +5719,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 31 Mar 2011 16:31:08 -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 31 Mar 2011 16:31:09 -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.441 diff -u -p -r1.441 remote.c --- gdb/remote.c 18 Mar 2011 14:22:34 -0000 1.441 +++ gdb/remote.c 31 Mar 2011 16:31:10 -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.280 diff -u -p -r1.280 target.c --- gdb/target.c 31 Mar 2011 14:32:48 -0000 1.280 +++ gdb/target.c 31 Mar 2011 16:31:11 -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 @@ -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, 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. */ @@ -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; Index: gdb/target.h =================================================================== RCS file: /cvs/src/src/gdb/target.h,v retrieving revision 1.203 diff -u -p -r1.203 target.h --- gdb/target.h 31 Mar 2011 14:32:48 -0000 1.203 +++ gdb/target.h 31 Mar 2011 16:31:11 -0000 @@ -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. + + 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. */ -#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. */