* infrun.c (normal_stop): Use has_stack_frames instead of

target_has_stack.
	* mi/mi-main.c (mi_execute_command): Avoid calling inferior_thread
	when there is no thread selected.
	(mi_cmd_execute): Don't special case commands that can run without
	a valid selected thread.
	* top.c (execute_command): Don't special case commands that can
	run without a valid selected thread.  Use has_stack_frames.
	* infcmd.c (ensure_valid_thread): New.
	(continue_1, step_1, jump_command, signal_command): Use it.
	(detach_command): Error out if there's no selected thread/inferior.
	* thread.c (print_thread_info): Allow having no thread selected.
	(switch_to_thread): Don't read the PC if there is no current thread.
	(do_restore_current_thread_cleanup): Don't record the current
	frame if there is no current thread.
	(make_cleanup_restore_current_thread): Don't read frame info if
	there is no selected thread.
	(_initialize_thread): Don't mark commands as
	"no_selected_thread_ok".
	* frame.c (get_current_frame): Error out if there is no valid
	selected thread.
	(has_stack_frames): Return false if there is no valid
	selected thread.
	* cli/cli-cmds.c (init_cli_cmds): Don't mark commands as
	"no_selected_thread_ok".
	* cli/cli-decode.c (set_cmd_no_selected_thread_ok)
	(get_cmd_no_selected_thread_ok): Delete.
	* cli/cli-decode.h (CMD_NO_SELECTED_THREAD_OK): Delete.
	(set_cmd_no_selected_thread_ok, get_cmd_no_selected_thread_ok):
	Delete declaration.
	* stack.c (get_selected_block): Use has_stack_frames.
This commit is contained in:
Pedro Alves 2009-03-25 21:42:35 +00:00
parent f04c6d38e2
commit d729566a19
12 changed files with 137 additions and 134 deletions

View File

@ -1,3 +1,37 @@
2009-03-25 Pedro Alves <pedro@codesourcery.com>
* infrun.c (normal_stop): Use has_stack_frames instead of
target_has_stack.
* mi/mi-main.c (mi_execute_command): Avoid calling inferior_thread
when there is no thread selected.
(mi_cmd_execute): Don't special case commands that can run without
a valid selected thread.
* top.c (execute_command): Don't special case commands that can
run without a valid selected thread. Use has_stack_frames.
* infcmd.c (ensure_valid_thread): New.
(continue_1, step_1, jump_command, signal_command): Use it.
(detach_command): Error out if there's no selected thread/inferior.
* thread.c (print_thread_info): Allow having no thread selected.
(switch_to_thread): Don't read the PC if there is no current thread.
(do_restore_current_thread_cleanup): Don't record the current
frame if there is no current thread.
(make_cleanup_restore_current_thread): Don't read frame info if
there is no selected thread.
(_initialize_thread): Don't mark commands as
"no_selected_thread_ok".
* frame.c (get_current_frame): Error out if there is no valid
selected thread.
(has_stack_frames): Return false if there is no valid
selected thread.
* cli/cli-cmds.c (init_cli_cmds): Don't mark commands as
"no_selected_thread_ok".
* cli/cli-decode.c (set_cmd_no_selected_thread_ok)
(get_cmd_no_selected_thread_ok): Delete.
* cli/cli-decode.h (CMD_NO_SELECTED_THREAD_OK): Delete.
(set_cmd_no_selected_thread_ok, get_cmd_no_selected_thread_ok):
Delete declaration.
* stack.c (get_selected_block): Use has_stack_frames.
2009-03-25 Thiago Jung Bauermann <bauerman@br.ibm.com> 2009-03-25 Thiago Jung Bauermann <bauerman@br.ibm.com>
Fix size of FPSCR in Power 7 processors. Fix size of FPSCR in Power 7 processors.

View File

@ -1248,9 +1248,8 @@ The commands below can be used to select other frames by number or address."),
/* Define general commands. */ /* Define general commands. */
c = add_com ("pwd", class_files, pwd_command, _("\ add_com ("pwd", class_files, pwd_command, _("\
Print working directory. This is used for your program as well.")); Print working directory. This is used for your program as well."));
set_cmd_no_selected_thread_ok (c);
c = add_cmd ("cd", class_files, cd_command, _("\ c = add_cmd ("cd", class_files, cd_command, _("\
Set working directory to DIR for debugger and program being debugged.\n\ Set working directory to DIR for debugger and program being debugged.\n\
@ -1291,7 +1290,6 @@ when GDB is started."), gdbinit);
c = add_com ("help", class_support, help_command, c = add_com ("help", class_support, help_command,
_("Print list of commands.")); _("Print list of commands."));
set_cmd_completer (c, command_completer); set_cmd_completer (c, command_completer);
set_cmd_no_selected_thread_ok (c);
add_com_alias ("q", "quit", class_support, 1); add_com_alias ("q", "quit", class_support, 1);
add_com_alias ("h", "help", class_support, 1); add_com_alias ("h", "help", class_support, 1);
@ -1317,19 +1315,17 @@ Without an argument, history expansion is enabled."),
show_history_expansion_p, show_history_expansion_p,
&sethistlist, &showhistlist); &sethistlist, &showhistlist);
c = add_prefix_cmd ("info", class_info, info_command, _("\ add_prefix_cmd ("info", class_info, info_command, _("\
Generic command for showing things about the program being debugged."), Generic command for showing things about the program being debugged."),
&infolist, "info ", 0, &cmdlist); &infolist, "info ", 0, &cmdlist);
set_cmd_no_selected_thread_ok (c);
add_com_alias ("i", "info", class_info, 1); add_com_alias ("i", "info", class_info, 1);
add_com ("complete", class_obscure, complete_command, add_com ("complete", class_obscure, complete_command,
_("List the completions for the rest of the line as a command.")); _("List the completions for the rest of the line as a command."));
c = add_prefix_cmd ("show", class_info, show_command, _("\ add_prefix_cmd ("show", class_info, show_command, _("\
Generic command for showing things about the debugger."), Generic command for showing things about the debugger."),
&showlist, "show ", 0, &cmdlist); &showlist, "show ", 0, &cmdlist);
set_cmd_no_selected_thread_ok (c);
/* Another way to get at the same thing. */ /* Another way to get at the same thing. */
add_info ("set", show_command, _("Show all GDB settings.")); add_info ("set", show_command, _("Show all GDB settings."));

View File

@ -112,18 +112,6 @@ get_cmd_context (struct cmd_list_element *cmd)
return cmd->context; return cmd->context;
} }
void
set_cmd_no_selected_thread_ok (struct cmd_list_element *cmd)
{
cmd->flags |= CMD_NO_SELECTED_THREAD_OK;
}
int
get_cmd_no_selected_thread_ok (struct cmd_list_element *cmd)
{
return cmd->flags & CMD_NO_SELECTED_THREAD_OK;
}
enum cmd_types enum cmd_types
cmd_type (struct cmd_list_element *cmd) cmd_type (struct cmd_list_element *cmd)
{ {

View File

@ -48,10 +48,6 @@ cmd_types;
#define DEPRECATED_WARN_USER 0x2 #define DEPRECATED_WARN_USER 0x2
#define MALLOCED_REPLACEMENT 0x4 #define MALLOCED_REPLACEMENT 0x4
/* This flag is set if the command is allowed to run when the target
has execution, but there's no selected thread. */
#define CMD_NO_SELECTED_THREAD_OK 0x10
struct cmd_list_element struct cmd_list_element
{ {
/* Points to next command in this list. */ /* Points to next command in this list. */
@ -259,13 +255,6 @@ extern int cmd_cfunc_eq (struct cmd_list_element *cmd,
extern void set_cmd_context (struct cmd_list_element *cmd, void *context); extern void set_cmd_context (struct cmd_list_element *cmd, void *context);
extern void *get_cmd_context (struct cmd_list_element *cmd); extern void *get_cmd_context (struct cmd_list_element *cmd);
/* Mark command as ok to call when there is no selected thread. There
is no way to disable this once set. */
extern void set_cmd_no_selected_thread_ok (struct cmd_list_element *);
/* Return true if command is no-selected-thread-ok. */
extern int get_cmd_no_selected_thread_ok (struct cmd_list_element *);
extern struct cmd_list_element *lookup_cmd (char **, extern struct cmd_list_element *lookup_cmd (char **,
struct cmd_list_element *, char *, struct cmd_list_element *, char *,
int, int); int, int);

View File

@ -980,6 +980,10 @@ 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 (ptid_equal (inferior_ptid, null_ptid))
error (_("No selected thread."));
if (is_exited (inferior_ptid))
error (_("Invalid selected thread."));
if (is_executing (inferior_ptid)) if (is_executing (inferior_ptid))
error (_("Target is executing.")); error (_("Target is executing."));
@ -1009,8 +1013,15 @@ has_stack_frames (void)
if (!target_has_registers || !target_has_stack || !target_has_memory) if (!target_has_registers || !target_has_stack || !target_has_memory)
return 0; return 0;
/* If the current thread is executing, don't try to read from /* No current inferior, no frame. */
it. */ if (ptid_equal (inferior_ptid, null_ptid))
return 0;
/* Don't try to read from a dead thread. */
if (is_exited (inferior_ptid))
return 0;
/* ... or from a spinning thread. */
if (is_executing (inferior_ptid)) if (is_executing (inferior_ptid))
return 0; return 0;

View File

@ -616,6 +616,15 @@ proceed_thread_callback (struct thread_info *thread, void *arg)
return 0; return 0;
} }
void
ensure_valid_thread (void)
{
if (ptid_equal (inferior_ptid, null_ptid)
|| is_exited (inferior_ptid))
error (_("\
Cannot execute this command without a live selected thread."));
}
void void
continue_1 (int all_threads) continue_1 (int all_threads)
{ {
@ -637,6 +646,7 @@ continue_1 (int all_threads)
} }
else else
{ {
ensure_valid_thread ();
ensure_not_running (); ensure_not_running ();
clear_proceed_status (); clear_proceed_status ();
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
@ -781,6 +791,7 @@ step_1 (int skip_subroutines, int single_inst, char *count_string)
int thread = -1; int thread = -1;
ERROR_NO_INFERIOR; ERROR_NO_INFERIOR;
ensure_valid_thread ();
ensure_not_running (); ensure_not_running ();
if (count_string) if (count_string)
@ -991,6 +1002,7 @@ jump_command (char *arg, int from_tty)
int async_exec = 0; int async_exec = 0;
ERROR_NO_INFERIOR; ERROR_NO_INFERIOR;
ensure_valid_thread ();
ensure_not_running (); ensure_not_running ();
/* Find out whether we must run in the background. */ /* Find out whether we must run in the background. */
@ -1092,6 +1104,7 @@ signal_command (char *signum_exp, int from_tty)
dont_repeat (); /* Too dangerous. */ dont_repeat (); /* Too dangerous. */
ERROR_NO_INFERIOR; ERROR_NO_INFERIOR;
ensure_valid_thread ();
ensure_not_running (); ensure_not_running ();
/* Find out whether we must run in the background. */ /* Find out whether we must run in the background. */
@ -2383,6 +2396,10 @@ void
detach_command (char *args, int from_tty) detach_command (char *args, int from_tty)
{ {
dont_repeat (); /* Not for the faint of heart. */ dont_repeat (); /* Not for the faint of heart. */
if (ptid_equal (inferior_ptid, null_ptid))
error (_("The program is not being run."));
target_detach (args, from_tty); target_detach (args, from_tty);
/* If the solist is global across inferiors, don't clear it when we /* If the solist is global across inferiors, don't clear it when we

View File

@ -4302,7 +4302,7 @@ Further execution is probably impossible.\n"));
/* Set the current source location. This will also happen if we /* Set the current source location. This will also happen if we
display the frame below, but the current SAL will be incorrect display the frame below, but the current SAL will be incorrect
during a user hook-stop function. */ during a user hook-stop function. */
if (target_has_stack && !stop_stack_dummy) if (has_stack_frames () && !stop_stack_dummy)
set_current_sal_from_frame (get_current_frame (), 1); set_current_sal_from_frame (get_current_frame (), 1);
/* Let the user/frontend see the threads as stopped. */ /* Let the user/frontend see the threads as stopped. */
@ -4314,7 +4314,7 @@ Further execution is probably impossible.\n"));
catch_errors (hook_stop_stub, stop_command, catch_errors (hook_stop_stub, stop_command,
"Error while running hook_stop:\n", RETURN_MASK_ALL); "Error while running hook_stop:\n", RETURN_MASK_ALL);
if (!target_has_stack) if (!has_stack_frames ())
goto done; goto done;
if (last.kind == TARGET_WAITKIND_SIGNALLED if (last.kind == TARGET_WAITKIND_SIGNALLED

View File

@ -1284,21 +1284,23 @@ mi_execute_command (char *cmd, int from_tty)
&& strcmp (command->command, "thread-select") != 0) && strcmp (command->command, "thread-select") != 0)
{ {
struct mi_interp *mi = top_level_interpreter_data (); struct mi_interp *mi = top_level_interpreter_data ();
struct thread_info *ti = inferior_thread (); int report_change = 0;
int report_change;
if (command->thread == -1) if (command->thread == -1)
{ {
report_change = !ptid_equal (previous_ptid, null_ptid) report_change = (!ptid_equal (previous_ptid, null_ptid)
&& !ptid_equal (inferior_ptid, previous_ptid); && !ptid_equal (inferior_ptid, previous_ptid)
&& !ptid_equal (inferior_ptid, null_ptid));
} }
else else if (!ptid_equal (inferior_ptid, null_ptid))
{ {
struct thread_info *ti = inferior_thread ();
report_change = (ti->num != command->thread); report_change = (ti->num != command->thread);
} }
if (report_change) if (report_change)
{ {
struct thread_info *ti = inferior_thread ();
target_terminal_ours (); target_terminal_ours ();
fprintf_unfiltered (mi->event_channel, fprintf_unfiltered (mi->event_channel,
"thread-selected,id=\"%d\"", "thread-selected,id=\"%d\"",
@ -1353,28 +1355,7 @@ mi_cmd_execute (struct mi_parse *parse)
} }
if (parse->cmd->argv_func != NULL) if (parse->cmd->argv_func != NULL)
{ parse->cmd->argv_func (parse->command, parse->argv, parse->argc);
if (target_can_async_p ()
&& target_has_execution
&& is_exited (inferior_ptid)
&& (strcmp (parse->command, "thread-info") != 0
&& strcmp (parse->command, "thread-list-ids") != 0
&& strcmp (parse->command, "thread-select") != 0
&& strcmp (parse->command, "list-thread-groups") != 0))
{
struct ui_file *stb;
stb = mem_fileopen ();
fputs_unfiltered ("Cannot execute command ", stb);
fputstr_unfiltered (parse->command, '"', stb);
fputs_unfiltered (" without a selected thread", stb);
make_cleanup_ui_file_delete (stb);
error_stream (stb);
}
parse->cmd->argv_func (parse->command, parse->argv, parse->argc);
}
else if (parse->cmd->cli.cmd != 0) else if (parse->cmd->cli.cmd != 0)
{ {
/* FIXME: DELETE THIS. */ /* FIXME: DELETE THIS. */

View File

@ -6606,19 +6606,6 @@ remote_mourn_1 (struct target_ops *target)
generic_mourn_inferior (); generic_mourn_inferior ();
} }
static int
select_new_thread_callback (struct thread_info *th, void* data)
{
if (!is_exited (th->ptid))
{
switch_to_thread (th->ptid);
printf_filtered (_("[Switching to %s]\n"),
target_pid_to_str (inferior_ptid));
return 1;
}
return 0;
}
static void static void
extended_remote_mourn_1 (struct target_ops *target) extended_remote_mourn_1 (struct target_ops *target)
{ {
@ -6662,16 +6649,7 @@ extended_remote_mourn_1 (struct target_ops *target)
/* Call common code to mark the inferior as not running. */ /* Call common code to mark the inferior as not running. */
generic_mourn_inferior (); generic_mourn_inferior ();
if (have_inferiors ()) if (!have_inferiors ())
{
extern void nullify_last_target_wait_ptid ();
/* Multi-process case. The current process has exited, but
there are other processes to debug. Switch to the first
available. */
iterate_over_threads (select_new_thread_callback, NULL);
nullify_last_target_wait_ptid ();
}
else
{ {
if (!remote_multi_process_p (rs)) if (!remote_multi_process_p (rs))
{ {

View File

@ -1694,13 +1694,7 @@ select_and_print_frame (struct frame_info *frame)
struct block * struct block *
get_selected_block (CORE_ADDR *addr_in_block) get_selected_block (CORE_ADDR *addr_in_block)
{ {
if (!target_has_stack) if (!has_stack_frames ())
return 0;
if (is_exited (inferior_ptid))
return 0;
if (is_executing (inferior_ptid))
return 0; return 0;
return get_frame_block (get_selected_frame (NULL), addr_in_block); return get_frame_block (get_selected_frame (NULL), addr_in_block);

View File

@ -785,10 +785,11 @@ print_thread_info (struct ui_out *uiout, int requested_thread, int pid)
the "info threads" command. */ the "info threads" command. */
do_cleanups (old_chain); do_cleanups (old_chain);
if (pid == -1 && requested_thread == -1 ) if (pid == -1 && requested_thread == -1)
{ {
gdb_assert (current_thread != -1 gdb_assert (current_thread != -1
|| !thread_list); || !thread_list
|| ptid_equal (inferior_ptid, null_ptid));
if (current_thread != -1 && ui_out_is_mi_like_p (uiout)) if (current_thread != -1 && ui_out_is_mi_like_p (uiout))
ui_out_field_int (uiout, "current-thread-id", current_thread); ui_out_field_int (uiout, "current-thread-id", current_thread);
@ -796,6 +797,11 @@ print_thread_info (struct ui_out *uiout, int requested_thread, int pid)
ui_out_message (uiout, 0, "\n\ ui_out_message (uiout, 0, "\n\
The current thread <Thread ID %d> has terminated. See `help thread'.\n", The current thread <Thread ID %d> has terminated. See `help thread'.\n",
current_thread); current_thread);
else if (thread_list
&& current_thread == -1
&& ptid_equal (current_ptid, null_ptid))
ui_out_message (uiout, 0, "\n\
No selected thread. See `help thread'.\n");
} }
} }
@ -828,7 +834,9 @@ switch_to_thread (ptid_t ptid)
/* We don't check for is_stopped, because we're called at times /* We don't check for is_stopped, because we're called at times
while in the TARGET_RUNNING state, e.g., while handling an while in the TARGET_RUNNING state, e.g., while handling an
internal event. */ internal event. */
if (!is_exited (ptid) && !is_executing (ptid)) if (!ptid_equal (inferior_ptid, null_ptid)
&& !is_exited (ptid)
&& !is_executing (ptid))
stop_pc = read_pc (); stop_pc = read_pc ();
else else
stop_pc = ~(CORE_ADDR) 0; stop_pc = ~(CORE_ADDR) 0;
@ -909,11 +917,24 @@ do_restore_current_thread_cleanup (void *arg)
{ {
struct thread_info *tp; struct thread_info *tp;
struct current_thread_cleanup *old = arg; struct current_thread_cleanup *old = arg;
restore_current_thread (old->inferior_ptid);
tp = find_thread_pid (old->inferior_ptid);
/* If the previously selected thread belonged to a process that has
in the mean time been deleted (due to normal exit, detach, etc.),
then don't revert back to it, but instead simply drop back to no
thread selected. */
if (tp
&& is_exited (tp->ptid)
&& find_inferior_pid (ptid_get_pid (tp->ptid)) == NULL)
restore_current_thread (null_ptid);
else
restore_current_thread (old->inferior_ptid);
/* The running state of the originally selected thread may have /* The running state of the originally selected thread may have
changed, so we have to recheck it here. */ changed, so we have to recheck it here. */
if (old->was_stopped if (!ptid_equal (inferior_ptid, null_ptid)
&& old->was_stopped
&& is_stopped (inferior_ptid) && is_stopped (inferior_ptid)
&& target_has_registers && target_has_registers
&& target_has_stack && target_has_stack
@ -942,21 +963,25 @@ make_cleanup_restore_current_thread (void)
old = xmalloc (sizeof (struct current_thread_cleanup)); old = xmalloc (sizeof (struct current_thread_cleanup));
old->inferior_ptid = inferior_ptid; old->inferior_ptid = inferior_ptid;
old->was_stopped = is_stopped (inferior_ptid);
if (old->was_stopped
&& target_has_registers
&& target_has_stack
&& target_has_memory)
frame = get_selected_frame (NULL);
else
frame = NULL;
old->selected_frame_id = get_frame_id (frame); if (!ptid_equal (inferior_ptid, null_ptid))
old->selected_frame_level = frame_relative_level (frame); {
old->was_stopped = is_stopped (inferior_ptid);
if (old->was_stopped
&& target_has_registers
&& target_has_stack
&& target_has_memory)
frame = get_selected_frame (NULL);
else
frame = NULL;
tp = find_thread_pid (inferior_ptid); old->selected_frame_id = get_frame_id (frame);
if (tp) old->selected_frame_level = frame_relative_level (frame);
tp->refcount++;
tp = find_thread_pid (inferior_ptid);
if (tp)
tp->refcount++;
}
return make_cleanup_dtor (do_restore_current_thread_cleanup, old, return make_cleanup_dtor (do_restore_current_thread_cleanup, old,
restore_current_thread_cleanup_dtor); restore_current_thread_cleanup_dtor);
@ -1086,6 +1111,9 @@ thread_command (char *tidstr, int from_tty)
{ {
if (!tidstr) if (!tidstr)
{ {
if (ptid_equal (inferior_ptid, null_ptid))
error (_("No thread selected"));
if (target_has_stack) if (target_has_stack)
{ {
if (is_exited (inferior_ptid)) if (is_exited (inferior_ptid))
@ -1172,26 +1200,21 @@ void
_initialize_thread (void) _initialize_thread (void)
{ {
static struct cmd_list_element *thread_apply_list = NULL; static struct cmd_list_element *thread_apply_list = NULL;
struct cmd_list_element *c;
c = add_info ("threads", info_threads_command, add_info ("threads", info_threads_command,
_("IDs of currently known threads.")); _("IDs of currently known threads."));
set_cmd_no_selected_thread_ok (c);
c = add_prefix_cmd ("thread", class_run, thread_command, _("\ add_prefix_cmd ("thread", class_run, thread_command, _("\
Use this command to switch between threads.\n\ Use this command to switch between threads.\n\
The new thread ID must be currently known."), The new thread ID must be currently known."),
&thread_cmd_list, "thread ", 1, &cmdlist); &thread_cmd_list, "thread ", 1, &cmdlist);
set_cmd_no_selected_thread_ok (c);
c = add_prefix_cmd ("apply", class_run, thread_apply_command, add_prefix_cmd ("apply", class_run, thread_apply_command,
_("Apply a command to a list of threads."), _("Apply a command to a list of threads."),
&thread_apply_list, "thread apply ", 1, &thread_cmd_list); &thread_apply_list, "thread apply ", 1, &thread_cmd_list);
set_cmd_no_selected_thread_ok (c);
c = add_cmd ("all", class_run, thread_apply_all_command, add_cmd ("all", class_run, thread_apply_all_command,
_("Apply a command to all threads."), &thread_apply_list); _("Apply a command to all threads."), &thread_apply_list);
set_cmd_no_selected_thread_ok (c);
if (!xdb_commands) if (!xdb_commands)
add_com_alias ("t", "thread", class_run, 1); add_com_alias ("t", "thread", class_run, 1);

View File

@ -400,14 +400,6 @@ execute_command (char *p, int from_tty)
c = lookup_cmd (&p, cmdlist, "", 0, 1); c = lookup_cmd (&p, cmdlist, "", 0, 1);
/* If the selected thread has terminated, we allow only a
limited set of commands. */
if (target_can_async_p ()
&& is_exited (inferior_ptid)
&& !get_cmd_no_selected_thread_ok (c))
error (_("\
Cannot execute this command without a live selected thread. See `help thread'."));
/* Pass null arg rather than an empty one. */ /* Pass null arg rather than an empty one. */
arg = *p ? p : 0; arg = *p ? p : 0;
@ -469,7 +461,7 @@ Cannot execute this command without a live selected thread. See `help thread'."
/* 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_has_stack && is_stopped (inferior_ptid)) if (has_stack_frames ())
{ {
flang = get_frame_language (); flang = get_frame_language ();
if (!warned if (!warned