Add "executing" property to threads.
* inferior.h (target_executing): Delete. * gdbthread.h (struct thread_info): Add executing_ field. (set_executing, is_executing): New. * thread.c (main_thread_executing): New. (init_thread_list): Clear it and also main_thread_running. (is_running): Return false if target has no execution. (any_running, is_executing, set_executing): New. * top.c: Include "gdbthread.h". (target_executing): Delete. (execute_command): Replace target_executing check by any_running. * event-top.c: Include "gdbthread.h". (display_gdb_prompt, command_handler): Replace target_executing by is_running. * inf-loop.c: Include "gdbthread.h". Don't mark as not executing here. Replace target_executing by is_running. * infrun.c (handle_inferior_event): Mark all threads as not-executing. * linux-nat.c (linux_nat_resume): Don't mark thread as executing here. * stack.c (get_selected_block): Return null if inferior is executing. * target.c (target_resume): Mark resumed ptid as executing. * breakpoint.c (until_break_command): Replace target_executing check by is_executing. * remote.c (remote_async_resume): Don't mark inferior as executing here. * mi/mi-interp.c (mi_cmd_interpreter_exec): Replace target_executing by any_running. * mi/mi-main.c (mi_cmd_exec_interrupt, mi_cmd_execute) (mi_execute_async_cli_command): Replace target_executing by is_running. * frame.c (get_current_frame): Error out if the current thread is executing. (has_stack_frames): New. (get_selected_frame, deprecated_safe_get_selected_frame): Check has_stack_frames. * Makefile.in (event-top.o, frame.o, inf-loop.o, top.o): Depend on $(gdbthread_h).
This commit is contained in:
parent
4487aabf2e
commit
8ea051c51f
@ -1,3 +1,50 @@
|
|||||||
|
2008-07-09 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
|
Add "executing" property to threads.
|
||||||
|
|
||||||
|
* inferior.h (target_executing): Delete.
|
||||||
|
* gdbthread.h (struct thread_info): Add executing_ field.
|
||||||
|
(set_executing, is_executing): New.
|
||||||
|
* thread.c (main_thread_executing): New.
|
||||||
|
(init_thread_list): Clear it and also main_thread_running.
|
||||||
|
(is_running): Return false if target has no execution.
|
||||||
|
(any_running, is_executing, set_executing): New.
|
||||||
|
|
||||||
|
* top.c: Include "gdbthread.h".
|
||||||
|
(target_executing): Delete.
|
||||||
|
(execute_command): Replace target_executing check by any_running.
|
||||||
|
* event-top.c: Include "gdbthread.h".
|
||||||
|
(display_gdb_prompt, command_handler): Replace target_executing by
|
||||||
|
is_running.
|
||||||
|
* inf-loop.c: Include "gdbthread.h". Don't mark as not executing
|
||||||
|
here. Replace target_executing by is_running.
|
||||||
|
* infrun.c (handle_inferior_event): Mark all threads as
|
||||||
|
not-executing.
|
||||||
|
* linux-nat.c (linux_nat_resume): Don't mark thread as executing
|
||||||
|
here.
|
||||||
|
* stack.c (get_selected_block): Return null if inferior is
|
||||||
|
executing.
|
||||||
|
* target.c (target_resume): Mark resumed ptid as executing.
|
||||||
|
* breakpoint.c (until_break_command): Replace target_executing
|
||||||
|
check by is_executing.
|
||||||
|
* remote.c (remote_async_resume): Don't mark inferior as executing
|
||||||
|
here.
|
||||||
|
* mi/mi-interp.c (mi_cmd_interpreter_exec): Replace target_executing
|
||||||
|
by any_running.
|
||||||
|
|
||||||
|
* mi/mi-main.c (mi_cmd_exec_interrupt, mi_cmd_execute)
|
||||||
|
(mi_execute_async_cli_command): Replace target_executing by
|
||||||
|
is_running.
|
||||||
|
|
||||||
|
* frame.c (get_current_frame): Error out if the current thread is
|
||||||
|
executing.
|
||||||
|
(has_stack_frames): New.
|
||||||
|
(get_selected_frame, deprecated_safe_get_selected_frame): Check
|
||||||
|
has_stack_frames.
|
||||||
|
|
||||||
|
* Makefile.in (event-top.o, frame.o, inf-loop.o, top.o): Depend on
|
||||||
|
$(gdbthread_h).
|
||||||
|
|
||||||
2008-07-09 Pedro Alves <pedro@codesourcery.com>
|
2008-07-09 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
* symfile.c (load_command): Reopen the exec file and reread
|
* symfile.c (load_command): Reopen the exec file and reread
|
||||||
|
@ -2106,7 +2106,7 @@ event-loop.o: event-loop.c $(defs_h) $(event_loop_h) $(event_top_h) \
|
|||||||
event-top.o: event-top.c $(defs_h) $(top_h) $(inferior_h) $(target_h) \
|
event-top.o: event-top.c $(defs_h) $(top_h) $(inferior_h) $(target_h) \
|
||||||
$(terminal_h) $(event_loop_h) $(event_top_h) $(interps_h) \
|
$(terminal_h) $(event_loop_h) $(event_top_h) $(interps_h) \
|
||||||
$(exceptions_h) $(cli_script_h) $(gdbcmd_h) $(readline_h) \
|
$(exceptions_h) $(cli_script_h) $(gdbcmd_h) $(readline_h) \
|
||||||
$(readline_history_h) $(main_h)
|
$(readline_history_h) $(main_h) $(gdbthread_h)
|
||||||
exceptions.o: exceptions.c $(defs_h) $(exceptions_h) $(breakpoint_h) \
|
exceptions.o: exceptions.c $(defs_h) $(exceptions_h) $(breakpoint_h) \
|
||||||
$(target_h) $(inferior_h) $(annotate_h) $(ui_out_h) $(gdb_assert_h) \
|
$(target_h) $(inferior_h) $(annotate_h) $(ui_out_h) $(gdb_assert_h) \
|
||||||
$(gdb_string_h) $(serial_h)
|
$(gdb_string_h) $(serial_h)
|
||||||
@ -2141,7 +2141,8 @@ frame.o: frame.c $(defs_h) $(frame_h) $(target_h) $(value_h) $(inferior_h) \
|
|||||||
$(regcache_h) $(gdb_assert_h) $(gdb_string_h) $(user_regs_h) \
|
$(regcache_h) $(gdb_assert_h) $(gdb_string_h) $(user_regs_h) \
|
||||||
$(gdb_obstack_h) $(dummy_frame_h) $(sentinel_frame_h) $(gdbcore_h) \
|
$(gdb_obstack_h) $(dummy_frame_h) $(sentinel_frame_h) $(gdbcore_h) \
|
||||||
$(annotate_h) $(language_h) $(frame_unwind_h) $(frame_base_h) \
|
$(annotate_h) $(language_h) $(frame_unwind_h) $(frame_base_h) \
|
||||||
$(command_h) $(gdbcmd_h) $(observer_h) $(objfiles_h) $(exceptions_h)
|
$(command_h) $(gdbcmd_h) $(observer_h) $(objfiles_h) $(exceptions_h) \
|
||||||
|
$(gdbthread_h)
|
||||||
frame-unwind.o: frame-unwind.c $(defs_h) $(frame_h) $(frame_unwind_h) \
|
frame-unwind.o: frame-unwind.c $(defs_h) $(frame_h) $(frame_unwind_h) \
|
||||||
$(gdb_assert_h) $(dummy_frame_h) $(gdb_obstack_h) $(value_h) \
|
$(gdb_assert_h) $(dummy_frame_h) $(gdb_obstack_h) $(value_h) \
|
||||||
$(regcache_h)
|
$(regcache_h)
|
||||||
@ -2322,7 +2323,7 @@ infcmd.o: infcmd.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
|
|||||||
$(user_regs_h) $(exceptions_h) $(cli_decode_h) $(gdbthread_h)
|
$(user_regs_h) $(exceptions_h) $(cli_decode_h) $(gdbthread_h)
|
||||||
inf-loop.o: inf-loop.c $(defs_h) $(inferior_h) $(target_h) $(event_loop_h) \
|
inf-loop.o: inf-loop.c $(defs_h) $(inferior_h) $(target_h) $(event_loop_h) \
|
||||||
$(event_top_h) $(inf_loop_h) $(remote_h) $(exceptions_h) \
|
$(event_top_h) $(inf_loop_h) $(remote_h) $(exceptions_h) \
|
||||||
$(language_h)
|
$(language_h) $(gdbthread_h)
|
||||||
inflow.o: inflow.c $(defs_h) $(frame_h) $(inferior_h) $(command_h) \
|
inflow.o: inflow.c $(defs_h) $(frame_h) $(inferior_h) $(command_h) \
|
||||||
$(serial_h) $(terminal_h) $(target_h) $(gdbthread_h) $(gdb_string_h) \
|
$(serial_h) $(terminal_h) $(target_h) $(gdbthread_h) $(gdb_string_h) \
|
||||||
$(inflow_h) $(gdb_select_h)
|
$(inflow_h) $(gdb_select_h)
|
||||||
@ -2928,7 +2929,7 @@ top.o: top.c $(defs_h) $(gdbcmd_h) $(call_cmds_h) $(cli_cmds_h) \
|
|||||||
$(annotate_h) $(completer_h) $(top_h) $(version_h) $(serial_h) \
|
$(annotate_h) $(completer_h) $(top_h) $(version_h) $(serial_h) \
|
||||||
$(doublest_h) $(gdb_assert_h) $(readline_h) $(readline_history_h) \
|
$(doublest_h) $(gdb_assert_h) $(readline_h) $(readline_history_h) \
|
||||||
$(event_top_h) $(gdb_string_h) $(gdb_stat_h) $(ui_out_h) \
|
$(event_top_h) $(gdb_string_h) $(gdb_stat_h) $(ui_out_h) \
|
||||||
$(cli_out_h) $(main_h) $(event_loop_h)
|
$(cli_out_h) $(main_h) $(event_loop_h) $(gdbthread_h)
|
||||||
tracepoint.o: tracepoint.c $(defs_h) $(symtab_h) $(frame_h) $(gdbtypes_h) \
|
tracepoint.o: tracepoint.c $(defs_h) $(symtab_h) $(frame_h) $(gdbtypes_h) \
|
||||||
$(expression_h) $(gdbcmd_h) $(value_h) $(target_h) $(language_h) \
|
$(expression_h) $(gdbcmd_h) $(value_h) $(target_h) $(language_h) \
|
||||||
$(gdb_string_h) $(inferior_h) $(tracepoint_h) $(remote_h) \
|
$(gdb_string_h) $(inferior_h) $(tracepoint_h) $(remote_h) \
|
||||||
|
@ -6229,7 +6229,7 @@ until_break_command (char *arg, int from_tty, int anywhere)
|
|||||||
deleted when the target stops. Otherwise, we're already stopped and
|
deleted when the target stops. Otherwise, we're already stopped and
|
||||||
delete breakpoints via cleanup chain. */
|
delete breakpoints via cleanup chain. */
|
||||||
|
|
||||||
if (target_can_async_p () && target_executing)
|
if (target_can_async_p () && is_running (inferior_ptid))
|
||||||
{
|
{
|
||||||
arg1 =
|
arg1 =
|
||||||
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
|
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "cli/cli-script.h" /* for reset_command_nest_depth */
|
#include "cli/cli-script.h" /* for reset_command_nest_depth */
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "gdbthread.h"
|
||||||
|
|
||||||
/* For dont_repeat() */
|
/* For dont_repeat() */
|
||||||
#include "gdbcmd.h"
|
#include "gdbcmd.h"
|
||||||
@ -268,7 +269,7 @@ display_gdb_prompt (char *new_prompt)
|
|||||||
if (!current_interp_display_prompt_p ())
|
if (!current_interp_display_prompt_p ())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (target_executing && sync_execution)
|
if (sync_execution && is_running (inferior_ptid))
|
||||||
{
|
{
|
||||||
/* This is to trick readline into not trying to display the
|
/* This is to trick readline into not trying to display the
|
||||||
prompt. Even though we display the prompt using this
|
prompt. Even though we display the prompt using this
|
||||||
@ -516,7 +517,7 @@ command_handler (char *command)
|
|||||||
/* Do any commands attached to breakpoint we stopped at. Only if we
|
/* Do any commands attached to breakpoint we stopped at. Only if we
|
||||||
are always running synchronously. Or if we have just executed a
|
are always running synchronously. Or if we have just executed a
|
||||||
command that doesn't start the target. */
|
command that doesn't start the target. */
|
||||||
if (!target_can_async_p () || !target_executing)
|
if (!target_can_async_p () || !is_running (inferior_ptid))
|
||||||
{
|
{
|
||||||
bpstat_do_actions (&stop_bpstat);
|
bpstat_do_actions (&stop_bpstat);
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
|
24
gdb/frame.c
24
gdb/frame.c
@ -40,6 +40,7 @@
|
|||||||
#include "observer.h"
|
#include "observer.h"
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
|
#include "gdbthread.h"
|
||||||
|
|
||||||
static struct frame_info *get_prev_frame_1 (struct frame_info *this_frame);
|
static struct frame_info *get_prev_frame_1 (struct frame_info *this_frame);
|
||||||
|
|
||||||
@ -930,6 +931,9 @@ get_current_frame (void)
|
|||||||
error (_("No stack."));
|
error (_("No stack."));
|
||||||
if (!target_has_memory)
|
if (!target_has_memory)
|
||||||
error (_("No memory."));
|
error (_("No memory."));
|
||||||
|
if (is_executing (inferior_ptid))
|
||||||
|
error (_("Target is executing."));
|
||||||
|
|
||||||
if (current_frame == NULL)
|
if (current_frame == NULL)
|
||||||
{
|
{
|
||||||
struct frame_info *sentinel_frame =
|
struct frame_info *sentinel_frame =
|
||||||
@ -950,6 +954,20 @@ get_current_frame (void)
|
|||||||
|
|
||||||
static struct frame_info *selected_frame;
|
static struct frame_info *selected_frame;
|
||||||
|
|
||||||
|
static int
|
||||||
|
has_stack_frames (void)
|
||||||
|
{
|
||||||
|
if (!target_has_registers || !target_has_stack || !target_has_memory)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* If the current thread is executing, don't try to read from
|
||||||
|
it. */
|
||||||
|
if (is_executing (inferior_ptid))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the selected frame. Always non-NULL (unless there isn't an
|
/* Return the selected frame. Always non-NULL (unless there isn't an
|
||||||
inferior sufficient for creating a frame) in which case an error is
|
inferior sufficient for creating a frame) in which case an error is
|
||||||
thrown. */
|
thrown. */
|
||||||
@ -959,9 +977,7 @@ get_selected_frame (const char *message)
|
|||||||
{
|
{
|
||||||
if (selected_frame == NULL)
|
if (selected_frame == NULL)
|
||||||
{
|
{
|
||||||
if (message != NULL && (!target_has_registers
|
if (message != NULL && !has_stack_frames ())
|
||||||
|| !target_has_stack
|
|
||||||
|| !target_has_memory))
|
|
||||||
error (("%s"), message);
|
error (("%s"), message);
|
||||||
/* Hey! Don't trust this. It should really be re-finding the
|
/* Hey! Don't trust this. It should really be re-finding the
|
||||||
last selected frame of the currently selected thread. This,
|
last selected frame of the currently selected thread. This,
|
||||||
@ -980,7 +996,7 @@ get_selected_frame (const char *message)
|
|||||||
struct frame_info *
|
struct frame_info *
|
||||||
deprecated_safe_get_selected_frame (void)
|
deprecated_safe_get_selected_frame (void)
|
||||||
{
|
{
|
||||||
if (!target_has_registers || !target_has_stack || !target_has_memory)
|
if (!has_stack_frames ())
|
||||||
return NULL;
|
return NULL;
|
||||||
return get_selected_frame (NULL);
|
return get_selected_frame (NULL);
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,25 @@ struct thread_info
|
|||||||
In fact, this may be overloaded with
|
In fact, this may be overloaded with
|
||||||
kernel thread id, etc. */
|
kernel thread id, etc. */
|
||||||
int num; /* Convenient handle (GDB thread id) */
|
int num; /* Convenient handle (GDB thread id) */
|
||||||
|
|
||||||
|
/* Non-zero means the thread is executing. Note: this is different
|
||||||
|
from saying that there is an active target and we are stopped at
|
||||||
|
a breakpoint, for instance. This is a real indicator whether the
|
||||||
|
thread is off and running. */
|
||||||
|
/* This field is internal to thread.c. Never access it directly,
|
||||||
|
use is_executing instead. */
|
||||||
|
int executing_;
|
||||||
|
|
||||||
|
/* Frontend view of the running state. Note that this is different
|
||||||
|
from EXECUTING. When the thread is stopped internally while
|
||||||
|
handling an internal event, like a software single-step
|
||||||
|
breakpoint, executing will be false, but running will still be
|
||||||
|
true. As a possible future extension, this could turn into
|
||||||
|
enum { stopped, stepping, finishing, until(ling), ... } */
|
||||||
|
/* This field is internal to thread.c. Never access it directly,
|
||||||
|
use is_running instead. */
|
||||||
|
int running_;
|
||||||
|
|
||||||
/* State from wait_for_inferior */
|
/* State from wait_for_inferior */
|
||||||
CORE_ADDR prev_pc;
|
CORE_ADDR prev_pc;
|
||||||
struct breakpoint *step_resume_breakpoint;
|
struct breakpoint *step_resume_breakpoint;
|
||||||
@ -63,10 +82,6 @@ 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;
|
||||||
|
|
||||||
/* This field is internal for thread.c. Never access it directly,
|
|
||||||
use is_running instead. */
|
|
||||||
int running_;
|
|
||||||
|
|
||||||
/* 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;
|
||||||
};
|
};
|
||||||
@ -161,9 +176,19 @@ extern void switch_to_thread (ptid_t ptid);
|
|||||||
If PIDGET (PTID) is -1, marks all threads. */
|
If PIDGET (PTID) is -1, marks all threads. */
|
||||||
extern void set_running (ptid_t ptid, int running);
|
extern void set_running (ptid_t ptid, int running);
|
||||||
|
|
||||||
/* Reports if thread PTID is know to be running right now. */
|
/* Reports if thread PTID is known to be running right now. */
|
||||||
extern int is_running (ptid_t ptid);
|
extern int is_running (ptid_t ptid);
|
||||||
|
|
||||||
|
/* Reports if any thread is known to be running right now. */
|
||||||
|
extern int any_running (void);
|
||||||
|
|
||||||
|
/* Marks thread PTID as executing, or as stopped.
|
||||||
|
If PIDGET (PTID) is -1, marks all threads. */
|
||||||
|
extern void set_executing (ptid_t ptid, int executing);
|
||||||
|
|
||||||
|
/* Reports if thread PTID is executing. */
|
||||||
|
extern int is_executing (ptid_t ptid);
|
||||||
|
|
||||||
/* Commands with a prefix of `thread'. */
|
/* Commands with a prefix of `thread'. */
|
||||||
extern struct cmd_list_element *thread_cmd_list;
|
extern struct cmd_list_element *thread_cmd_list;
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "language.h"
|
#include "language.h"
|
||||||
|
#include "gdbthread.h"
|
||||||
|
|
||||||
static int fetch_inferior_event_wrapper (gdb_client_data client_data);
|
static int fetch_inferior_event_wrapper (gdb_client_data client_data);
|
||||||
|
|
||||||
@ -72,14 +73,6 @@ inferior_event_handler (enum inferior_event_type event_type,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case INF_EXEC_COMPLETE:
|
case INF_EXEC_COMPLETE:
|
||||||
|
|
||||||
/* This is the first thing to do -- so that continuations know that
|
|
||||||
the target is stopped. For example, command_line_handler_continuation
|
|
||||||
will run breakpoint commands, and if we think that the target is
|
|
||||||
running, we'll refuse to execute most commands. MI continuation
|
|
||||||
presently uses target_executing to either print or not print *stopped. */
|
|
||||||
target_executing = 0;
|
|
||||||
|
|
||||||
/* Unregister the inferior from the event loop. This is done so that
|
/* Unregister the inferior from the event loop. This is done so that
|
||||||
when the inferior is not running we don't get distracted by
|
when the inferior is not running we don't get distracted by
|
||||||
spurious inferior output. */
|
spurious inferior output. */
|
||||||
@ -121,8 +114,8 @@ inferior_event_handler (enum inferior_event_type event_type,
|
|||||||
|
|
||||||
/* If no breakpoint command resumed the inferior, prepare for
|
/* If no breakpoint command resumed the inferior, prepare for
|
||||||
interaction with the user. */
|
interaction with the user. */
|
||||||
if (!target_executing)
|
if (!is_running (inferior_ptid))
|
||||||
{
|
{
|
||||||
if (was_sync)
|
if (was_sync)
|
||||||
{
|
{
|
||||||
display_gdb_prompt (0);
|
display_gdb_prompt (0);
|
||||||
|
@ -111,12 +111,6 @@ extern const char *get_inferior_io_terminal (void);
|
|||||||
|
|
||||||
extern ptid_t inferior_ptid;
|
extern ptid_t inferior_ptid;
|
||||||
|
|
||||||
/* Is the inferior running right now, as a result of a 'run&',
|
|
||||||
'continue&' etc command? This is used in asycn gdb to determine
|
|
||||||
whether a command that the user enters while the target is running
|
|
||||||
is allowed or not. */
|
|
||||||
extern int target_executing;
|
|
||||||
|
|
||||||
/* Are we simulating synchronous execution? This is used in async gdb
|
/* Are we simulating synchronous execution? This is used in async gdb
|
||||||
to implement the 'run', 'continue' etc commands, which will not
|
to implement the 'run', 'continue' etc commands, which will not
|
||||||
redisplay the prompt until the execution is actually over. */
|
redisplay the prompt until the execution is actually over. */
|
||||||
|
@ -1771,6 +1771,11 @@ handle_inferior_event (struct execution_control_state *ecs)
|
|||||||
&& ecs->ws.kind != TARGET_WAITKIND_SIGNALLED && ecs->new_thread_event)
|
&& ecs->ws.kind != TARGET_WAITKIND_SIGNALLED && ecs->new_thread_event)
|
||||||
add_thread (ecs->ptid);
|
add_thread (ecs->ptid);
|
||||||
|
|
||||||
|
/* Mark all threads as not-executing. In non-stop, this should be
|
||||||
|
adjusted to only mark ecs->ptid. */
|
||||||
|
if (ecs->ws.kind != TARGET_WAITKIND_IGNORE)
|
||||||
|
set_executing (pid_to_ptid (-1), 0);
|
||||||
|
|
||||||
switch (ecs->ws.kind)
|
switch (ecs->ws.kind)
|
||||||
{
|
{
|
||||||
case TARGET_WAITKIND_LOADED:
|
case TARGET_WAITKIND_LOADED:
|
||||||
|
@ -1624,10 +1624,7 @@ linux_nat_resume (ptid_t ptid, int step, enum target_signal signo)
|
|||||||
signo ? strsignal (signo) : "0");
|
signo ? strsignal (signo) : "0");
|
||||||
|
|
||||||
if (target_can_async_p ())
|
if (target_can_async_p ())
|
||||||
{
|
target_async (inferior_event_handler, 0);
|
||||||
target_executing = 1;
|
|
||||||
target_async (inferior_event_handler, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Issue kill to specified lwp. */
|
/* Issue kill to specified lwp. */
|
||||||
|
@ -175,8 +175,8 @@ mi_cmd_exec_continue (char *command, char **argv, int argc)
|
|||||||
void
|
void
|
||||||
mi_cmd_exec_interrupt (char *command, char **argv, int argc)
|
mi_cmd_exec_interrupt (char *command, char **argv, int argc)
|
||||||
{
|
{
|
||||||
if (!target_executing)
|
if (!is_running (inferior_ptid))
|
||||||
error ("mi_cmd_exec_interrupt: Inferior not executing.");
|
error ("mi_cmd_exec_interrupt: Inferior not running.");
|
||||||
|
|
||||||
interrupt_target_command (NULL, 0);
|
interrupt_target_command (NULL, 0);
|
||||||
}
|
}
|
||||||
@ -1059,7 +1059,7 @@ mi_cmd_execute (struct mi_parse *parse)
|
|||||||
|
|
||||||
if (parse->cmd->argv_func != NULL)
|
if (parse->cmd->argv_func != NULL)
|
||||||
{
|
{
|
||||||
if (target_executing)
|
if (is_running (inferior_ptid))
|
||||||
{
|
{
|
||||||
if (strcmp (parse->command, "exec-interrupt"))
|
if (strcmp (parse->command, "exec-interrupt"))
|
||||||
{
|
{
|
||||||
@ -1144,7 +1144,7 @@ mi_execute_async_cli_command (char *cli_command, char **argv, int argc)
|
|||||||
if (target_can_async_p ())
|
if (target_can_async_p ())
|
||||||
{
|
{
|
||||||
/* If we're not executing, an exception should have been throw. */
|
/* If we're not executing, an exception should have been throw. */
|
||||||
gdb_assert (target_executing);
|
gdb_assert (is_running (inferior_ptid));
|
||||||
do_cleanups (old_cleanups);
|
do_cleanups (old_cleanups);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3232,13 +3232,6 @@ remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
|
|||||||
NOT asynchronously. */
|
NOT asynchronously. */
|
||||||
if (target_can_async_p ())
|
if (target_can_async_p ())
|
||||||
target_async (inferior_event_handler, 0);
|
target_async (inferior_event_handler, 0);
|
||||||
/* Tell the world that the target is now executing. */
|
|
||||||
/* FIXME: cagney/1999-09-23: Is it the targets responsibility to set
|
|
||||||
this? Instead, should the client of target just assume (for
|
|
||||||
async targets) that the target is going to start executing? Is
|
|
||||||
this information already found in the continuation block? */
|
|
||||||
if (target_is_async_p ())
|
|
||||||
target_executing = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "regcache.h"
|
#include "regcache.h"
|
||||||
#include "solib.h"
|
#include "solib.h"
|
||||||
#include "valprint.h"
|
#include "valprint.h"
|
||||||
|
#include "gdbthread.h"
|
||||||
|
|
||||||
#include "gdb_assert.h"
|
#include "gdb_assert.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -1643,6 +1644,9 @@ get_selected_block (CORE_ADDR *addr_in_block)
|
|||||||
if (!target_has_stack)
|
if (!target_has_stack)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (is_executing (inferior_ptid))
|
||||||
|
return 0;
|
||||||
|
|
||||||
return get_frame_block (get_selected_frame (NULL), addr_in_block);
|
return get_frame_block (get_selected_frame (NULL), addr_in_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1787,8 +1787,8 @@ target_resume (ptid_t ptid, int step, enum target_signal signal)
|
|||||||
{
|
{
|
||||||
dcache_invalidate (target_dcache);
|
dcache_invalidate (target_dcache);
|
||||||
(*current_target.to_resume) (ptid, step, signal);
|
(*current_target.to_resume) (ptid, step, signal);
|
||||||
|
set_executing (ptid, 1);
|
||||||
set_running (ptid, 1);
|
set_running (ptid, 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
/* Look through the list of possible targets for a target that can
|
/* Look through the list of possible targets for a target that can
|
||||||
follow forks. */
|
follow forks. */
|
||||||
|
72
gdb/thread.c
72
gdb/thread.c
@ -63,6 +63,9 @@ static void thread_apply_command (char *, int);
|
|||||||
static void restore_current_thread (ptid_t);
|
static void restore_current_thread (ptid_t);
|
||||||
static void prune_threads (void);
|
static void prune_threads (void);
|
||||||
|
|
||||||
|
static int main_thread_running = 0;
|
||||||
|
static int main_thread_executing = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
delete_step_resume_breakpoint (void *arg)
|
delete_step_resume_breakpoint (void *arg)
|
||||||
{
|
{
|
||||||
@ -104,6 +107,9 @@ init_thread_list (void)
|
|||||||
struct thread_info *tp, *tpnext;
|
struct thread_info *tp, *tpnext;
|
||||||
|
|
||||||
highest_thread_num = 0;
|
highest_thread_num = 0;
|
||||||
|
main_thread_running = 0;
|
||||||
|
main_thread_executing = 0;
|
||||||
|
|
||||||
if (!thread_list)
|
if (!thread_list)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -441,8 +447,6 @@ prune_threads (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int main_thread_running = 0;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
set_running (ptid_t ptid, int running)
|
set_running (ptid_t ptid, int running)
|
||||||
{
|
{
|
||||||
@ -494,6 +498,9 @@ is_running (ptid_t ptid)
|
|||||||
{
|
{
|
||||||
struct thread_info *tp;
|
struct thread_info *tp;
|
||||||
|
|
||||||
|
if (!target_has_execution)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!thread_list)
|
if (!thread_list)
|
||||||
return main_thread_running;
|
return main_thread_running;
|
||||||
|
|
||||||
@ -502,6 +509,67 @@ is_running (ptid_t ptid)
|
|||||||
return tp->running_;
|
return tp->running_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
any_running (void)
|
||||||
|
{
|
||||||
|
struct thread_info *tp;
|
||||||
|
|
||||||
|
if (!target_has_execution)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!thread_list)
|
||||||
|
return main_thread_running;
|
||||||
|
|
||||||
|
for (tp = thread_list; tp; tp = tp->next)
|
||||||
|
if (tp->running_)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
is_executing (ptid_t ptid)
|
||||||
|
{
|
||||||
|
struct thread_info *tp;
|
||||||
|
|
||||||
|
if (!target_has_execution)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!thread_list)
|
||||||
|
return main_thread_executing;
|
||||||
|
|
||||||
|
tp = find_thread_pid (ptid);
|
||||||
|
gdb_assert (tp);
|
||||||
|
return tp->executing_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_executing (ptid_t ptid, int executing)
|
||||||
|
{
|
||||||
|
struct thread_info *tp;
|
||||||
|
|
||||||
|
if (!thread_list)
|
||||||
|
{
|
||||||
|
/* This target does not add the main thread to the thread list.
|
||||||
|
Use a global flag to indicate that the thread is
|
||||||
|
executing. */
|
||||||
|
main_thread_executing = executing;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PIDGET (ptid) == -1)
|
||||||
|
{
|
||||||
|
for (tp = thread_list; tp; tp = tp->next)
|
||||||
|
tp->executing_ = executing;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tp = find_thread_pid (ptid);
|
||||||
|
gdb_assert (tp);
|
||||||
|
tp->executing_ = executing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Prints the list of threads and their details on UIOUT.
|
/* Prints the list of threads and their details on UIOUT.
|
||||||
This is a version of 'info_thread_command' suitable for
|
This is a version of 'info_thread_command' suitable for
|
||||||
use from MI.
|
use from MI.
|
||||||
|
13
gdb/top.c
13
gdb/top.c
@ -46,6 +46,7 @@
|
|||||||
#include "gdb_assert.h"
|
#include "gdb_assert.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "event-loop.h"
|
#include "event-loop.h"
|
||||||
|
#include "gdbthread.h"
|
||||||
|
|
||||||
/* readline include files */
|
/* readline include files */
|
||||||
#include "readline/readline.h"
|
#include "readline/readline.h"
|
||||||
@ -181,12 +182,6 @@ int remote_timeout = 2;
|
|||||||
|
|
||||||
int remote_debug = 0;
|
int remote_debug = 0;
|
||||||
|
|
||||||
/* Non-zero means the target is running. Note: this is different from
|
|
||||||
saying that there is an active target and we are stopped at a
|
|
||||||
breakpoint, for instance. This is a real indicator whether the
|
|
||||||
target is off and running, which gdb is doing something else. */
|
|
||||||
int target_executing = 0;
|
|
||||||
|
|
||||||
/* Sbrk location on entry to main. Used for statistics only. */
|
/* Sbrk location on entry to main. Used for statistics only. */
|
||||||
#ifdef HAVE_SBRK
|
#ifdef HAVE_SBRK
|
||||||
char *lim_at_start;
|
char *lim_at_start;
|
||||||
@ -422,7 +417,9 @@ 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 () && target_executing && !get_cmd_async_ok (c))
|
if (target_can_async_p ()
|
||||||
|
&& any_running ()
|
||||||
|
&& !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."));
|
||||||
|
|
||||||
/* Pass null arg rather than an empty one. */
|
/* Pass null arg rather than an empty one. */
|
||||||
@ -486,7 +483,7 @@ execute_command (char *p, int from_tty)
|
|||||||
/* FIXME: This should be cacheing the frame and only running when
|
/* FIXME: This should be cacheing the frame and only running when
|
||||||
the frame changes. */
|
the frame changes. */
|
||||||
|
|
||||||
if (!target_executing && target_has_stack)
|
if (target_has_stack && !is_running (inferior_ptid))
|
||||||
{
|
{
|
||||||
flang = get_frame_language ();
|
flang = get_frame_language ();
|
||||||
if (!warned
|
if (!warned
|
||||||
|
Loading…
Reference in New Issue
Block a user