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.
This commit is contained in:
Pedro Alves 2008-09-08 21:51:18 +00:00
parent 32400bebb2
commit 2020b7abd8
16 changed files with 274 additions and 131 deletions

View file

@ -1,3 +1,56 @@
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

View 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);

View 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
{

View 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);

View 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)

View 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;

View 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;

View 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);

View 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. */

View 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

View 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

View 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

View 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) */
}

View 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;
}
}

View 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;
}

View 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;
}