aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog53
-rw-r--r--gdb/fbsd-nat.c25
-rw-r--r--gdb/fork-child.c7
-rw-r--r--gdb/gdbthread.h7
-rw-r--r--gdb/infcmd.c10
-rw-r--r--gdb/inferior.h4
-rw-r--r--gdb/infrun.c131
-rw-r--r--gdb/linux-nat.c77
-rw-r--r--gdb/procfs.c30
-rw-r--r--gdb/solib-irix.c10
-rw-r--r--gdb/solib-osf.c10
-rw-r--r--gdb/solib-sunos.c10
-rw-r--r--gdb/solib-svr4.c11
-rw-r--r--gdb/thread.c8
-rw-r--r--gdb/win32-nat.c6
-rw-r--r--gdb/windows-nat.c6
16 files changed, 274 insertions, 131 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c0f2597..b6b451b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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
diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index 6f442cc..215d2a7 100644
--- a/gdb/fbsd-nat.c
+++ b/gdb/fbsd-nat.c
@@ -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);
diff --git a/gdb/fork-child.c b/gdb/fork-child.c
index 229770f..269dd43 100644
--- a/gdb/fork-child.c
+++ b/gdb/fork-child.c
@@ -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
{
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index ca74976..3082abf 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -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);
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index a86f236..055b228 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -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)
diff --git a/gdb/inferior.h b/gdb/inferior.h
index f39cc2c..78af8c2 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -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;
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 4e28c22..d34fc20 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -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;
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 07ded10..42e19b5 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -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);
diff --git a/gdb/procfs.c b/gdb/procfs.c
index beeb4f5..e8cd6d9 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -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. */
diff --git a/gdb/solib-irix.c b/gdb/solib-irix.c
index 0e80b94..5b612ec 100644
--- a/gdb/solib-irix.c
+++ b/gdb/solib-irix.c
@@ -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
diff --git a/gdb/solib-osf.c b/gdb/solib-osf.c
index 3f9dca4..b83a8ec 100644
--- a/gdb/solib-osf.c
+++ b/gdb/solib-osf.c
@@ -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
diff --git a/gdb/solib-sunos.c b/gdb/solib-sunos.c
index 6e5b440..c83b057 100644
--- a/gdb/solib-sunos.c
+++ b/gdb/solib-sunos.c
@@ -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
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index fc6bf6f..032ae19 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -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) */
}
diff --git a/gdb/thread.c b/gdb/thread.c
index 9d9831c..33b4795 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -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;
}
}
diff --git a/gdb/win32-nat.c b/gdb/win32-nat.c
index e84214d..0671470 100644
--- a/gdb/win32-nat.c
+++ b/gdb/win32-nat.c
@@ -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;
}
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index e84214d..0671470 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -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;
}