mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-21 10:34:21 +08:00
Per-thread commands.
* gdbthread.h: Remove unneeded forward declarations. Include "inferior.h". (struct thread_info): Add continuations, intermediate_continuations, proceed_to_finish, step_over_calls, stop_step, step_multi and stop_signal members. (save_infrun_state): Add continuations, intermediate_continuations, proceed_to_finish, step_over_calls, stop_step, step_multi, stop_signal and stop_bpstat parameters. (load_infrun_state): Add continuations, intermediate_continuations, proceed_to_finish, step_over_calls, stop_step, step_multi, stop_signal and stop_bpstat parameters. * thread.c (load_infrun_state): In non-stop mode, load continuations, intermediate_continuations, proceed_to_finish, step_over_calls, stop_step, step_multi and stop_signal. (save_infrun_state): Store continuations, intermediate_continuations, proceed_to_finish, step_over_calls, stop_step, step_multi, stop_signal and stop_bpstat. (save_infrun_state): Store continuations, intermediate_continuations, proceed_to_finish, step_over_calls, stop_step, step_multi, stop_signal and stop_bpstat. (free_thread): Clear The thread's stop_bpstat. * inferior.h (context_switch_to): Declare. * infrun.c (ecss): New global. (context_switch): Context switch continuations, intermediate_continuations, proceed_to_finish, step_over_calls, stop_step, step_multi, stop_signal and stop_bpstat. (wait_for_inferior): Use global ecss. (async_ecss, async_ecs): Delete. (fetch_inferior_event): Use global ecss. (context_switch_to): New. * top.c (execute_command): In non-stop, only check if the current thread is running, in all-stop, check if there's any thread running. * breakpoint.c (bpstat_remove_breakpoint): New. (bpstat_remove_breakpoint_callback): New. (delete_breakpoint): Clear the stop_bpstats of all threads. * mi/mi-main.c (mi_cmd_execute): In non-stop, only check if the current thread is running, in all-stop, check if there's any thread running. * Makefile.in (gdbthread_h): Depend on $(inferior_h).
This commit is contained in:
@ -1,3 +1,56 @@
|
|||||||
|
2008-07-09 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
Vladimir Prus <vladimir@codesourcery.com>
|
||||||
|
|
||||||
|
Per-thread commands.
|
||||||
|
|
||||||
|
* gdbthread.h: Remove unneeded forward declarations.
|
||||||
|
Include "inferior.h".
|
||||||
|
(struct thread_info): Add continuations,
|
||||||
|
intermediate_continuations, proceed_to_finish, step_over_calls,
|
||||||
|
stop_step, step_multi and stop_signal members.
|
||||||
|
(save_infrun_state): Add continuations,
|
||||||
|
intermediate_continuations, proceed_to_finish, step_over_calls,
|
||||||
|
stop_step, step_multi, stop_signal and stop_bpstat parameters.
|
||||||
|
(load_infrun_state): Add continuations,
|
||||||
|
intermediate_continuations, proceed_to_finish, step_over_calls,
|
||||||
|
stop_step, step_multi, stop_signal and stop_bpstat parameters.
|
||||||
|
|
||||||
|
* thread.c (load_infrun_state): In non-stop mode, load
|
||||||
|
continuations, intermediate_continuations, proceed_to_finish,
|
||||||
|
step_over_calls, stop_step, step_multi and stop_signal.
|
||||||
|
(save_infrun_state): Store continuations,
|
||||||
|
intermediate_continuations, proceed_to_finish, step_over_calls,
|
||||||
|
stop_step, step_multi, stop_signal and stop_bpstat.
|
||||||
|
(save_infrun_state): Store continuations,
|
||||||
|
intermediate_continuations, proceed_to_finish, step_over_calls,
|
||||||
|
stop_step, step_multi, stop_signal and stop_bpstat.
|
||||||
|
(free_thread): Clear The thread's stop_bpstat.
|
||||||
|
|
||||||
|
* inferior.h (context_switch_to): Declare.
|
||||||
|
|
||||||
|
* infrun.c (ecss): New global.
|
||||||
|
(context_switch): Context switch continuations,
|
||||||
|
intermediate_continuations, proceed_to_finish, step_over_calls,
|
||||||
|
stop_step, step_multi, stop_signal and stop_bpstat.
|
||||||
|
(wait_for_inferior): Use global ecss.
|
||||||
|
(async_ecss, async_ecs): Delete.
|
||||||
|
(fetch_inferior_event): Use global ecss.
|
||||||
|
(context_switch_to): New.
|
||||||
|
|
||||||
|
* top.c (execute_command): In non-stop, only check if the current
|
||||||
|
thread is running, in all-stop, check if there's any thread
|
||||||
|
running.
|
||||||
|
|
||||||
|
* breakpoint.c (bpstat_remove_breakpoint): New.
|
||||||
|
(bpstat_remove_breakpoint_callback): New.
|
||||||
|
(delete_breakpoint): Clear the stop_bpstats of all threads.
|
||||||
|
|
||||||
|
* mi/mi-main.c (mi_cmd_execute): In non-stop, only check if the
|
||||||
|
current thread is running, in all-stop, check if there's any
|
||||||
|
thread running.
|
||||||
|
|
||||||
|
* Makefile.in (gdbthread_h): Depend on $(inferior_h).
|
||||||
|
|
||||||
2008-07-09 Pedro Alves <pedro@codesourcery.com>
|
2008-07-09 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
Add non_stop global.
|
Add non_stop global.
|
||||||
|
@ -800,7 +800,7 @@ gdb_stabs_h = gdb-stabs.h
|
|||||||
gdb_stat_h = gdb_stat.h
|
gdb_stat_h = gdb_stat.h
|
||||||
gdb_string_h = gdb_string.h
|
gdb_string_h = gdb_string.h
|
||||||
gdb_thread_db_h = gdb_thread_db.h
|
gdb_thread_db_h = gdb_thread_db.h
|
||||||
gdbthread_h = gdbthread.h $(breakpoint_h) $(frame_h) $(ui_out_h)
|
gdbthread_h = gdbthread.h $(breakpoint_h) $(frame_h) $(ui_out_h) $(inferior_h)
|
||||||
gdbtypes_h = gdbtypes.h $(hashtab_h)
|
gdbtypes_h = gdbtypes.h $(hashtab_h)
|
||||||
gdb_vfork_h = gdb_vfork.h
|
gdb_vfork_h = gdb_vfork.h
|
||||||
gdb_wait_h = gdb_wait.h
|
gdb_wait_h = gdb_wait.h
|
||||||
|
@ -7168,6 +7168,29 @@ update_global_location_list_nothrow (int inserting)
|
|||||||
update_global_location_list (inserting);
|
update_global_location_list (inserting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear BPT from a BPS. */
|
||||||
|
static void
|
||||||
|
bpstat_remove_breakpoint (bpstat bps, struct breakpoint *bpt)
|
||||||
|
{
|
||||||
|
bpstat bs;
|
||||||
|
for (bs = bps; bs; bs = bs->next)
|
||||||
|
if (bs->breakpoint_at && bs->breakpoint_at->owner == bpt)
|
||||||
|
{
|
||||||
|
bs->breakpoint_at = NULL;
|
||||||
|
bs->old_val = NULL;
|
||||||
|
/* bs->commands will be freed later. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback for iterate_over_threads. */
|
||||||
|
static int
|
||||||
|
bpstat_remove_breakpoint_callback (struct thread_info *th, void *data)
|
||||||
|
{
|
||||||
|
struct breakpoint *bpt = data;
|
||||||
|
bpstat_remove_breakpoint (th->stop_bpstat, bpt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Delete a breakpoint and clean up all traces of it in the data
|
/* Delete a breakpoint and clean up all traces of it in the data
|
||||||
structures. */
|
structures. */
|
||||||
|
|
||||||
@ -7175,7 +7198,6 @@ void
|
|||||||
delete_breakpoint (struct breakpoint *bpt)
|
delete_breakpoint (struct breakpoint *bpt)
|
||||||
{
|
{
|
||||||
struct breakpoint *b;
|
struct breakpoint *b;
|
||||||
bpstat bs;
|
|
||||||
struct bp_location *loc, *next;
|
struct bp_location *loc, *next;
|
||||||
|
|
||||||
gdb_assert (bpt != NULL);
|
gdb_assert (bpt != NULL);
|
||||||
@ -7239,13 +7261,11 @@ delete_breakpoint (struct breakpoint *bpt)
|
|||||||
bpstat_do_actions (&stop_bpstat);
|
bpstat_do_actions (&stop_bpstat);
|
||||||
in event-top.c won't do anything, and temporary breakpoints
|
in event-top.c won't do anything, and temporary breakpoints
|
||||||
with commands won't work. */
|
with commands won't work. */
|
||||||
for (bs = stop_bpstat; bs; bs = bs->next)
|
|
||||||
if (bs->breakpoint_at && bs->breakpoint_at->owner == bpt)
|
/* Clear the current context. */
|
||||||
{
|
bpstat_remove_breakpoint (stop_bpstat, bpt);
|
||||||
bs->breakpoint_at = NULL;
|
/* And from all threads. */
|
||||||
bs->old_val = NULL;
|
iterate_over_threads (bpstat_remove_breakpoint_callback, bpt);
|
||||||
/* bs->commands will be freed later. */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now that breakpoint is removed from breakpoint
|
/* Now that breakpoint is removed from breakpoint
|
||||||
list, update the global location list. This
|
list, update the global location list. This
|
||||||
|
@ -22,17 +22,12 @@
|
|||||||
#ifndef GDBTHREAD_H
|
#ifndef GDBTHREAD_H
|
||||||
#define GDBTHREAD_H
|
#define GDBTHREAD_H
|
||||||
|
|
||||||
struct breakpoint;
|
|
||||||
struct frame_id;
|
|
||||||
struct symtab;
|
struct symtab;
|
||||||
|
|
||||||
/* For bpstat */
|
|
||||||
#include "breakpoint.h"
|
#include "breakpoint.h"
|
||||||
|
|
||||||
/* For struct frame_id. */
|
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
|
|
||||||
#include "ui-out.h"
|
#include "ui-out.h"
|
||||||
|
#include "inferior.h"
|
||||||
|
|
||||||
struct thread_info
|
struct thread_info
|
||||||
{
|
{
|
||||||
@ -82,6 +77,20 @@ struct thread_info
|
|||||||
when we finally do stop stepping. */
|
when we finally do stop stepping. */
|
||||||
bpstat stepping_through_solib_catchpoints;
|
bpstat stepping_through_solib_catchpoints;
|
||||||
|
|
||||||
|
/* The below are only per-thread in non-stop mode. */
|
||||||
|
/* Per-thread command support. */
|
||||||
|
struct continuation *continuations;
|
||||||
|
struct continuation *intermediate_continuations;
|
||||||
|
int proceed_to_finish;
|
||||||
|
enum step_over_calls_kind step_over_calls;
|
||||||
|
int stop_step;
|
||||||
|
int step_multi;
|
||||||
|
|
||||||
|
enum target_signal stop_signal;
|
||||||
|
/* Used in continue_command to set the proceed count of the
|
||||||
|
breakpoint the thread stopped at. */
|
||||||
|
bpstat stop_bpstat;
|
||||||
|
|
||||||
/* Private data used by the target vector implementation. */
|
/* Private data used by the target vector implementation. */
|
||||||
struct private_thread_info *private;
|
struct private_thread_info *private;
|
||||||
};
|
};
|
||||||
@ -152,7 +161,15 @@ extern void save_infrun_state (ptid_t ptid,
|
|||||||
int stepping_through_solib_after_catch,
|
int stepping_through_solib_after_catch,
|
||||||
bpstat stepping_through_solib_catchpoints,
|
bpstat stepping_through_solib_catchpoints,
|
||||||
int current_line,
|
int current_line,
|
||||||
struct symtab *current_symtab);
|
struct symtab *current_symtab,
|
||||||
|
struct continuation *continuations,
|
||||||
|
struct continuation *intermediate_continuations,
|
||||||
|
int proceed_to_finish,
|
||||||
|
enum step_over_calls_kind step_over_calls,
|
||||||
|
int stop_step,
|
||||||
|
int step_multi,
|
||||||
|
enum target_signal stop_signal,
|
||||||
|
bpstat stop_bpstat);
|
||||||
|
|
||||||
/* 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. */
|
||||||
@ -164,10 +181,18 @@ extern void load_infrun_state (ptid_t ptid,
|
|||||||
CORE_ADDR *step_range_end,
|
CORE_ADDR *step_range_end,
|
||||||
struct frame_id *step_frame_id,
|
struct frame_id *step_frame_id,
|
||||||
int *another_trap,
|
int *another_trap,
|
||||||
int *stepping_through_solib_affter_catch,
|
int *stepping_through_solib_after_catch,
|
||||||
bpstat *stepping_through_solib_catchpoints,
|
bpstat *stepping_through_solib_catchpoints,
|
||||||
int *current_line,
|
int *current_line,
|
||||||
struct symtab **current_symtab);
|
struct symtab **current_symtab,
|
||||||
|
struct continuation **continuations,
|
||||||
|
struct continuation **intermediate_continuations,
|
||||||
|
int *proceed_to_finish,
|
||||||
|
enum step_over_calls_kind *step_over_calls,
|
||||||
|
int *stop_step,
|
||||||
|
int *step_multi,
|
||||||
|
enum target_signal *stop_signal,
|
||||||
|
bpstat *stop_bpstat);
|
||||||
|
|
||||||
/* 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);
|
||||||
|
@ -132,6 +132,8 @@ extern void clear_proceed_status (void);
|
|||||||
|
|
||||||
extern void proceed (CORE_ADDR, enum target_signal, int);
|
extern void proceed (CORE_ADDR, enum target_signal, int);
|
||||||
|
|
||||||
|
extern ptid_t context_switch_to (ptid_t ptid);
|
||||||
|
|
||||||
/* When set, stop the 'step' command if we enter a function which has
|
/* When set, stop the 'step' command if we enter a function which has
|
||||||
no line number information. The normal behavior is that we step
|
no line number information. The normal behavior is that we step
|
||||||
over such function. */
|
over such function. */
|
||||||
|
67
gdb/infrun.c
67
gdb/infrun.c
@ -288,6 +288,8 @@ static struct breakpoint *step_resume_breakpoint = NULL;
|
|||||||
static ptid_t target_last_wait_ptid;
|
static ptid_t target_last_wait_ptid;
|
||||||
static struct target_waitstatus target_last_waitstatus;
|
static struct target_waitstatus target_last_waitstatus;
|
||||||
|
|
||||||
|
struct execution_control_state ecss;
|
||||||
|
|
||||||
/* This is used to remember when a fork, vfork or exec event
|
/* This is used to remember when a fork, vfork or exec event
|
||||||
was caught by a catchpoint, and thus the event is to be
|
was caught by a catchpoint, and thus the event is to be
|
||||||
followed at the next resume of the inferior, and not
|
followed at the next resume of the inferior, and not
|
||||||
@ -1429,7 +1431,6 @@ void
|
|||||||
wait_for_inferior (int treat_exec_as_sigtrap)
|
wait_for_inferior (int treat_exec_as_sigtrap)
|
||||||
{
|
{
|
||||||
struct cleanup *old_cleanups;
|
struct cleanup *old_cleanups;
|
||||||
struct execution_control_state ecss;
|
|
||||||
struct execution_control_state *ecs;
|
struct execution_control_state *ecs;
|
||||||
|
|
||||||
if (debug_infrun)
|
if (debug_infrun)
|
||||||
@ -1440,8 +1441,6 @@ wait_for_inferior (int treat_exec_as_sigtrap)
|
|||||||
old_cleanups = make_cleanup (delete_step_resume_breakpoint,
|
old_cleanups = make_cleanup (delete_step_resume_breakpoint,
|
||||||
&step_resume_breakpoint);
|
&step_resume_breakpoint);
|
||||||
|
|
||||||
/* wfi still stays in a loop, so it's OK just to take the address of
|
|
||||||
a local to get the ecs pointer. */
|
|
||||||
ecs = &ecss;
|
ecs = &ecss;
|
||||||
|
|
||||||
/* Fill in with reasonable starting values. */
|
/* Fill in with reasonable starting values. */
|
||||||
@ -1487,25 +1486,20 @@ wait_for_inferior (int treat_exec_as_sigtrap)
|
|||||||
event loop whenever a change of state is detected on the file
|
event loop whenever a change of state is detected on the file
|
||||||
descriptor corresponding to the target. It can be called more than
|
descriptor corresponding to the target. It can be called more than
|
||||||
once to complete a single execution command. In such cases we need
|
once to complete a single execution command. In such cases we need
|
||||||
to keep the state in a global variable ASYNC_ECSS. If it is the
|
to keep the state in a global variable ECSS. If it is the last time
|
||||||
last time that this function is called for a single execution
|
that this function is called for a single execution command, then
|
||||||
command, then report to the user that the inferior has stopped, and
|
report to the user that the inferior has stopped, and do the
|
||||||
do the necessary cleanups. */
|
necessary cleanups. */
|
||||||
|
|
||||||
struct execution_control_state async_ecss;
|
|
||||||
struct execution_control_state *async_ecs;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
fetch_inferior_event (void *client_data)
|
fetch_inferior_event (void *client_data)
|
||||||
{
|
{
|
||||||
static struct cleanup *old_cleanups;
|
struct execution_control_state *ecs = &ecss;
|
||||||
|
|
||||||
async_ecs = &async_ecss;
|
if (!ecs->wait_some_more)
|
||||||
|
|
||||||
if (!async_ecs->wait_some_more)
|
|
||||||
{
|
{
|
||||||
/* Fill in with reasonable starting values. */
|
/* Fill in with reasonable starting values. */
|
||||||
init_execution_control_state (async_ecs);
|
init_execution_control_state (ecs);
|
||||||
|
|
||||||
/* We'll update this if & when we switch to a new thread. */
|
/* We'll update this if & when we switch to a new thread. */
|
||||||
previous_inferior_ptid = inferior_ptid;
|
previous_inferior_ptid = inferior_ptid;
|
||||||
@ -1522,15 +1516,15 @@ fetch_inferior_event (void *client_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (deprecated_target_wait_hook)
|
if (deprecated_target_wait_hook)
|
||||||
async_ecs->ptid =
|
ecs->ptid =
|
||||||
deprecated_target_wait_hook (async_ecs->waiton_ptid, async_ecs->wp);
|
deprecated_target_wait_hook (ecs->waiton_ptid, ecs->wp);
|
||||||
else
|
else
|
||||||
async_ecs->ptid = target_wait (async_ecs->waiton_ptid, async_ecs->wp);
|
ecs->ptid = target_wait (ecs->waiton_ptid, ecs->wp);
|
||||||
|
|
||||||
/* Now figure out what to do with the result of the result. */
|
/* Now figure out what to do with the result of the result. */
|
||||||
handle_inferior_event (async_ecs);
|
handle_inferior_event (ecs);
|
||||||
|
|
||||||
if (!async_ecs->wait_some_more)
|
if (!ecs->wait_some_more)
|
||||||
{
|
{
|
||||||
delete_step_resume_breakpoint (&step_resume_breakpoint);
|
delete_step_resume_breakpoint (&step_resume_breakpoint);
|
||||||
|
|
||||||
@ -1608,7 +1602,14 @@ context_switch (struct execution_control_state *ecs)
|
|||||||
ecs->stepping_over_breakpoint,
|
ecs->stepping_over_breakpoint,
|
||||||
ecs->stepping_through_solib_after_catch,
|
ecs->stepping_through_solib_after_catch,
|
||||||
ecs->stepping_through_solib_catchpoints,
|
ecs->stepping_through_solib_catchpoints,
|
||||||
ecs->current_line, ecs->current_symtab);
|
ecs->current_line, ecs->current_symtab,
|
||||||
|
cmd_continuation, intermediate_continuation,
|
||||||
|
proceed_to_finish,
|
||||||
|
step_over_calls,
|
||||||
|
stop_step,
|
||||||
|
step_multi,
|
||||||
|
stop_signal,
|
||||||
|
stop_bpstat);
|
||||||
|
|
||||||
/* Load infrun state for the new thread. */
|
/* Load infrun state for the new thread. */
|
||||||
load_infrun_state (ecs->ptid, &prev_pc,
|
load_infrun_state (ecs->ptid, &prev_pc,
|
||||||
@ -1618,12 +1619,34 @@ context_switch (struct execution_control_state *ecs)
|
|||||||
&ecs->stepping_over_breakpoint,
|
&ecs->stepping_over_breakpoint,
|
||||||
&ecs->stepping_through_solib_after_catch,
|
&ecs->stepping_through_solib_after_catch,
|
||||||
&ecs->stepping_through_solib_catchpoints,
|
&ecs->stepping_through_solib_catchpoints,
|
||||||
&ecs->current_line, &ecs->current_symtab);
|
&ecs->current_line, &ecs->current_symtab,
|
||||||
|
&cmd_continuation, &intermediate_continuation,
|
||||||
|
&proceed_to_finish,
|
||||||
|
&step_over_calls,
|
||||||
|
&stop_step,
|
||||||
|
&step_multi,
|
||||||
|
&stop_signal,
|
||||||
|
&stop_bpstat);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_to_thread (ecs->ptid);
|
switch_to_thread (ecs->ptid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Context switch to thread PTID. */
|
||||||
|
ptid_t
|
||||||
|
context_switch_to (ptid_t ptid)
|
||||||
|
{
|
||||||
|
ptid_t current_ptid = inferior_ptid;
|
||||||
|
|
||||||
|
/* Context switch to the new thread. */
|
||||||
|
if (!ptid_equal (ptid, inferior_ptid))
|
||||||
|
{
|
||||||
|
ecss.ptid = ptid;
|
||||||
|
context_switch (&ecss);
|
||||||
|
}
|
||||||
|
return current_ptid;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
adjust_pc_after_break (struct execution_control_state *ecs)
|
adjust_pc_after_break (struct execution_control_state *ecs)
|
||||||
{
|
{
|
||||||
|
@ -1059,7 +1059,8 @@ mi_cmd_execute (struct mi_parse *parse)
|
|||||||
|
|
||||||
if (parse->cmd->argv_func != NULL)
|
if (parse->cmd->argv_func != NULL)
|
||||||
{
|
{
|
||||||
if (is_running (inferior_ptid))
|
if ((!non_stop && any_running ())
|
||||||
|
|| (non_stop && is_running (inferior_ptid)))
|
||||||
{
|
{
|
||||||
if (strcmp (parse->command, "exec-interrupt"))
|
if (strcmp (parse->command, "exec-interrupt"))
|
||||||
{
|
{
|
||||||
|
56
gdb/thread.c
56
gdb/thread.c
@ -93,6 +93,8 @@ free_thread (struct thread_info *tp)
|
|||||||
if (tp->step_resume_breakpoint)
|
if (tp->step_resume_breakpoint)
|
||||||
tp->step_resume_breakpoint->disposition = disp_del_at_next_stop;
|
tp->step_resume_breakpoint->disposition = disp_del_at_next_stop;
|
||||||
|
|
||||||
|
bpstat_clear (&tp->stop_bpstat);
|
||||||
|
|
||||||
/* FIXME: do I ever need to call the back-end to give it a
|
/* FIXME: do I ever need to call the back-end to give it a
|
||||||
chance at this private data before deleting the thread? */
|
chance at this private data before deleting the thread? */
|
||||||
if (tp->private)
|
if (tp->private)
|
||||||
@ -358,7 +360,15 @@ load_infrun_state (ptid_t ptid,
|
|||||||
int *stepping_through_solib_after_catch,
|
int *stepping_through_solib_after_catch,
|
||||||
bpstat *stepping_through_solib_catchpoints,
|
bpstat *stepping_through_solib_catchpoints,
|
||||||
int *current_line,
|
int *current_line,
|
||||||
struct symtab **current_symtab)
|
struct symtab **current_symtab,
|
||||||
|
struct continuation **continuations,
|
||||||
|
struct continuation **intermediate_continuations,
|
||||||
|
int *proceed_to_finish,
|
||||||
|
enum step_over_calls_kind *step_over_calls,
|
||||||
|
int *stop_step,
|
||||||
|
int *step_multi,
|
||||||
|
enum target_signal *stop_signal,
|
||||||
|
bpstat *stop_bpstat)
|
||||||
{
|
{
|
||||||
struct thread_info *tp;
|
struct thread_info *tp;
|
||||||
|
|
||||||
@ -381,6 +391,26 @@ load_infrun_state (ptid_t ptid,
|
|||||||
tp->stepping_through_solib_catchpoints;
|
tp->stepping_through_solib_catchpoints;
|
||||||
*current_line = tp->current_line;
|
*current_line = tp->current_line;
|
||||||
*current_symtab = tp->current_symtab;
|
*current_symtab = tp->current_symtab;
|
||||||
|
|
||||||
|
/* In all-stop mode, these are global state, while in non-stop mode,
|
||||||
|
they are per thread. */
|
||||||
|
if (non_stop)
|
||||||
|
{
|
||||||
|
*continuations = tp->continuations;
|
||||||
|
tp->continuations = NULL;
|
||||||
|
*intermediate_continuations = tp->intermediate_continuations;
|
||||||
|
tp->intermediate_continuations = NULL;
|
||||||
|
*proceed_to_finish = tp->proceed_to_finish;
|
||||||
|
*step_over_calls = tp->step_over_calls;
|
||||||
|
*stop_step = tp->stop_step;
|
||||||
|
*step_multi = tp->step_multi;
|
||||||
|
*stop_signal = tp->stop_signal;
|
||||||
|
|
||||||
|
/* Swap instead of copy, so we only have to update one of
|
||||||
|
them. */
|
||||||
|
*stop_bpstat = tp->stop_bpstat;
|
||||||
|
tp->stop_bpstat = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save infrun state for the thread PID. */
|
/* Save infrun state for the thread PID. */
|
||||||
@ -397,7 +427,15 @@ save_infrun_state (ptid_t ptid,
|
|||||||
int stepping_through_solib_after_catch,
|
int stepping_through_solib_after_catch,
|
||||||
bpstat stepping_through_solib_catchpoints,
|
bpstat stepping_through_solib_catchpoints,
|
||||||
int current_line,
|
int current_line,
|
||||||
struct symtab *current_symtab)
|
struct symtab *current_symtab,
|
||||||
|
struct continuation *continuations,
|
||||||
|
struct continuation *intermediate_continuations,
|
||||||
|
int proceed_to_finish,
|
||||||
|
enum step_over_calls_kind step_over_calls,
|
||||||
|
int stop_step,
|
||||||
|
int step_multi,
|
||||||
|
enum target_signal stop_signal,
|
||||||
|
bpstat stop_bpstat)
|
||||||
{
|
{
|
||||||
struct thread_info *tp;
|
struct thread_info *tp;
|
||||||
|
|
||||||
@ -418,6 +456,20 @@ save_infrun_state (ptid_t ptid,
|
|||||||
tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
|
tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
|
||||||
tp->current_line = current_line;
|
tp->current_line = current_line;
|
||||||
tp->current_symtab = current_symtab;
|
tp->current_symtab = current_symtab;
|
||||||
|
|
||||||
|
/* In all-stop mode, these are global state, while in non-stop mode,
|
||||||
|
they are per thread. */
|
||||||
|
if (non_stop)
|
||||||
|
{
|
||||||
|
tp->continuations = continuations;
|
||||||
|
tp->intermediate_continuations = intermediate_continuations;
|
||||||
|
tp->proceed_to_finish = proceed_to_finish;
|
||||||
|
tp->step_over_calls = step_over_calls;
|
||||||
|
tp->stop_step = stop_step;
|
||||||
|
tp->step_multi = step_multi;
|
||||||
|
tp->stop_signal = stop_signal;
|
||||||
|
tp->stop_bpstat = stop_bpstat;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if TP is an active thread. */
|
/* Return true if TP is an active thread. */
|
||||||
|
@ -418,7 +418,8 @@ execute_command (char *p, int from_tty)
|
|||||||
/* If the target is running, we allow only a limited set of
|
/* If the target is running, we allow only a limited set of
|
||||||
commands. */
|
commands. */
|
||||||
if (target_can_async_p ()
|
if (target_can_async_p ()
|
||||||
&& any_running ()
|
&& ((!non_stop && any_running ())
|
||||||
|
|| (non_stop && is_running (inferior_ptid)))
|
||||||
&& !get_cmd_async_ok (c))
|
&& !get_cmd_async_ok (c))
|
||||||
error (_("Cannot execute this command while the target is running."));
|
error (_("Cannot execute this command while the target is running."));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user