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:
parent
32400bebb2
commit
2020b7abd8
16 changed files with 274 additions and 131 deletions
|
@ -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>
|
2008-09-08 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
* gdbthread.h (struct thread_info): Add comments around
|
* gdbthread.h (struct thread_info): Add comments around
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "inferior.h"
|
#include "inferior.h"
|
||||||
#include "regcache.h"
|
#include "regcache.h"
|
||||||
#include "regset.h"
|
#include "regset.h"
|
||||||
|
#include "gdbthread.h"
|
||||||
|
|
||||||
#include "gdb_assert.h"
|
#include "gdb_assert.h"
|
||||||
#include "gdb_string.h"
|
#include "gdb_string.h"
|
||||||
|
@ -137,6 +138,28 @@ fbsd_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
|
||||||
return 0;
|
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
|
/* Create appropriate note sections for a corefile, returning them in
|
||||||
allocated memory. */
|
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,
|
note_data = elfcore_write_prstatus (obfd, note_data, note_size,
|
||||||
ptid_get_pid (inferior_ptid),
|
ptid_get_pid (inferior_ptid),
|
||||||
stop_signal, &gregs);
|
find_stop_signal (), &gregs);
|
||||||
|
|
||||||
size = sizeof fpregs;
|
size = sizeof fpregs;
|
||||||
regset = gdbarch_regset_from_core_section (gdbarch, ".reg2", size);
|
regset = gdbarch_regset_from_core_section (gdbarch, ".reg2", size);
|
||||||
|
|
|
@ -434,15 +434,18 @@ startup_inferior (int ntraps)
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
struct thread_info *tp;
|
||||||
|
|
||||||
/* Make wait_for_inferior be quiet. */
|
/* Make wait_for_inferior be quiet. */
|
||||||
stop_soon = STOP_QUIETLY;
|
stop_soon = STOP_QUIETLY;
|
||||||
wait_for_inferior (1);
|
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.
|
/* Let shell child handle its own signals in its own way.
|
||||||
FIXME: what if child has exited? Must exit loop
|
FIXME: what if child has exited? Must exit loop
|
||||||
somehow. */
|
somehow. */
|
||||||
resume (0, stop_signal);
|
resume (0, tp->stop_signal);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -149,6 +149,7 @@ struct thread_info
|
||||||
int stop_step;
|
int stop_step;
|
||||||
int step_multi;
|
int step_multi;
|
||||||
|
|
||||||
|
/* Last signal that the inferior received (why it stopped). */
|
||||||
enum target_signal stop_signal;
|
enum target_signal stop_signal;
|
||||||
|
|
||||||
/* Chain containing status of breakpoint(s) the thread stopped
|
/* 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 *continuations,
|
||||||
struct continuation *intermediate_continuations,
|
struct continuation *intermediate_continuations,
|
||||||
int stop_step,
|
int stop_step,
|
||||||
int step_multi,
|
int step_multi);
|
||||||
enum target_signal stop_signal);
|
|
||||||
|
|
||||||
/* infrun context switch: load the debugger state previously saved
|
/* infrun context switch: load the debugger state previously saved
|
||||||
for the given thread. */
|
for the given thread. */
|
||||||
|
@ -233,8 +233,7 @@ extern void load_infrun_state (ptid_t ptid,
|
||||||
struct continuation **continuations,
|
struct continuation **continuations,
|
||||||
struct continuation **intermediate_continuations,
|
struct continuation **intermediate_continuations,
|
||||||
int *stop_step,
|
int *stop_step,
|
||||||
int *step_multi,
|
int *step_multi);
|
||||||
enum target_signal *stop_signal);
|
|
||||||
|
|
||||||
/* Switch from one thread to another. */
|
/* Switch from one thread to another. */
|
||||||
extern void switch_to_thread (ptid_t ptid);
|
extern void switch_to_thread (ptid_t ptid);
|
||||||
|
|
10
gdb/infcmd.c
10
gdb/infcmd.c
|
@ -147,10 +147,6 @@ static char *inferior_io_terminal;
|
||||||
|
|
||||||
ptid_t inferior_ptid;
|
ptid_t inferior_ptid;
|
||||||
|
|
||||||
/* Last signal that the inferior received (why it stopped). */
|
|
||||||
|
|
||||||
enum target_signal stop_signal;
|
|
||||||
|
|
||||||
/* Address at which inferior stopped. */
|
/* Address at which inferior stopped. */
|
||||||
|
|
||||||
CORE_ADDR stop_pc;
|
CORE_ADDR stop_pc;
|
||||||
|
@ -1505,11 +1501,11 @@ It stopped at a breakpoint that has since been deleted.\n"));
|
||||||
stat = bpstat_num (&bs, &num);
|
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"),
|
printf_filtered (_("It stopped with signal %s, %s.\n"),
|
||||||
target_signal_to_name (stop_signal),
|
target_signal_to_name (tp->stop_signal),
|
||||||
target_signal_to_string (stop_signal));
|
target_signal_to_string (tp->stop_signal));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!from_tty)
|
if (!from_tty)
|
||||||
|
|
|
@ -279,10 +279,6 @@ extern void interrupt_target_command (char *args, int from_tty);
|
||||||
|
|
||||||
extern void interrupt_target_1 (int all_threads);
|
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. */
|
/* Address at which inferior stopped. */
|
||||||
|
|
||||||
extern CORE_ADDR stop_pc;
|
extern CORE_ADDR stop_pc;
|
||||||
|
|
131
gdb/infrun.c
131
gdb/infrun.c
|
@ -1078,6 +1078,10 @@ a command like `return' or `jump' to continue execution."));
|
||||||
}
|
}
|
||||||
|
|
||||||
target_resume (resume_ptid, step, sig);
|
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);
|
discard_cleanups (old_cleanups);
|
||||||
|
@ -1182,6 +1186,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
|
||||||
struct thread_info *tp;
|
struct thread_info *tp;
|
||||||
CORE_ADDR pc = regcache_read_pc (regcache);
|
CORE_ADDR pc = regcache_read_pc (regcache);
|
||||||
int oneproc = 0;
|
int oneproc = 0;
|
||||||
|
enum target_signal stop_signal;
|
||||||
|
|
||||||
if (step > 0)
|
if (step > 0)
|
||||||
step_start_function = find_pc_function (pc);
|
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))
|
if (! tp->trap_expected || use_displaced_stepping (gdbarch))
|
||||||
insert_breakpoints ();
|
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)
|
if (siggnal != TARGET_SIGNAL_DEFAULT)
|
||||||
stop_signal = siggnal;
|
tp->stop_signal = siggnal;
|
||||||
/* If this signal should not be seen by program,
|
/* If this signal should not be seen by program,
|
||||||
give it zero. Used for debugging signals. */
|
give it zero. Used for debugging signals. */
|
||||||
else if (!signal_program[stop_signal])
|
else if (!signal_program[tp->stop_signal])
|
||||||
stop_signal = TARGET_SIGNAL_0;
|
tp->stop_signal = TARGET_SIGNAL_0;
|
||||||
|
|
||||||
annotate_starting ();
|
annotate_starting ();
|
||||||
|
|
||||||
|
@ -1300,7 +1330,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
|
||||||
init_infwait_state ();
|
init_infwait_state ();
|
||||||
|
|
||||||
/* Resume inferior. */
|
/* 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)
|
/* Wait for it to stop (if not standalone)
|
||||||
and in any case decode why it stopped, and act accordingly. */
|
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);
|
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. */
|
/* The first resume is not following a fork/vfork/exec. */
|
||||||
pending_follow.kind = TARGET_WAITKIND_SPURIOUS; /* I.e., none. */
|
pending_follow.kind = TARGET_WAITKIND_SPURIOUS; /* I.e., none. */
|
||||||
|
|
||||||
|
@ -1712,15 +1739,13 @@ context_switch (ptid_t ptid)
|
||||||
save_infrun_state (inferior_ptid,
|
save_infrun_state (inferior_ptid,
|
||||||
cmd_continuation, intermediate_continuation,
|
cmd_continuation, intermediate_continuation,
|
||||||
stop_step,
|
stop_step,
|
||||||
step_multi,
|
step_multi);
|
||||||
stop_signal);
|
|
||||||
|
|
||||||
/* Load infrun state for the new thread. */
|
/* Load infrun state for the new thread. */
|
||||||
load_infrun_state (ptid,
|
load_infrun_state (ptid,
|
||||||
&cmd_continuation, &intermediate_continuation,
|
&cmd_continuation, &intermediate_continuation,
|
||||||
&stop_step,
|
&stop_step,
|
||||||
&step_multi,
|
&step_multi);
|
||||||
&stop_signal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_to_thread (ptid);
|
switch_to_thread (ptid);
|
||||||
|
@ -2023,7 +2048,6 @@ handle_inferior_event (struct execution_control_state *ecs)
|
||||||
if (debug_infrun)
|
if (debug_infrun)
|
||||||
fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SIGNALLED\n");
|
fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SIGNALLED\n");
|
||||||
stop_print_frame = 0;
|
stop_print_frame = 0;
|
||||||
stop_signal = ecs->ws.value.sig;
|
|
||||||
target_terminal_ours (); /* Must do this before mourn anyway */
|
target_terminal_ours (); /* Must do this before mourn anyway */
|
||||||
|
|
||||||
/* Note: By definition of TARGET_WAITKIND_SIGNALLED, we shouldn't
|
/* 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. */
|
may be needed. */
|
||||||
target_mourn_inferior ();
|
target_mourn_inferior ();
|
||||||
|
|
||||||
print_stop_reason (SIGNAL_EXITED, stop_signal);
|
print_stop_reason (SIGNAL_EXITED, ecs->ws.value.sig);
|
||||||
singlestep_breakpoints_inserted_p = 0;
|
singlestep_breakpoints_inserted_p = 0;
|
||||||
stop_stepping (ecs);
|
stop_stepping (ecs);
|
||||||
return;
|
return;
|
||||||
|
@ -2044,7 +2068,6 @@ handle_inferior_event (struct execution_control_state *ecs)
|
||||||
case TARGET_WAITKIND_VFORKED:
|
case TARGET_WAITKIND_VFORKED:
|
||||||
if (debug_infrun)
|
if (debug_infrun)
|
||||||
fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_FORKED\n");
|
fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_FORKED\n");
|
||||||
stop_signal = TARGET_SIGNAL_TRAP;
|
|
||||||
pending_follow.kind = ecs->ws.kind;
|
pending_follow.kind = ecs->ws.kind;
|
||||||
|
|
||||||
pending_follow.fork_event.parent_pid = ecs->ptid;
|
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 no catchpoint triggered for this, then keep going. */
|
||||||
if (ecs->random_signal)
|
if (ecs->random_signal)
|
||||||
{
|
{
|
||||||
stop_signal = TARGET_SIGNAL_0;
|
ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
|
||||||
keep_going (ecs);
|
keep_going (ecs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ecs->event_thread->stop_signal = TARGET_SIGNAL_TRAP;
|
||||||
goto process_event_stop_test;
|
goto process_event_stop_test;
|
||||||
|
|
||||||
case TARGET_WAITKIND_EXECD:
|
case TARGET_WAITKIND_EXECD:
|
||||||
if (debug_infrun)
|
if (debug_infrun)
|
||||||
fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_EXECD\n");
|
fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_EXECD\n");
|
||||||
stop_signal = TARGET_SIGNAL_TRAP;
|
|
||||||
|
|
||||||
pending_follow.execd_pathname =
|
pending_follow.execd_pathname =
|
||||||
savestring (ecs->ws.value.execd_pathname,
|
savestring (ecs->ws.value.execd_pathname,
|
||||||
strlen (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 no catchpoint triggered for this, then keep going. */
|
||||||
if (ecs->random_signal)
|
if (ecs->random_signal)
|
||||||
{
|
{
|
||||||
stop_signal = TARGET_SIGNAL_0;
|
ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
|
||||||
keep_going (ecs);
|
keep_going (ecs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ecs->event_thread->stop_signal = TARGET_SIGNAL_TRAP;
|
||||||
goto process_event_stop_test;
|
goto process_event_stop_test;
|
||||||
|
|
||||||
/* Be careful not to try to gather much state about a thread
|
/* 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:
|
case TARGET_WAITKIND_STOPPED:
|
||||||
if (debug_infrun)
|
if (debug_infrun)
|
||||||
fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_STOPPED\n");
|
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;
|
break;
|
||||||
|
|
||||||
/* We had an event in the inferior, but we are not interested
|
/* 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
|
/* 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
|
displaced single-step? (Doing so usually affects the PC, so do
|
||||||
it here, before we set stop_pc.) */
|
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));
|
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
|
/* We've either finished single-stepping past the single-step
|
||||||
breakpoint, or stopped for some other reason. It would be nice if
|
breakpoint, or stopped for some other reason. It would be nice if
|
||||||
we could tell, but we can't reliably. */
|
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)
|
if (debug_infrun)
|
||||||
fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n");
|
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
|
/* If we stopped for some other reason than single-stepping, ignore
|
||||||
the fact that we were supposed to switch back. */
|
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;
|
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,
|
another thread. If so, then step that thread past the breakpoint,
|
||||||
and continue it. */
|
and continue it. */
|
||||||
|
|
||||||
if (stop_signal == TARGET_SIGNAL_TRAP)
|
if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
|
||||||
{
|
{
|
||||||
int thread_hop_needed = 0;
|
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)
|
if (new_singlestep_pc != singlestep_pc)
|
||||||
{
|
{
|
||||||
|
enum target_signal stop_signal;
|
||||||
|
|
||||||
if (debug_infrun)
|
if (debug_infrun)
|
||||||
fprintf_unfiltered (gdb_stdlog, "infrun: unexpected thread,"
|
fprintf_unfiltered (gdb_stdlog, "infrun: unexpected thread,"
|
||||||
" but expected thread advanced also\n");
|
" 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
|
singlestep_ptid. Don't swap here, since that's
|
||||||
the context we want to use. Just fudge our
|
the context we want to use. Just fudge our
|
||||||
state and continue. */
|
state and continue. */
|
||||||
|
stop_signal = ecs->event_thread->stop_signal;
|
||||||
|
ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
|
||||||
ecs->ptid = singlestep_ptid;
|
ecs->ptid = singlestep_ptid;
|
||||||
ecs->event_thread = find_thread_pid (ecs->ptid);
|
ecs->event_thread = find_thread_pid (ecs->ptid);
|
||||||
|
ecs->event_thread->stop_signal = stop_signal;
|
||||||
stop_pc = new_singlestep_pc;
|
stop_pc = new_singlestep_pc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2498,7 +2527,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
|
||||||
ecs->random_signal = 0;
|
ecs->random_signal = 0;
|
||||||
stopped_by_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
|
&& ecs->event_thread->trap_expected
|
||||||
&& gdbarch_single_step_through_delay_p (current_gdbarch)
|
&& gdbarch_single_step_through_delay_p (current_gdbarch)
|
||||||
&& currently_stepping (ecs->event_thread))
|
&& 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
|
If we're doing a displaced step past a breakpoint, then the
|
||||||
breakpoint is always inserted at the original instruction;
|
breakpoint is always inserted at the original instruction;
|
||||||
non-standard signals can't be explained by the breakpoint. */
|
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
|
|| (! ecs->event_thread->trap_expected
|
||||||
&& breakpoint_inserted_here_p (stop_pc)
|
&& breakpoint_inserted_here_p (stop_pc)
|
||||||
&& (stop_signal == TARGET_SIGNAL_ILL
|
&& (ecs->event_thread->stop_signal == TARGET_SIGNAL_ILL
|
||||||
|| stop_signal == TARGET_SIGNAL_SEGV
|
|| ecs->event_thread->stop_signal == TARGET_SIGNAL_SEGV
|
||||||
|| stop_signal == TARGET_SIGNAL_EMT))
|
|| ecs->event_thread->stop_signal == TARGET_SIGNAL_EMT))
|
||||||
|| stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_NO_SIGSTOP
|
|| stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_NO_SIGSTOP
|
||||||
|| stop_soon == STOP_QUIETLY_REMOTE)
|
|| 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)
|
if (debug_infrun)
|
||||||
fprintf_unfiltered (gdb_stdlog, "infrun: stopped\n");
|
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
|
(e.g. gdbserver). We already rely on SIGTRAP being our
|
||||||
signal, so this is no exception. */
|
signal, so this is no exception. */
|
||||||
if (stop_soon == STOP_QUIETLY_NO_SIGSTOP
|
if (stop_soon == STOP_QUIETLY_NO_SIGSTOP
|
||||||
&& (stop_signal == TARGET_SIGNAL_STOP
|
&& (ecs->event_thread->stop_signal == TARGET_SIGNAL_STOP
|
||||||
|| stop_signal == TARGET_SIGNAL_TRAP))
|
|| ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP))
|
||||||
{
|
{
|
||||||
stop_stepping (ecs);
|
stop_stepping (ecs);
|
||||||
stop_signal = TARGET_SIGNAL_0;
|
ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
|
||||||
return;
|
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
|
be necessary for call dummies on a non-executable stack on
|
||||||
SPARC. */
|
SPARC. */
|
||||||
|
|
||||||
if (stop_signal == TARGET_SIGNAL_TRAP)
|
if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
|
||||||
ecs->random_signal
|
ecs->random_signal
|
||||||
= !(bpstat_explains_signal (ecs->event_thread->stop_bpstat)
|
= !(bpstat_explains_signal (ecs->event_thread->stop_bpstat)
|
||||||
|| ecs->event_thread->trap_expected
|
|| 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);
|
ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat);
|
||||||
if (!ecs->random_signal)
|
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;
|
int printed = 0;
|
||||||
|
|
||||||
if (debug_infrun)
|
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;
|
stopped_by_random_signal = 1;
|
||||||
|
|
||||||
if (signal_print[stop_signal])
|
if (signal_print[ecs->event_thread->stop_signal])
|
||||||
{
|
{
|
||||||
printed = 1;
|
printed = 1;
|
||||||
target_terminal_ours_for_output ();
|
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);
|
stop_stepping (ecs);
|
||||||
return;
|
return;
|
||||||
|
@ -2683,8 +2713,8 @@ process_event_stop_test:
|
||||||
target_terminal_inferior ();
|
target_terminal_inferior ();
|
||||||
|
|
||||||
/* Clear the signal if it should not be passed. */
|
/* Clear the signal if it should not be passed. */
|
||||||
if (signal_program[stop_signal] == 0)
|
if (signal_program[ecs->event_thread->stop_signal] == 0)
|
||||||
stop_signal = TARGET_SIGNAL_0;
|
ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
|
||||||
|
|
||||||
if (ecs->event_thread->prev_pc == read_pc ()
|
if (ecs->event_thread->prev_pc == read_pc ()
|
||||||
&& ecs->event_thread->trap_expected
|
&& ecs->event_thread->trap_expected
|
||||||
|
@ -2712,7 +2742,7 @@ process_event_stop_test:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ecs->event_thread->step_range_end != 0
|
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
|
&& (ecs->event_thread->step_range_start <= stop_pc
|
||||||
&& stop_pc < ecs->event_thread->step_range_end)
|
&& stop_pc < ecs->event_thread->step_range_end)
|
||||||
&& frame_id_eq (get_frame_id (get_current_frame ()),
|
&& 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
|
/* If we did not do break;, it means we should keep running the
|
||||||
inferior and not return to debugger. */
|
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
|
/* 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
|
the inferior, else we'd not get here) and we haven't yet
|
||||||
gotten our trap. Simply continue. */
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -3577,11 +3609,12 @@ keep_going (struct execution_control_state *ecs)
|
||||||
simulator; the simulator then delivers the hardware
|
simulator; the simulator then delivers the hardware
|
||||||
equivalent of a SIGNAL_TRAP to the program being debugged. */
|
equivalent of a SIGNAL_TRAP to the program being debugged. */
|
||||||
|
|
||||||
if (stop_signal == TARGET_SIGNAL_TRAP && !signal_program[stop_signal])
|
if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP
|
||||||
stop_signal = TARGET_SIGNAL_0;
|
&& !signal_program[ecs->event_thread->stop_signal])
|
||||||
|
ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
|
||||||
|
|
||||||
|
resume (currently_stepping (ecs->event_thread),
|
||||||
resume (currently_stepping (ecs->event_thread), stop_signal);
|
ecs->event_thread->stop_signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare_to_wait (ecs);
|
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 inferior_status *inf_status = XMALLOC (struct inferior_status);
|
||||||
struct thread_info *tp = inferior_thread ();
|
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_pc = stop_pc;
|
||||||
inf_status->stop_step = stop_step;
|
inf_status->stop_step = stop_step;
|
||||||
inf_status->stop_stack_dummy = stop_stack_dummy;
|
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 ();
|
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_pc = inf_status->stop_pc;
|
||||||
stop_step = inf_status->stop_step;
|
stop_step = inf_status->stop_step;
|
||||||
stop_stack_dummy = inf_status->stop_stack_dummy;
|
stop_stack_dummy = inf_status->stop_stack_dummy;
|
||||||
|
|
|
@ -1453,19 +1453,11 @@ get_pending_status (struct lwp_info *lp, int *status)
|
||||||
{
|
{
|
||||||
/* If the core knows the thread is not executing, then we
|
/* If the core knows the thread is not executing, then we
|
||||||
have the last signal recorded in
|
have the last signal recorded in
|
||||||
thread_info->stop_signal, unless this is inferior_ptid,
|
thread_info->stop_signal. */
|
||||||
in which case, it's in the global stop_signal, due to
|
|
||||||
context switching. */
|
|
||||||
|
|
||||||
if (ptid_equal (lp->ptid, inferior_ptid))
|
|
||||||
signo = stop_signal;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct thread_info *tp = find_thread_pid (lp->ptid);
|
struct thread_info *tp = find_thread_pid (lp->ptid);
|
||||||
gdb_assert (tp);
|
|
||||||
signo = tp->stop_signal;
|
signo = tp->stop_signal;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (signo != TARGET_SIGNAL_0
|
if (signo != TARGET_SIGNAL_0
|
||||||
&& !signal_pass_state (signo))
|
&& !signal_pass_state (signo))
|
||||||
|
@ -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 (GET_LWP (lp->ptid) == GET_LWP (last_ptid))
|
||||||
{
|
{
|
||||||
if (stop_signal != TARGET_SIGNAL_0
|
struct thread_info *tp = find_thread_pid (lp->ptid);
|
||||||
&& signal_pass_state (stop_signal))
|
if (tp->stop_signal != TARGET_SIGNAL_0
|
||||||
*status = W_STOPCODE (target_signal_to_host (stop_signal));
|
&& signal_pass_state (tp->stop_signal))
|
||||||
|
*status = W_STOPCODE (target_signal_to_host (tp->stop_signal));
|
||||||
}
|
}
|
||||||
else if (target_can_async_p ())
|
else if (target_can_async_p ())
|
||||||
queued_waitpid (GET_LWP (lp->ptid), status, __WALL);
|
queued_waitpid (GET_LWP (lp->ptid), status, __WALL);
|
||||||
|
@ -3338,12 +3331,35 @@ linux_nat_find_memory_regions (int (*func) (CORE_ADDR,
|
||||||
return 0;
|
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
|
/* Records the thread's register state for the corefile note
|
||||||
section. */
|
section. */
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
|
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_gregset_t gregs;
|
||||||
gdb_fpregset_t fpregs;
|
gdb_fpregset_t fpregs;
|
||||||
|
@ -3438,6 +3454,7 @@ struct linux_nat_corefile_thread_data
|
||||||
char *note_data;
|
char *note_data;
|
||||||
int *note_size;
|
int *note_size;
|
||||||
int num_notes;
|
int num_notes;
|
||||||
|
enum target_signal stop_signal;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Called by gdbthread.c once per thread. Records the thread's
|
/* 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,
|
args->note_data = linux_nat_do_thread_registers (args->obfd,
|
||||||
ti->ptid,
|
ti->ptid,
|
||||||
args->note_data,
|
args->note_data,
|
||||||
args->note_size);
|
args->note_size,
|
||||||
|
args->stop_signal);
|
||||||
args->num_notes++;
|
args->num_notes++;
|
||||||
|
|
||||||
return 0;
|
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
|
/* Fills the "to_make_corefile_note" target vector. Builds the note
|
||||||
section for a corefile, and returns it in a malloc buffer. */
|
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_data = note_data;
|
||||||
thread_args.note_size = note_size;
|
thread_args.note_size = note_size;
|
||||||
thread_args.num_notes = 0;
|
thread_args.num_notes = 0;
|
||||||
|
thread_args.stop_signal = find_stop_signal ();
|
||||||
iterate_over_lwps (linux_nat_corefile_thread_callback, &thread_args);
|
iterate_over_lwps (linux_nat_corefile_thread_callback, &thread_args);
|
||||||
if (thread_args.num_notes == 0)
|
gdb_assert (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;
|
note_data = thread_args.note_data;
|
||||||
}
|
|
||||||
|
|
||||||
auxv_len = target_read_alloc (¤t_target, TARGET_OBJECT_AUXV,
|
auxv_len = target_read_alloc (¤t_target, TARGET_OBJECT_AUXV,
|
||||||
NULL, &auxv);
|
NULL, &auxv);
|
||||||
|
|
30
gdb/procfs.c
30
gdb/procfs.c
|
@ -6045,13 +6045,36 @@ procfs_first_available (void)
|
||||||
return pid_to_ptid (procinfo_list ? procinfo_list->pid : -1);
|
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" =================== */
|
/* =================== GCORE .NOTE "MODULE" =================== */
|
||||||
#if defined (UNIXWARE) || defined (PIOCOPENLWP) || defined (PCAGENT)
|
#if defined (UNIXWARE) || defined (PIOCOPENLWP) || defined (PCAGENT)
|
||||||
/* gcore only implemented on solaris and unixware (so far) */
|
/* gcore only implemented on solaris and unixware (so far) */
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
procfs_do_thread_registers (bfd *obfd, ptid_t ptid,
|
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);
|
struct regcache *regcache = get_thread_regcache (ptid);
|
||||||
gdb_gregset_t gregs;
|
gdb_gregset_t gregs;
|
||||||
|
@ -6089,6 +6112,7 @@ struct procfs_corefile_thread_data {
|
||||||
bfd *obfd;
|
bfd *obfd;
|
||||||
char *note_data;
|
char *note_data;
|
||||||
int *note_size;
|
int *note_size;
|
||||||
|
enum target_signal stop_signal;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -6102,7 +6126,8 @@ procfs_corefile_thread_callback (procinfo *pi, procinfo *thread, void *data)
|
||||||
inferior_ptid = MERGEPID (pi->pid, thread->tid);
|
inferior_ptid = MERGEPID (pi->pid, thread->tid);
|
||||||
args->note_data = procfs_do_thread_registers (args->obfd, inferior_ptid,
|
args->note_data = procfs_do_thread_registers (args->obfd, inferior_ptid,
|
||||||
args->note_data,
|
args->note_data,
|
||||||
args->note_size);
|
args->note_size,
|
||||||
|
args->stop_signal);
|
||||||
inferior_ptid = saved_ptid;
|
inferior_ptid = saved_ptid;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -6156,6 +6181,7 @@ procfs_make_note_section (bfd *obfd, int *note_size)
|
||||||
thread_args.obfd = obfd;
|
thread_args.obfd = obfd;
|
||||||
thread_args.note_data = note_data;
|
thread_args.note_data = note_data;
|
||||||
thread_args.note_size = note_size;
|
thread_args.note_size = note_size;
|
||||||
|
thread_args.stop_signal = find_stop_signal ();
|
||||||
proc_iterate_over_threads (pi, procfs_corefile_thread_callback, &thread_args);
|
proc_iterate_over_threads (pi, procfs_corefile_thread_callback, &thread_args);
|
||||||
|
|
||||||
/* There should be always at least one thread. */
|
/* There should be always at least one thread. */
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "gdbcore.h"
|
#include "gdbcore.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "inferior.h"
|
#include "inferior.h"
|
||||||
|
#include "gdbthread.h"
|
||||||
|
|
||||||
#include "solist.h"
|
#include "solist.h"
|
||||||
#include "solib.h"
|
#include "solib.h"
|
||||||
|
@ -421,6 +422,8 @@ enable_break (void)
|
||||||
static void
|
static void
|
||||||
irix_solib_create_inferior_hook (void)
|
irix_solib_create_inferior_hook (void)
|
||||||
{
|
{
|
||||||
|
struct thread_info *tp;
|
||||||
|
|
||||||
if (!enable_break ())
|
if (!enable_break ())
|
||||||
{
|
{
|
||||||
warning (_("shared library handler failed to enable breakpoint"));
|
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
|
can go groveling around in the dynamic linker structures to find
|
||||||
out what we need to know about them. */
|
out what we need to know about them. */
|
||||||
|
|
||||||
|
tp = inferior_thread ();
|
||||||
clear_proceed_status ();
|
clear_proceed_status ();
|
||||||
stop_soon = STOP_QUIETLY;
|
stop_soon = STOP_QUIETLY;
|
||||||
stop_signal = TARGET_SIGNAL_0;
|
tp->stop_signal = TARGET_SIGNAL_0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
target_resume (pid_to_ptid (-1), 0, stop_signal);
|
target_resume (pid_to_ptid (-1), 0, tp->stop_signal);
|
||||||
wait_for_inferior (0);
|
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
|
/* We are now either at the "mapping complete" breakpoint (or somewhere
|
||||||
else, a condition we aren't prepared to deal with anyway), so adjust
|
else, a condition we aren't prepared to deal with anyway), so adjust
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "inferior.h"
|
#include "inferior.h"
|
||||||
|
#include "gdbthread.h"
|
||||||
#include "solist.h"
|
#include "solist.h"
|
||||||
|
|
||||||
#ifdef USE_LDR_ROUTINES
|
#ifdef USE_LDR_ROUTINES
|
||||||
|
@ -306,6 +307,8 @@ osf_clear_solib (void)
|
||||||
static void
|
static void
|
||||||
osf_solib_create_inferior_hook (void)
|
osf_solib_create_inferior_hook (void)
|
||||||
{
|
{
|
||||||
|
struct thread_info *tp;
|
||||||
|
|
||||||
/* If we are attaching to the inferior, the shared libraries
|
/* If we are attaching to the inferior, the shared libraries
|
||||||
have already been mapped, so nothing more to do. */
|
have already been mapped, so nothing more to do. */
|
||||||
if (attach_flag)
|
if (attach_flag)
|
||||||
|
@ -330,15 +333,16 @@ osf_solib_create_inferior_hook (void)
|
||||||
if (!target_can_run (¤t_target))
|
if (!target_can_run (¤t_target))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
tp = inferior_thread ();
|
||||||
clear_proceed_status ();
|
clear_proceed_status ();
|
||||||
stop_soon = STOP_QUIETLY;
|
stop_soon = STOP_QUIETLY;
|
||||||
stop_signal = TARGET_SIGNAL_0;
|
tp->stop_signal = TARGET_SIGNAL_0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
target_resume (minus_one_ptid, 0, stop_signal);
|
target_resume (minus_one_ptid, 0, tp->stop_signal);
|
||||||
wait_for_inferior (0);
|
wait_for_inferior (0);
|
||||||
}
|
}
|
||||||
while (stop_signal != TARGET_SIGNAL_TRAP);
|
while (tp->stop_signal != TARGET_SIGNAL_TRAP);
|
||||||
|
|
||||||
/* solib_add will call reinit_frame_cache.
|
/* solib_add will call reinit_frame_cache.
|
||||||
But we are stopped in the runtime loader and we do not have symbols
|
But we are stopped in the runtime loader and we do not have symbols
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
#include "gdbcore.h"
|
#include "gdbcore.h"
|
||||||
#include "inferior.h"
|
#include "inferior.h"
|
||||||
|
#include "gdbthread.h"
|
||||||
#include "solist.h"
|
#include "solist.h"
|
||||||
#include "bcache.h"
|
#include "bcache.h"
|
||||||
#include "regcache.h"
|
#include "regcache.h"
|
||||||
|
@ -737,6 +738,8 @@ sunos_special_symbol_handling (void)
|
||||||
static void
|
static void
|
||||||
sunos_solib_create_inferior_hook (void)
|
sunos_solib_create_inferior_hook (void)
|
||||||
{
|
{
|
||||||
|
struct thread_info *tp;
|
||||||
|
|
||||||
if ((debug_base = locate_base ()) == 0)
|
if ((debug_base = locate_base ()) == 0)
|
||||||
{
|
{
|
||||||
/* Can't find the symbol or the executable is statically linked. */
|
/* 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
|
can go groveling around in the dynamic linker structures to find
|
||||||
out what we need to know about them. */
|
out what we need to know about them. */
|
||||||
|
|
||||||
|
tp = inferior_thread ();
|
||||||
clear_proceed_status ();
|
clear_proceed_status ();
|
||||||
stop_soon = STOP_QUIETLY;
|
stop_soon = STOP_QUIETLY;
|
||||||
stop_signal = TARGET_SIGNAL_0;
|
tp->stop_signal = TARGET_SIGNAL_0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
target_resume (pid_to_ptid (-1), 0, stop_signal);
|
target_resume (pid_to_ptid (-1), 0, tp->stop_signal);
|
||||||
wait_for_inferior (0);
|
wait_for_inferior (0);
|
||||||
}
|
}
|
||||||
while (stop_signal != TARGET_SIGNAL_TRAP);
|
while (tp->stop_signal != TARGET_SIGNAL_TRAP);
|
||||||
stop_soon = NO_STOP_QUIETLY;
|
stop_soon = NO_STOP_QUIETLY;
|
||||||
|
|
||||||
/* We are now either at the "mapping complete" breakpoint (or somewhere
|
/* We are now either at the "mapping complete" breakpoint (or somewhere
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "gdbcore.h"
|
#include "gdbcore.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "inferior.h"
|
#include "inferior.h"
|
||||||
|
#include "gdbthread.h"
|
||||||
|
|
||||||
#include "gdb_assert.h"
|
#include "gdb_assert.h"
|
||||||
|
|
||||||
|
@ -1560,6 +1561,8 @@ svr4_relocate_main_executable (void)
|
||||||
static void
|
static void
|
||||||
svr4_solib_create_inferior_hook (void)
|
svr4_solib_create_inferior_hook (void)
|
||||||
{
|
{
|
||||||
|
struct thread_info *tp;
|
||||||
|
|
||||||
/* Relocate the main executable if necessary. */
|
/* Relocate the main executable if necessary. */
|
||||||
svr4_relocate_main_executable ();
|
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
|
can go groveling around in the dynamic linker structures to find
|
||||||
out what we need to know about them. */
|
out what we need to know about them. */
|
||||||
|
|
||||||
|
tp = inferior_thread ();
|
||||||
|
|
||||||
clear_proceed_status ();
|
clear_proceed_status ();
|
||||||
stop_soon = STOP_QUIETLY;
|
stop_soon = STOP_QUIETLY;
|
||||||
stop_signal = TARGET_SIGNAL_0;
|
tp->stop_signal = TARGET_SIGNAL_0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
target_resume (pid_to_ptid (-1), 0, stop_signal);
|
target_resume (pid_to_ptid (-1), 0, tp->stop_signal);
|
||||||
wait_for_inferior (0);
|
wait_for_inferior (0);
|
||||||
}
|
}
|
||||||
while (stop_signal != TARGET_SIGNAL_TRAP);
|
while (tp->stop_signal != TARGET_SIGNAL_TRAP);
|
||||||
stop_soon = NO_STOP_QUIETLY;
|
stop_soon = NO_STOP_QUIETLY;
|
||||||
#endif /* defined(_SCO_DS) */
|
#endif /* defined(_SCO_DS) */
|
||||||
}
|
}
|
||||||
|
|
|
@ -446,8 +446,7 @@ load_infrun_state (ptid_t ptid,
|
||||||
struct continuation **continuations,
|
struct continuation **continuations,
|
||||||
struct continuation **intermediate_continuations,
|
struct continuation **intermediate_continuations,
|
||||||
int *stop_step,
|
int *stop_step,
|
||||||
int *step_multi,
|
int *step_multi)
|
||||||
enum target_signal *stop_signal)
|
|
||||||
{
|
{
|
||||||
struct thread_info *tp;
|
struct thread_info *tp;
|
||||||
|
|
||||||
|
@ -467,7 +466,6 @@ load_infrun_state (ptid_t ptid,
|
||||||
tp->intermediate_continuations = NULL;
|
tp->intermediate_continuations = NULL;
|
||||||
*stop_step = tp->stop_step;
|
*stop_step = tp->stop_step;
|
||||||
*step_multi = tp->step_multi;
|
*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 *continuations,
|
||||||
struct continuation *intermediate_continuations,
|
struct continuation *intermediate_continuations,
|
||||||
int stop_step,
|
int stop_step,
|
||||||
int step_multi,
|
int step_multi)
|
||||||
enum target_signal stop_signal)
|
|
||||||
{
|
{
|
||||||
struct thread_info *tp;
|
struct thread_info *tp;
|
||||||
|
|
||||||
|
@ -497,7 +494,6 @@ save_infrun_state (ptid_t ptid,
|
||||||
tp->intermediate_continuations = intermediate_continuations;
|
tp->intermediate_continuations = intermediate_continuations;
|
||||||
tp->stop_step = stop_step;
|
tp->stop_step = stop_step;
|
||||||
tp->step_multi = step_multi;
|
tp->step_multi = step_multi;
|
||||||
tp->stop_signal = stop_signal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1523,6 +1523,7 @@ do_initial_win32_stuff (DWORD pid)
|
||||||
{
|
{
|
||||||
extern int stop_after_trap;
|
extern int stop_after_trap;
|
||||||
int i;
|
int i;
|
||||||
|
struct thread_info *tp;
|
||||||
|
|
||||||
last_sig = TARGET_SIGNAL_0;
|
last_sig = TARGET_SIGNAL_0;
|
||||||
event_count = 0;
|
event_count = 0;
|
||||||
|
@ -1551,8 +1552,9 @@ do_initial_win32_stuff (DWORD pid)
|
||||||
{
|
{
|
||||||
stop_after_trap = 1;
|
stop_after_trap = 1;
|
||||||
wait_for_inferior (0);
|
wait_for_inferior (0);
|
||||||
if (stop_signal != TARGET_SIGNAL_TRAP)
|
tp = inferior_thread ();
|
||||||
resume (0, stop_signal);
|
if (tp->stop_signal != TARGET_SIGNAL_TRAP)
|
||||||
|
resume (0, tp->stop_signal);
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1523,6 +1523,7 @@ do_initial_win32_stuff (DWORD pid)
|
||||||
{
|
{
|
||||||
extern int stop_after_trap;
|
extern int stop_after_trap;
|
||||||
int i;
|
int i;
|
||||||
|
struct thread_info *tp;
|
||||||
|
|
||||||
last_sig = TARGET_SIGNAL_0;
|
last_sig = TARGET_SIGNAL_0;
|
||||||
event_count = 0;
|
event_count = 0;
|
||||||
|
@ -1551,8 +1552,9 @@ do_initial_win32_stuff (DWORD pid)
|
||||||
{
|
{
|
||||||
stop_after_trap = 1;
|
stop_after_trap = 1;
|
||||||
wait_for_inferior (0);
|
wait_for_inferior (0);
|
||||||
if (stop_signal != TARGET_SIGNAL_TRAP)
|
tp = inferior_thread ();
|
||||||
resume (0, stop_signal);
|
if (tp->stop_signal != TARGET_SIGNAL_TRAP)
|
||||||
|
resume (0, tp->stop_signal);
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue