This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC: 5/9] Make stop_signal per-thread in all-stop, and don't context-switch it


This patch removes the global stop_signal, in favour of accessing
the equivalent member in thread_info.

This field was already per-thread in non-stop, since in
non-stop we can have multiple threads stepping independently.
This patch makes it per-thread too in all-stop.

Of noteworthy importance:

 - When generating a core dump with gcore, GDB currently records
the same stop_signal in all threads.  BFD, on the other end, and by
consequence, the core target, while reading a core dump, ignores the signal
associated with every thread but the last one to be read.  This looked
surprising to me, but, I've kept the behaviour.

 - When a multi-threaded program stopped with a signal that has
"Pass to program" set to yes, and the target OS has a notion of per-thread
signal queues, and the user switches to another thread, and issues
continue, because stop_signal was global, we'd pass the stop_signal to
a different thread that originally reported it.  This leads to cases like
PR2276.  I'm not looking for behaviour changes with this patch, so
to keep the old behaviour, I've needed the changes in `proceed' below.

-- 
Pedro Alves
2008-08-16  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.

---
 gdb/fbsd-nat.c    |   25 ++++++++++
 gdb/fork-child.c  |    7 ++-
 gdb/gdbthread.h   |    7 +--
 gdb/infcmd.c      |   10 +---
 gdb/inferior.h    |    4 -
 gdb/infrun.c      |  123 ++++++++++++++++++++++++++++++++----------------------
 gdb/linux-nat.c   |   77 ++++++++++++++++-----------------
 gdb/procfs.c      |   30 ++++++++++++-
 gdb/solib-irix.c  |   10 +++-
 gdb/solib-osf.c   |   10 +++-
 gdb/solib-sunos.c |   10 +++-
 gdb/solib-svr4.c  |   11 +++-
 gdb/thread.c      |    8 ---
 gdb/win32-nat.c   |    6 +-
 14 files changed, 209 insertions(+), 129 deletions(-)

Index: src/gdb/inferior.h
===================================================================
--- src.orig/gdb/inferior.h	2008-08-16 14:20:52.000000000 +0100
+++ src/gdb/inferior.h	2008-08-16 16:13:44.000000000 +0100
@@ -279,10 +279,6 @@ extern void interrupt_target_command (ch
 
 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: src/gdb/gdbthread.h
===================================================================
--- src.orig/gdb/gdbthread.h	2008-08-16 14:20:56.000000000 +0100
+++ src/gdb/gdbthread.h	2008-08-16 16:13:44.000000000 +0100
@@ -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 pt
 			       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 pt
 			       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: src/gdb/thread.c
===================================================================
--- src.orig/gdb/thread.c	2008-08-16 14:20:56.000000000 +0100
+++ src/gdb/thread.c	2008-08-16 16:13:44.000000000 +0100
@@ -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: src/gdb/infcmd.c
===================================================================
--- src.orig/gdb/infcmd.c	2008-08-16 14:20:56.000000000 +0100
+++ src/gdb/infcmd.c	2008-08-16 16:13:44.000000000 +0100
@@ -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;
@@ -1528,11 +1524,11 @@ It stopped at a breakpoint that has sinc
 	  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: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c	2008-08-16 14:20:56.000000000 +0100
+++ src/gdb/infrun.c	2008-08-16 16:14:01.000000000 +0100
@@ -1074,6 +1074,10 @@ a command like `return' or `jump' to con
         }
 
       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);
@@ -1178,6 +1182,7 @@ proceed (CORE_ADDR addr, enum target_sig
   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);
@@ -1252,12 +1257,34 @@ proceed (CORE_ADDR addr, enum target_sig
   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);
+	  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 ();
 
@@ -1299,7 +1326,7 @@ proceed (CORE_ADDR addr, enum target_sig
   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.  */
@@ -1354,9 +1381,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. */
 
@@ -1701,15 +1725,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);
@@ -2010,7 +2032,6 @@ handle_inferior_event (struct execution_
       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
@@ -2020,7 +2041,7 @@ handle_inferior_event (struct execution_
          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;
@@ -2031,7 +2052,6 @@ handle_inferior_event (struct execution_
     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;
@@ -2052,17 +2072,16 @@ handle_inferior_event (struct execution_
       /* 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));
@@ -2096,10 +2115,11 @@ handle_inferior_event (struct execution_
       /* 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
@@ -2126,7 +2146,7 @@ handle_inferior_event (struct execution_
     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
@@ -2169,7 +2189,8 @@ targets should add new threads to the th
   /* 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));
 
@@ -2203,7 +2224,7 @@ targets should add new threads to the th
       /* 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");
@@ -2232,7 +2253,7 @@ targets should add new threads to the th
 
       /* 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;
 
@@ -2266,7 +2287,7 @@ targets should add new threads to the th
      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;
 
@@ -2485,7 +2506,7 @@ targets should add new threads to the th
   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))
@@ -2542,16 +2563,16 @@ targets should add new threads to the th
      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");
@@ -2583,11 +2604,11 @@ targets should add new threads to the th
 	 (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;
 	}
 
@@ -2618,7 +2639,7 @@ targets should add new threads to the th
          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
@@ -2628,7 +2649,7 @@ targets should add new threads to the th
 	{
 	  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;
 	}
     }
 
@@ -2649,17 +2670,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;
@@ -2670,8 +2692,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
@@ -2699,7 +2721,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 ()),
@@ -3531,12 +3553,14 @@ keep_going (struct execution_control_sta
   /* 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
     {
@@ -3591,11 +3615,12 @@ keep_going (struct execution_control_sta
          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);
@@ -4380,7 +4405,7 @@ save_inferior_status (int restore_stack_
   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;
@@ -4434,7 +4459,7 @@ restore_inferior_status (struct inferior
 {
   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: src/gdb/fbsd-nat.c
===================================================================
--- src.orig/gdb/fbsd-nat.c	2008-08-16 14:18:51.000000000 +0100
+++ src/gdb/fbsd-nat.c	2008-08-16 14:20:57.000000000 +0100
@@ -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) (C
   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_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: src/gdb/fork-child.c
===================================================================
--- src.orig/gdb/fork-child.c	2008-08-16 14:18:51.000000000 +0100
+++ src/gdb/fork-child.c	2008-08-16 14:20:57.000000000 +0100
@@ -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: src/gdb/linux-nat.c
===================================================================
--- src.orig/gdb/linux-nat.c	2008-08-16 14:20:45.000000000 +0100
+++ src/gdb/linux-nat.c	2008-08-16 14:20:57.000000000 +0100
@@ -1456,18 +1456,10 @@ get_pending_status (struct lwp_info *lp,
 	{
 	  /* 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
@@ -1495,9 +1487,10 @@ GPT: lwp %s had signal %s, but it is in 
     {
       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);
@@ -3341,12 +3334,35 @@ linux_nat_find_memory_regions (int (*fun
   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;
@@ -3441,6 +3457,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
@@ -3454,25 +3471,13 @@ linux_nat_corefile_thread_callback (stru
   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.  */
 
@@ -3519,18 +3524,10 @@ linux_nat_make_corefile_notes (bfd *obfd
   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: src/gdb/procfs.c
===================================================================
--- src.orig/gdb/procfs.c	2008-08-16 14:19:34.000000000 +0100
+++ src/gdb/procfs.c	2008-08-16 14:22:11.000000000 +0100
@@ -6051,13 +6051,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;
@@ -6095,6 +6118,7 @@ struct procfs_corefile_thread_data {
   bfd *obfd;
   char *note_data;
   int *note_size;
+  enum target_signal stop_signal;
 };
 
 static int
@@ -6108,7 +6132,8 @@ procfs_corefile_thread_callback (procinf
       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;
@@ -6162,6 +6187,7 @@ procfs_make_note_section (bfd *obfd, int
   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: src/gdb/solib-irix.c
===================================================================
--- src.orig/gdb/solib-irix.c	2008-08-16 14:18:51.000000000 +0100
+++ src/gdb/solib-irix.c	2008-08-16 14:20:57.000000000 +0100
@@ -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: src/gdb/solib-osf.c
===================================================================
--- src.orig/gdb/solib-osf.c	2008-08-16 14:18:51.000000000 +0100
+++ src/gdb/solib-osf.c	2008-08-16 14:30:08.000000000 +0100
@@ -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: src/gdb/solib-sunos.c
===================================================================
--- src.orig/gdb/solib-sunos.c	2008-08-16 14:18:51.000000000 +0100
+++ src/gdb/solib-sunos.c	2008-08-16 14:30:18.000000000 +0100
@@ -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"
@@ -738,6 +739,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. */
@@ -759,15 +762,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: src/gdb/solib-svr4.c
===================================================================
--- src.orig/gdb/solib-svr4.c	2008-08-16 14:18:51.000000000 +0100
+++ src/gdb/solib-svr4.c	2008-08-16 14:29:51.000000000 +0100
@@ -31,6 +31,7 @@
 #include "gdbcore.h"
 #include "target.h"
 #include "inferior.h"
+#include "gdbthread.h"
 
 #include "gdb_assert.h"
 
@@ -1388,6 +1389,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 ();
 
@@ -1407,15 +1410,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: src/gdb/win32-nat.c
===================================================================
--- src.orig/gdb/win32-nat.c	2008-08-16 14:18:51.000000000 +0100
+++ src/gdb/win32-nat.c	2008-08-16 14:20:57.000000000 +0100
@@ -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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]