Remove the global stop_signal in favour of a per-thread
authorPedro Alves <palves@redhat.com>
Mon, 8 Sep 2008 21:51:18 +0000 (21:51 +0000)
committerPedro Alves <palves@redhat.com>
Mon, 8 Sep 2008 21:51:18 +0000 (21:51 +0000)
stop_signal.

* inferior.h (stop_signal): Delete.
* gdbthread.h (save_infrun_state, load_infrun_state): Remove
stop_signal argument.
* thread.c (load_infrun_state, save_infrun_state): Remove
stop_signal argument.  Don't reference it.

* infcmd.c (stop_signal): Delete.
(program_info): Adjust.
* infrun.c (resume): Clear stop_signal.
(proceed): Adjust.  Pass the last stop_signal to the thread we're
resuming.
(context_switch): Don't context-switch stop_signal.
(handle_inferior_event, keep_going): Adjust.
(save_inferior_status, restore_inferior_status): Adjust.

* fbsd-nat.c: Include "gdbthread.h".
(find_signalled_thread, find_stop_signal): New.
(fbsd_make_corefile_notes): Use it.
* fork-child.c (startup_inferior): Adjust.

* linux-nat.c (get_pending_status): Adjust.
(linux_nat_do_thread_registers): Adjust.
(find_signalled_thread, find_stop_signal): New.
(linux_nat_do_thread_registers): Add stop_signal parameter.
(struct linux_nat_corefile_thread_data): Add stop_signal member.
(linux_nat_corefile_thread_callback): Pass stop_signal.
(linux_nat_do_registers): Delete.
(linux_nat_make_corefile_notes): Use find_stop_signal.  Assume
there's always a thread.

* procfs.c (find_signalled_thread, find_stop_signal): New.
(find_stop_signal): New.
(procfs_do_thread_registers): Add stop_signal parameter.
(struct procfs_corefile_thread_data): Add stop_signal member.
(procfs_corefile_thread_callback): Pass args->stop_signal.
(procfs_make_note_section): Find the last stop_signal.

* solib-irix.c: Include gdbthread.h.
(irix_solib_create_inferior_hook): Adjust.
* solib-osf.c: Include gdbthread.h.
(osf_solib_create_inferior_hook): Adjust.
* solib-sunos.c: Include gdbthread.h.
(sunos_solib_create_inferior_hook): Adjust.
* solib-svr4.c: Include gdbthread.h.
(svr4_solib_create_inferior_hook): Adjust.

* win32-nat.c (do_initial_win32_stuff): Adjust.

16 files changed:
gdb/ChangeLog
gdb/fbsd-nat.c
gdb/fork-child.c
gdb/gdbthread.h
gdb/infcmd.c
gdb/inferior.h
gdb/infrun.c
gdb/linux-nat.c
gdb/procfs.c
gdb/solib-irix.c
gdb/solib-osf.c
gdb/solib-sunos.c
gdb/solib-svr4.c
gdb/thread.c
gdb/win32-nat.c
gdb/windows-nat.c

index c0f2597..b6b451b 100644 (file)
@@ -1,5 +1,58 @@
 2008-09-08  Pedro Alves  <pedro@codesourcery.com>
 
+       Remove the global stop_signal in favour of a per-thread
+       stop_signal.
+
+       * inferior.h (stop_signal): Delete.
+       * gdbthread.h (save_infrun_state, load_infrun_state): Remove
+       stop_signal argument.
+       * thread.c (load_infrun_state, save_infrun_state): Remove
+       stop_signal argument.  Don't reference it.
+
+       * infcmd.c (stop_signal): Delete.
+       (program_info): Adjust.
+       * infrun.c (resume): Clear stop_signal.
+       (proceed): Adjust.  Pass the last stop_signal to the thread we're
+       resuming.
+       (context_switch): Don't context-switch stop_signal.
+       (handle_inferior_event, keep_going): Adjust.
+       (save_inferior_status, restore_inferior_status): Adjust.
+
+       * fbsd-nat.c: Include "gdbthread.h".
+       (find_signalled_thread, find_stop_signal): New.
+       (fbsd_make_corefile_notes): Use it.
+       * fork-child.c (startup_inferior): Adjust.
+
+       * linux-nat.c (get_pending_status): Adjust.
+       (linux_nat_do_thread_registers): Adjust.
+       (find_signalled_thread, find_stop_signal): New.
+       (linux_nat_do_thread_registers): Add stop_signal parameter.
+       (struct linux_nat_corefile_thread_data): Add stop_signal member.
+       (linux_nat_corefile_thread_callback): Pass stop_signal.
+       (linux_nat_do_registers): Delete.
+       (linux_nat_make_corefile_notes): Use find_stop_signal.  Assume
+       there's always a thread.
+
+       * procfs.c (find_signalled_thread, find_stop_signal): New.
+       (find_stop_signal): New.
+       (procfs_do_thread_registers): Add stop_signal parameter.
+       (struct procfs_corefile_thread_data): Add stop_signal member.
+       (procfs_corefile_thread_callback): Pass args->stop_signal.
+       (procfs_make_note_section): Find the last stop_signal.
+
+       * solib-irix.c: Include gdbthread.h.
+       (irix_solib_create_inferior_hook): Adjust.
+       * solib-osf.c: Include gdbthread.h.
+       (osf_solib_create_inferior_hook): Adjust.
+       * solib-sunos.c: Include gdbthread.h.
+       (sunos_solib_create_inferior_hook): Adjust.
+       * solib-svr4.c: Include gdbthread.h.
+       (svr4_solib_create_inferior_hook): Adjust.
+
+       * win32-nat.c (do_initial_win32_stuff): Adjust.
+
+2008-09-08  Pedro Alves  <pedro@codesourcery.com>
+
        * gdbthread.h (struct thread_info): Add comments around
        proceed_to_finish.
        (save_infrun_state, load_infrun_state): Remove proceed_to_finish
index 6f442cc..215d2a7 100644 (file)
@@ -22,6 +22,7 @@
 #include "inferior.h"
 #include "regcache.h"
 #include "regset.h"
+#include "gdbthread.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -137,6 +138,28 @@ fbsd_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
   return 0;
 }
 
+static int
+find_signalled_thread (struct thread_info *info, void *data)
+{
+  if (info->stop_signal != TARGET_SIGNAL_0
+      && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
+    return 1;
+
+  return 0;
+}
+
+static enum target_signal
+find_stop_signal (void)
+{
+  struct thread_info *info =
+    iterate_over_threads (find_signalled_thread, NULL);
+
+  if (info)
+    return info->stop_signal;
+  else
+    return TARGET_SIGNAL_0;
+}
+
 /* Create appropriate note sections for a corefile, returning them in
    allocated memory.  */
 
@@ -165,7 +188,7 @@ fbsd_make_corefile_notes (bfd *obfd, int *note_size)
 
   note_data = elfcore_write_prstatus (obfd, note_data, note_size,
                                      ptid_get_pid (inferior_ptid),
-                                     stop_signal, &gregs);
+                                     find_stop_signal (), &gregs);
 
   size = sizeof fpregs;
   regset = gdbarch_regset_from_core_section (gdbarch, ".reg2", size);
index 229770f..269dd43 100644 (file)
@@ -434,15 +434,18 @@ startup_inferior (int ntraps)
 
   while (1)
     {
+      struct thread_info *tp;
+
       /* Make wait_for_inferior be quiet. */
       stop_soon = STOP_QUIETLY;
       wait_for_inferior (1);
-      if (stop_signal != TARGET_SIGNAL_TRAP)
+      tp = inferior_thread ();
+      if (tp->stop_signal != TARGET_SIGNAL_TRAP)
        {
          /* Let shell child handle its own signals in its own way.
             FIXME: what if child has exited?  Must exit loop
             somehow.  */
-         resume (0, stop_signal);
+         resume (0, tp->stop_signal);
        }
       else
        {
index ca74976..3082abf 100644 (file)
@@ -149,6 +149,7 @@ struct thread_info
   int stop_step;
   int step_multi;
 
+  /* Last signal that the inferior received (why it stopped).  */
   enum target_signal stop_signal;
 
   /* Chain containing status of breakpoint(s) the thread stopped
@@ -224,8 +225,7 @@ extern void save_infrun_state (ptid_t ptid,
                               struct continuation *continuations,
                               struct continuation *intermediate_continuations,
                               int stop_step,
-                              int step_multi,
-                              enum target_signal stop_signal);
+                              int step_multi);
 
 /* infrun context switch: load the debugger state previously saved
    for the given thread.  */
@@ -233,8 +233,7 @@ extern void load_infrun_state (ptid_t ptid,
                               struct continuation **continuations,
                               struct continuation **intermediate_continuations,
                               int *stop_step,
-                              int *step_multi,
-                              enum target_signal *stop_signal);
+                              int *step_multi);
 
 /* Switch from one thread to another.  */
 extern void switch_to_thread (ptid_t ptid);
index a86f236..055b228 100644 (file)
@@ -147,10 +147,6 @@ static char *inferior_io_terminal;
 
 ptid_t inferior_ptid;
 
-/* Last signal that the inferior received (why it stopped).  */
-
-enum target_signal stop_signal;
-
 /* Address at which inferior stopped.  */
 
 CORE_ADDR stop_pc;
@@ -1505,11 +1501,11 @@ It stopped at a breakpoint that has since been deleted.\n"));
          stat = bpstat_num (&bs, &num);
        }
     }
-  else if (stop_signal != TARGET_SIGNAL_0)
+  else if (tp->stop_signal != TARGET_SIGNAL_0)
     {
       printf_filtered (_("It stopped with signal %s, %s.\n"),
-                      target_signal_to_name (stop_signal),
-                      target_signal_to_string (stop_signal));
+                      target_signal_to_name (tp->stop_signal),
+                      target_signal_to_string (tp->stop_signal));
     }
 
   if (!from_tty)
index f39cc2c..78af8c2 100644 (file)
@@ -279,10 +279,6 @@ extern void interrupt_target_command (char *args, int from_tty);
 
 extern void interrupt_target_1 (int all_threads);
 
-/* Last signal that the inferior received (why it stopped).  */
-
-extern enum target_signal stop_signal;
-
 /* Address at which inferior stopped.  */
 
 extern CORE_ADDR stop_pc;
index 4e28c22..d34fc20 100644 (file)
@@ -1078,6 +1078,10 @@ a command like `return' or `jump' to continue execution."));
         }
 
       target_resume (resume_ptid, step, sig);
+
+      /* Avoid confusing the next resume, if the next stop/resume
+        happens to apply to another thread.  */
+      tp->stop_signal = TARGET_SIGNAL_0;
     }
 
   discard_cleanups (old_cleanups);
@@ -1182,6 +1186,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
   struct thread_info *tp;
   CORE_ADDR pc = regcache_read_pc (regcache);
   int oneproc = 0;
+  enum target_signal stop_signal;
 
   if (step > 0)
     step_start_function = find_pc_function (pc);
@@ -1256,12 +1261,37 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
   if (! tp->trap_expected || use_displaced_stepping (gdbarch))
     insert_breakpoints ();
 
+  if (!non_stop)
+    {
+      /* Pass the last stop signal to the thread we're resuming,
+        irrespective of whether the current thread is the thread that
+        got the last event or not.  This was historically GDB's
+        behaviour before keeping a stop_signal per thread.  */
+
+      struct thread_info *last_thread;
+      ptid_t last_ptid;
+      struct target_waitstatus last_status;
+
+      get_last_target_status (&last_ptid, &last_status);
+      if (!ptid_equal (inferior_ptid, last_ptid)
+         && !ptid_equal (last_ptid, null_ptid)
+         && !ptid_equal (last_ptid, minus_one_ptid))
+       {
+         last_thread = find_thread_pid (last_ptid);
+         if (last_thread)
+           {
+             tp->stop_signal = last_thread->stop_signal;
+             last_thread->stop_signal = TARGET_SIGNAL_0;
+           }
+       }
+    }
+
   if (siggnal != TARGET_SIGNAL_DEFAULT)
-    stop_signal = siggnal;
+    tp->stop_signal = siggnal;
   /* If this signal should not be seen by program,
      give it zero.  Used for debugging signals.  */
-  else if (!signal_program[stop_signal])
-    stop_signal = TARGET_SIGNAL_0;
+  else if (!signal_program[tp->stop_signal])
+    tp->stop_signal = TARGET_SIGNAL_0;
 
   annotate_starting ();
 
@@ -1300,7 +1330,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
   init_infwait_state ();
 
   /* Resume inferior.  */
-  resume (oneproc || step || bpstat_should_step (), stop_signal);
+  resume (oneproc || step || bpstat_should_step (), tp->stop_signal);
 
   /* Wait for it to stop (if not standalone)
      and in any case decode why it stopped, and act accordingly.  */
@@ -1355,9 +1385,6 @@ init_wait_for_inferior (void)
 
   breakpoint_init_inferior (inf_starting);
 
-  /* Don't confuse first call to proceed(). */
-  stop_signal = TARGET_SIGNAL_0;
-
   /* The first resume is not following a fork/vfork/exec. */
   pending_follow.kind = TARGET_WAITKIND_SPURIOUS;      /* I.e., none. */
 
@@ -1712,15 +1739,13 @@ context_switch (ptid_t ptid)
       save_infrun_state (inferior_ptid,
                         cmd_continuation, intermediate_continuation,
                         stop_step,
-                        step_multi,
-                        stop_signal);
+                        step_multi);
 
       /* Load infrun state for the new thread.  */
       load_infrun_state (ptid,
                         &cmd_continuation, &intermediate_continuation,
                         &stop_step,
-                        &step_multi,
-                        &stop_signal);
+                        &step_multi);
     }
 
   switch_to_thread (ptid);
@@ -2023,7 +2048,6 @@ handle_inferior_event (struct execution_control_state *ecs)
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SIGNALLED\n");
       stop_print_frame = 0;
-      stop_signal = ecs->ws.value.sig;
       target_terminal_ours (); /* Must do this before mourn anyway */
 
       /* Note: By definition of TARGET_WAITKIND_SIGNALLED, we shouldn't
@@ -2033,7 +2057,7 @@ handle_inferior_event (struct execution_control_state *ecs)
          may be needed. */
       target_mourn_inferior ();
 
-      print_stop_reason (SIGNAL_EXITED, stop_signal);
+      print_stop_reason (SIGNAL_EXITED, ecs->ws.value.sig);
       singlestep_breakpoints_inserted_p = 0;
       stop_stepping (ecs);
       return;
@@ -2044,7 +2068,6 @@ handle_inferior_event (struct execution_control_state *ecs)
     case TARGET_WAITKIND_VFORKED:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_FORKED\n");
-      stop_signal = TARGET_SIGNAL_TRAP;
       pending_follow.kind = ecs->ws.kind;
 
       pending_follow.fork_event.parent_pid = ecs->ptid;
@@ -2065,17 +2088,16 @@ handle_inferior_event (struct execution_control_state *ecs)
       /* If no catchpoint triggered for this, then keep going.  */
       if (ecs->random_signal)
        {
-         stop_signal = TARGET_SIGNAL_0;
+         ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
          keep_going (ecs);
          return;
        }
+      ecs->event_thread->stop_signal = TARGET_SIGNAL_TRAP;
       goto process_event_stop_test;
 
     case TARGET_WAITKIND_EXECD:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_EXECD\n");
-      stop_signal = TARGET_SIGNAL_TRAP;
-
       pending_follow.execd_pathname =
        savestring (ecs->ws.value.execd_pathname,
                    strlen (ecs->ws.value.execd_pathname));
@@ -2109,10 +2131,11 @@ handle_inferior_event (struct execution_control_state *ecs)
       /* If no catchpoint triggered for this, then keep going.  */
       if (ecs->random_signal)
        {
-         stop_signal = TARGET_SIGNAL_0;
+         ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
          keep_going (ecs);
          return;
        }
+      ecs->event_thread->stop_signal = TARGET_SIGNAL_TRAP;
       goto process_event_stop_test;
 
       /* Be careful not to try to gather much state about a thread
@@ -2139,7 +2162,7 @@ handle_inferior_event (struct execution_control_state *ecs)
     case TARGET_WAITKIND_STOPPED:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_STOPPED\n");
-      stop_signal = ecs->ws.value.sig;
+      ecs->event_thread->stop_signal = ecs->ws.value.sig;
       break;
 
       /* We had an event in the inferior, but we are not interested
@@ -2182,7 +2205,8 @@ targets should add new threads to the thread list themselves in non-stop mode.")
   /* Do we need to clean up the state of a thread that has completed a
      displaced single-step?  (Doing so usually affects the PC, so do
      it here, before we set stop_pc.)  */
-  displaced_step_fixup (ecs->ptid, stop_signal);
+  if (ecs->ws.kind == TARGET_WAITKIND_STOPPED)
+    displaced_step_fixup (ecs->ptid, ecs->event_thread->stop_signal);
 
   stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
 
@@ -2216,7 +2240,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
       /* We've either finished single-stepping past the single-step
          breakpoint, or stopped for some other reason.  It would be nice if
          we could tell, but we can't reliably.  */
-      if (stop_signal == TARGET_SIGNAL_TRAP)
+      if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
        {
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n");
@@ -2245,7 +2269,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
 
       /* If we stopped for some other reason than single-stepping, ignore
         the fact that we were supposed to switch back.  */
-      if (stop_signal == TARGET_SIGNAL_TRAP)
+      if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
        {
          struct thread_info *tp;
 
@@ -2279,7 +2303,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
      another thread.  If so, then step that thread past the breakpoint,
      and continue it.  */
 
-  if (stop_signal == TARGET_SIGNAL_TRAP)
+  if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
     {
       int thread_hop_needed = 0;
 
@@ -2333,6 +2357,8 @@ targets should add new threads to the thread list themselves in non-stop mode.")
 
             if (new_singlestep_pc != singlestep_pc)
               {
+                enum target_signal stop_signal;
+
                 if (debug_infrun)
                   fprintf_unfiltered (gdb_stdlog, "infrun: unexpected thread,"
                                       " but expected thread advanced also\n");
@@ -2341,8 +2367,11 @@ targets should add new threads to the thread list themselves in non-stop mode.")
                    singlestep_ptid.  Don't swap here, since that's
                    the context we want to use.  Just fudge our
                    state and continue.  */
+                 stop_signal = ecs->event_thread->stop_signal;
+                 ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
                  ecs->ptid = singlestep_ptid;
                  ecs->event_thread = find_thread_pid (ecs->ptid);
+                 ecs->event_thread->stop_signal = stop_signal;
                  stop_pc = new_singlestep_pc;
                }
              else
@@ -2498,7 +2527,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
   ecs->random_signal = 0;
   stopped_by_random_signal = 0;
 
-  if (stop_signal == TARGET_SIGNAL_TRAP
+  if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP
       && ecs->event_thread->trap_expected
       && gdbarch_single_step_through_delay_p (current_gdbarch)
       && currently_stepping (ecs->event_thread))
@@ -2555,16 +2584,16 @@ targets should add new threads to the thread list themselves in non-stop mode.")
      If we're doing a displaced step past a breakpoint, then the
      breakpoint is always inserted at the original instruction;
      non-standard signals can't be explained by the breakpoint.  */
-  if (stop_signal == TARGET_SIGNAL_TRAP
+  if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP
       || (! ecs->event_thread->trap_expected
           && breakpoint_inserted_here_p (stop_pc)
-         && (stop_signal == TARGET_SIGNAL_ILL
-             || stop_signal == TARGET_SIGNAL_SEGV
-             || stop_signal == TARGET_SIGNAL_EMT))
+         && (ecs->event_thread->stop_signal == TARGET_SIGNAL_ILL
+             || ecs->event_thread->stop_signal == TARGET_SIGNAL_SEGV
+             || ecs->event_thread->stop_signal == TARGET_SIGNAL_EMT))
       || stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_NO_SIGSTOP
       || stop_soon == STOP_QUIETLY_REMOTE)
     {
-      if (stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap)
+      if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap)
        {
           if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog, "infrun: stopped\n");
@@ -2596,11 +2625,11 @@ targets should add new threads to the thread list themselves in non-stop mode.")
         (e.g. gdbserver).  We already rely on SIGTRAP being our
         signal, so this is no exception.  */
       if (stop_soon == STOP_QUIETLY_NO_SIGSTOP
-         && (stop_signal == TARGET_SIGNAL_STOP
-             || stop_signal == TARGET_SIGNAL_TRAP))
+         && (ecs->event_thread->stop_signal == TARGET_SIGNAL_STOP
+             || ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP))
        {
          stop_stepping (ecs);
-         stop_signal = TARGET_SIGNAL_0;
+         ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
          return;
        }
 
@@ -2631,7 +2660,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
          be necessary for call dummies on a non-executable stack on
          SPARC.  */
 
-      if (stop_signal == TARGET_SIGNAL_TRAP)
+      if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
        ecs->random_signal
          = !(bpstat_explains_signal (ecs->event_thread->stop_bpstat)
              || ecs->event_thread->trap_expected
@@ -2641,7 +2670,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
        {
          ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat);
          if (!ecs->random_signal)
-           stop_signal = TARGET_SIGNAL_TRAP;
+           ecs->event_thread->stop_signal = TARGET_SIGNAL_TRAP;
        }
     }
 
@@ -2662,17 +2691,18 @@ process_event_stop_test:
       int printed = 0;
 
       if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: random signal %d\n", stop_signal);
+        fprintf_unfiltered (gdb_stdlog, "infrun: random signal %d\n",
+                            ecs->event_thread->stop_signal);
 
       stopped_by_random_signal = 1;
 
-      if (signal_print[stop_signal])
+      if (signal_print[ecs->event_thread->stop_signal])
        {
          printed = 1;
          target_terminal_ours_for_output ();
-         print_stop_reason (SIGNAL_RECEIVED, stop_signal);
+         print_stop_reason (SIGNAL_RECEIVED, ecs->event_thread->stop_signal);
        }
-      if (signal_stop_state (stop_signal))
+      if (signal_stop_state (ecs->event_thread->stop_signal))
        {
          stop_stepping (ecs);
          return;
@@ -2683,8 +2713,8 @@ process_event_stop_test:
        target_terminal_inferior ();
 
       /* Clear the signal if it should not be passed.  */
-      if (signal_program[stop_signal] == 0)
-       stop_signal = TARGET_SIGNAL_0;
+      if (signal_program[ecs->event_thread->stop_signal] == 0)
+       ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
 
       if (ecs->event_thread->prev_pc == read_pc ()
          && ecs->event_thread->trap_expected
@@ -2712,7 +2742,7 @@ process_event_stop_test:
        }
 
       if (ecs->event_thread->step_range_end != 0
-         && stop_signal != TARGET_SIGNAL_0
+         && ecs->event_thread->stop_signal != TARGET_SIGNAL_0
          && (ecs->event_thread->step_range_start <= stop_pc
              && stop_pc < ecs->event_thread->step_range_end)
          && frame_id_eq (get_frame_id (get_current_frame ()),
@@ -3517,12 +3547,14 @@ keep_going (struct execution_control_state *ecs)
   /* If we did not do break;, it means we should keep running the
      inferior and not return to debugger.  */
 
-  if (ecs->event_thread->trap_expected && stop_signal != TARGET_SIGNAL_TRAP)
+  if (ecs->event_thread->trap_expected
+      && ecs->event_thread->stop_signal != TARGET_SIGNAL_TRAP)
     {
       /* We took a signal (which we are supposed to pass through to
         the inferior, else we'd not get here) and we haven't yet
         gotten our trap.  Simply continue.  */
-      resume (currently_stepping (ecs->event_thread), stop_signal);
+      resume (currently_stepping (ecs->event_thread),
+             ecs->event_thread->stop_signal);
     }
   else
     {
@@ -3577,11 +3609,12 @@ keep_going (struct execution_control_state *ecs)
          simulator; the simulator then delivers the hardware
          equivalent of a SIGNAL_TRAP to the program being debugged. */
 
-      if (stop_signal == TARGET_SIGNAL_TRAP && !signal_program[stop_signal])
-       stop_signal = TARGET_SIGNAL_0;
-
+      if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP
+         && !signal_program[ecs->event_thread->stop_signal])
+       ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
 
-      resume (currently_stepping (ecs->event_thread), stop_signal);
+      resume (currently_stepping (ecs->event_thread),
+             ecs->event_thread->stop_signal);
     }
 
   prepare_to_wait (ecs);
@@ -4366,7 +4399,7 @@ save_inferior_status (int restore_stack_info)
   struct inferior_status *inf_status = XMALLOC (struct inferior_status);
   struct thread_info *tp = inferior_thread ();
 
-  inf_status->stop_signal = stop_signal;
+  inf_status->stop_signal = tp->stop_signal;
   inf_status->stop_pc = stop_pc;
   inf_status->stop_step = stop_step;
   inf_status->stop_stack_dummy = stop_stack_dummy;
@@ -4420,7 +4453,7 @@ restore_inferior_status (struct inferior_status *inf_status)
 {
   struct thread_info *tp = inferior_thread ();
 
-  stop_signal = inf_status->stop_signal;
+  tp->stop_signal = inf_status->stop_signal;
   stop_pc = inf_status->stop_pc;
   stop_step = inf_status->stop_step;
   stop_stack_dummy = inf_status->stop_stack_dummy;
index 07ded10..42e19b5 100644 (file)
@@ -1453,18 +1453,10 @@ get_pending_status (struct lwp_info *lp, int *status)
        {
          /* If the core knows the thread is not executing, then we
             have the last signal recorded in
-            thread_info->stop_signal, unless this is inferior_ptid,
-            in which case, it's in the global stop_signal, due to
-            context switching.  */
+            thread_info->stop_signal.  */
 
-         if (ptid_equal (lp->ptid, inferior_ptid))
-           signo = stop_signal;
-         else
-           {
-             struct thread_info *tp = find_thread_pid (lp->ptid);
-             gdb_assert (tp);
-             signo = tp->stop_signal;
-           }
+         struct thread_info *tp = find_thread_pid (lp->ptid);
+         signo = tp->stop_signal;
        }
 
       if (signo != TARGET_SIGNAL_0
@@ -1492,9 +1484,10 @@ GPT: lwp %s had signal %s, but it is in no pass state\n",
     {
       if (GET_LWP (lp->ptid) == GET_LWP (last_ptid))
        {
-         if (stop_signal != TARGET_SIGNAL_0
-             && signal_pass_state (stop_signal))
-           *status = W_STOPCODE (target_signal_to_host (stop_signal));
+         struct thread_info *tp = find_thread_pid (lp->ptid);
+         if (tp->stop_signal != TARGET_SIGNAL_0
+             && signal_pass_state (tp->stop_signal))
+           *status = W_STOPCODE (target_signal_to_host (tp->stop_signal));
        }
       else if (target_can_async_p ())
        queued_waitpid (GET_LWP (lp->ptid), status, __WALL);
@@ -3338,12 +3331,35 @@ linux_nat_find_memory_regions (int (*func) (CORE_ADDR,
   return 0;
 }
 
+static int
+find_signalled_thread (struct thread_info *info, void *data)
+{
+  if (info->stop_signal != TARGET_SIGNAL_0
+      && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
+    return 1;
+
+  return 0;
+}
+
+static enum target_signal
+find_stop_signal (void)
+{
+  struct thread_info *info =
+    iterate_over_threads (find_signalled_thread, NULL);
+
+  if (info)
+    return info->stop_signal;
+  else
+    return TARGET_SIGNAL_0;
+}
+
 /* Records the thread's register state for the corefile note
    section.  */
 
 static char *
 linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
-                              char *note_data, int *note_size)
+                              char *note_data, int *note_size,
+                              enum target_signal stop_signal)
 {
   gdb_gregset_t gregs;
   gdb_fpregset_t fpregs;
@@ -3438,6 +3454,7 @@ struct linux_nat_corefile_thread_data
   char *note_data;
   int *note_size;
   int num_notes;
+  enum target_signal stop_signal;
 };
 
 /* Called by gdbthread.c once per thread.  Records the thread's
@@ -3451,25 +3468,13 @@ linux_nat_corefile_thread_callback (struct lwp_info *ti, void *data)
   args->note_data = linux_nat_do_thread_registers (args->obfd,
                                                   ti->ptid,
                                                   args->note_data,
-                                                  args->note_size);
+                                                  args->note_size,
+                                                  args->stop_signal);
   args->num_notes++;
 
   return 0;
 }
 
-/* Records the register state for the corefile note section.  */
-
-static char *
-linux_nat_do_registers (bfd *obfd, ptid_t ptid,
-                       char *note_data, int *note_size)
-{
-  return linux_nat_do_thread_registers (obfd,
-                                       ptid_build (ptid_get_pid (inferior_ptid),
-                                                   ptid_get_pid (inferior_ptid),
-                                                   0),
-                                       note_data, note_size);
-}
-
 /* Fills the "to_make_corefile_note" target vector.  Builds the note
    section for a corefile, and returns it in a malloc buffer.  */
 
@@ -3516,18 +3521,10 @@ linux_nat_make_corefile_notes (bfd *obfd, int *note_size)
   thread_args.note_data = note_data;
   thread_args.note_size = note_size;
   thread_args.num_notes = 0;
+  thread_args.stop_signal = find_stop_signal ();
   iterate_over_lwps (linux_nat_corefile_thread_callback, &thread_args);
-  if (thread_args.num_notes == 0)
-    {
-      /* iterate_over_threads didn't come up with any threads; just
-         use inferior_ptid.  */
-      note_data = linux_nat_do_registers (obfd, inferior_ptid,
-                                         note_data, note_size);
-    }
-  else
-    {
-      note_data = thread_args.note_data;
-    }
+  gdb_assert (thread_args.num_notes != 0);
+  note_data = thread_args.note_data;
 
   auxv_len = target_read_alloc (&current_target, TARGET_OBJECT_AUXV,
                                NULL, &auxv);
index beeb4f5..e8cd6d9 100644 (file)
@@ -6045,13 +6045,36 @@ procfs_first_available (void)
   return pid_to_ptid (procinfo_list ? procinfo_list->pid : -1);
 }
 
+static int
+find_signalled_thread (struct thread_info *info, void *data)
+{
+  if (info->stop_signal != TARGET_SIGNAL_0
+      && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
+    return 1;
+
+  return 0;
+}
+
+static enum target_signal
+find_stop_signal (void)
+{
+  struct thread_info *info =
+    iterate_over_threads (find_signalled_thread, NULL);
+
+  if (info)
+    return info->stop_signal;
+  else
+    return TARGET_SIGNAL_0;
+}
+
 /* ===================  GCORE .NOTE "MODULE" =================== */
 #if defined (UNIXWARE) || defined (PIOCOPENLWP) || defined (PCAGENT)
 /* gcore only implemented on solaris and unixware (so far) */
 
 static char *
 procfs_do_thread_registers (bfd *obfd, ptid_t ptid,
-                           char *note_data, int *note_size)
+                           char *note_data, int *note_size,
+                           enum target_signal stop_signal)
 {
   struct regcache *regcache = get_thread_regcache (ptid);
   gdb_gregset_t gregs;
@@ -6089,6 +6112,7 @@ struct procfs_corefile_thread_data {
   bfd *obfd;
   char *note_data;
   int *note_size;
+  enum target_signal stop_signal;
 };
 
 static int
@@ -6102,7 +6126,8 @@ procfs_corefile_thread_callback (procinfo *pi, procinfo *thread, void *data)
       inferior_ptid = MERGEPID (pi->pid, thread->tid);
       args->note_data = procfs_do_thread_registers (args->obfd, inferior_ptid,
                                                    args->note_data,
-                                                   args->note_size);
+                                                   args->note_size,
+                                                   args->stop_signal);
       inferior_ptid = saved_ptid;
     }
   return 0;
@@ -6156,6 +6181,7 @@ procfs_make_note_section (bfd *obfd, int *note_size)
   thread_args.obfd = obfd;
   thread_args.note_data = note_data;
   thread_args.note_size = note_size;
+  thread_args.stop_signal = find_stop_signal ();
   proc_iterate_over_threads (pi, procfs_corefile_thread_callback, &thread_args);
 
   /* There should be always at least one thread.  */
index 0e80b94..5b612ec 100644 (file)
@@ -31,6 +31,7 @@
 #include "gdbcore.h"
 #include "target.h"
 #include "inferior.h"
+#include "gdbthread.h"
 
 #include "solist.h"
 #include "solib.h"
@@ -421,6 +422,8 @@ enable_break (void)
 static void
 irix_solib_create_inferior_hook (void)
 {
+  struct thread_info *tp;
+
   if (!enable_break ())
     {
       warning (_("shared library handler failed to enable breakpoint"));
@@ -432,15 +435,16 @@ irix_solib_create_inferior_hook (void)
      can go groveling around in the dynamic linker structures to find
      out what we need to know about them. */
 
+  tp = inferior_thread ();
   clear_proceed_status ();
   stop_soon = STOP_QUIETLY;
-  stop_signal = TARGET_SIGNAL_0;
+  tp->stop_signal = TARGET_SIGNAL_0;
   do
     {
-      target_resume (pid_to_ptid (-1), 0, stop_signal);
+      target_resume (pid_to_ptid (-1), 0, tp->stop_signal);
       wait_for_inferior (0);
     }
-  while (stop_signal != TARGET_SIGNAL_TRAP);
+  while (tp->stop_signal != TARGET_SIGNAL_TRAP);
 
   /* We are now either at the "mapping complete" breakpoint (or somewhere
      else, a condition we aren't prepared to deal with anyway), so adjust
index 3f9dca4..b83a8ec 100644 (file)
@@ -53,6 +53,7 @@
 #include "objfiles.h"
 #include "target.h"
 #include "inferior.h"
+#include "gdbthread.h"
 #include "solist.h"
 
 #ifdef USE_LDR_ROUTINES
@@ -306,6 +307,8 @@ osf_clear_solib (void)
 static void
 osf_solib_create_inferior_hook (void)
 {
+  struct thread_info *tp;
+
   /* If we are attaching to the inferior, the shared libraries
      have already been mapped, so nothing more to do.  */
   if (attach_flag)
@@ -330,15 +333,16 @@ osf_solib_create_inferior_hook (void)
   if (!target_can_run (&current_target))
     return;
 
+  tp = inferior_thread ();
   clear_proceed_status ();
   stop_soon = STOP_QUIETLY;
-  stop_signal = TARGET_SIGNAL_0;
+  tp->stop_signal = TARGET_SIGNAL_0;
   do
     {
-      target_resume (minus_one_ptid, 0, stop_signal);
+      target_resume (minus_one_ptid, 0, tp->stop_signal);
       wait_for_inferior (0);
     }
-  while (stop_signal != TARGET_SIGNAL_TRAP);
+  while (tp->stop_signal != TARGET_SIGNAL_TRAP);
 
   /*  solib_add will call reinit_frame_cache.
      But we are stopped in the runtime loader and we do not have symbols
index 6e5b440..c83b057 100644 (file)
@@ -36,6 +36,7 @@
 #include "objfiles.h"
 #include "gdbcore.h"
 #include "inferior.h"
+#include "gdbthread.h"
 #include "solist.h"
 #include "bcache.h"
 #include "regcache.h"
@@ -737,6 +738,8 @@ sunos_special_symbol_handling (void)
 static void
 sunos_solib_create_inferior_hook (void)
 {
+  struct thread_info *tp;
+
   if ((debug_base = locate_base ()) == 0)
     {
       /* Can't find the symbol or the executable is statically linked. */
@@ -758,15 +761,16 @@ sunos_solib_create_inferior_hook (void)
      can go groveling around in the dynamic linker structures to find
      out what we need to know about them. */
 
+  tp = inferior_thread ();
   clear_proceed_status ();
   stop_soon = STOP_QUIETLY;
-  stop_signal = TARGET_SIGNAL_0;
+  tp->stop_signal = TARGET_SIGNAL_0;
   do
     {
-      target_resume (pid_to_ptid (-1), 0, stop_signal);
+      target_resume (pid_to_ptid (-1), 0, tp->stop_signal);
       wait_for_inferior (0);
     }
-  while (stop_signal != TARGET_SIGNAL_TRAP);
+  while (tp->stop_signal != TARGET_SIGNAL_TRAP);
   stop_soon = NO_STOP_QUIETLY;
 
   /* We are now either at the "mapping complete" breakpoint (or somewhere
index fc6bf6f..032ae19 100644 (file)
@@ -31,6 +31,7 @@
 #include "gdbcore.h"
 #include "target.h"
 #include "inferior.h"
+#include "gdbthread.h"
 
 #include "gdb_assert.h"
 
@@ -1560,6 +1561,8 @@ svr4_relocate_main_executable (void)
 static void
 svr4_solib_create_inferior_hook (void)
 {
+  struct thread_info *tp;
+
   /* Relocate the main executable if necessary.  */
   svr4_relocate_main_executable ();
 
@@ -1579,15 +1582,17 @@ svr4_solib_create_inferior_hook (void)
      can go groveling around in the dynamic linker structures to find
      out what we need to know about them. */
 
+  tp = inferior_thread ();
+
   clear_proceed_status ();
   stop_soon = STOP_QUIETLY;
-  stop_signal = TARGET_SIGNAL_0;
+  tp->stop_signal = TARGET_SIGNAL_0;
   do
     {
-      target_resume (pid_to_ptid (-1), 0, stop_signal);
+      target_resume (pid_to_ptid (-1), 0, tp->stop_signal);
       wait_for_inferior (0);
     }
-  while (stop_signal != TARGET_SIGNAL_TRAP);
+  while (tp->stop_signal != TARGET_SIGNAL_TRAP);
   stop_soon = NO_STOP_QUIETLY;
 #endif /* defined(_SCO_DS) */
 }
index 9d9831c..33b4795 100644 (file)
@@ -446,8 +446,7 @@ load_infrun_state (ptid_t ptid,
                   struct continuation **continuations,
                   struct continuation **intermediate_continuations,
                   int *stop_step,
-                  int *step_multi,
-                  enum target_signal *stop_signal)
+                  int *step_multi)
 {
   struct thread_info *tp;
 
@@ -467,7 +466,6 @@ load_infrun_state (ptid_t ptid,
       tp->intermediate_continuations = NULL;
       *stop_step = tp->stop_step;
       *step_multi = tp->step_multi;
-      *stop_signal = tp->stop_signal;
     }
 }
 
@@ -478,8 +476,7 @@ save_infrun_state (ptid_t ptid,
                   struct continuation *continuations,
                   struct continuation *intermediate_continuations,
                   int stop_step,
-                  int step_multi,
-                  enum target_signal stop_signal)
+                  int step_multi)
 {
   struct thread_info *tp;
 
@@ -497,7 +494,6 @@ save_infrun_state (ptid_t ptid,
       tp->intermediate_continuations = intermediate_continuations;
       tp->stop_step = stop_step;
       tp->step_multi = step_multi;
-      tp->stop_signal = stop_signal;
     }
 }
 
index e84214d..0671470 100644 (file)
@@ -1523,6 +1523,7 @@ do_initial_win32_stuff (DWORD pid)
 {
   extern int stop_after_trap;
   int i;
+  struct thread_info *tp;
 
   last_sig = TARGET_SIGNAL_0;
   event_count = 0;
@@ -1551,8 +1552,9 @@ do_initial_win32_stuff (DWORD pid)
     {
       stop_after_trap = 1;
       wait_for_inferior (0);
-      if (stop_signal != TARGET_SIGNAL_TRAP)
-       resume (0, stop_signal);
+      tp = inferior_thread ();
+      if (tp->stop_signal != TARGET_SIGNAL_TRAP)
+       resume (0, tp->stop_signal);
       else
        break;
     }
index e84214d..0671470 100644 (file)
@@ -1523,6 +1523,7 @@ do_initial_win32_stuff (DWORD pid)
 {
   extern int stop_after_trap;
   int i;
+  struct thread_info *tp;
 
   last_sig = TARGET_SIGNAL_0;
   event_count = 0;
@@ -1551,8 +1552,9 @@ do_initial_win32_stuff (DWORD pid)
     {
       stop_after_trap = 1;
       wait_for_inferior (0);
-      if (stop_signal != TARGET_SIGNAL_TRAP)
-       resume (0, stop_signal);
+      tp = inferior_thread ();
+      if (tp->stop_signal != TARGET_SIGNAL_TRAP)
+       resume (0, tp->stop_signal);
       else
        break;
     }