diff options
author | Pedro Alves <palves@redhat.com> | 2008-07-09 22:42:43 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2008-07-09 22:42:43 +0000 |
commit | 94cc34afe2c3d9377f1b9cfd481b5822a03c283f (patch) | |
tree | e1b45035ccc11f0da08e382edfcfd6a835154323 /gdb/thread.c | |
parent | 59f0d5d9531817d3bb09aeef8fd33515b51a7cba (diff) | |
download | gdb-94cc34afe2c3d9377f1b9cfd481b5822a03c283f.zip gdb-94cc34afe2c3d9377f1b9cfd481b5822a03c283f.tar.gz gdb-94cc34afe2c3d9377f1b9cfd481b5822a03c283f.tar.bz2 |
Non-stop inferior control.
* infrun.c (resume): In non-stop mode, always resume just one
thread.
(proceed): Don't call prepare_to_proceed in non-stop mode.
(fetch_inferior_event): In non-stop mode, switch context before
handling the event.
(error_is_running, ensure_not_running): New.
(handle_inferior_event): In non-stop mode: Mark only the event
thread as stopped. Require that the target module manages adding
threads to the thread list. Assert that there isn't a
deferred_step_ptid set. Don't switch to infwait_thread_hop_state.
(normal_stop): Only mark not-running if inferior hasn't exited.
In non-stop mode, only mark the event thread.
* thread.c:Include "cli/cli-decode.h".
(print_thread_info): Don't read from a running thread.
Output "(running)" if thread is running.
(switch_to_thread): Don't read stop_pc if thread is executing.
(do_restore_current_thread_cleanup): Don't write to a running
thread.
(thread_apply_all_command): Don't read from a running thread. In
non-stop mode, do a full context-switch instead of just switching
threads.
(thread_apply_command): In non-stop mode, do a full context-switch
instead of just switching threads.
(do_captured_thread_select): Likewise. Inform user if selected
thread is running.
(_initialize_thread): Mark "info threads" and "thread" and
async_ok.
* inf-loop.c (inferior_event_handler): In non-stop mode, don't
unregister the target from the event loop.
* infcmd.c (continue_command, step_1, jump_command)
(signal_command): Ensure the selected thread isn't running.
(interrupt_target_command): In non-stop mode, interrupt only the
selected thread.
* inferior.h (error_is_running, ensure_not_running): Declare.
* target.h (struct target_ops): Add ptid argument to the to_stop
member.
(target_stop): Add ptid_t argument.
* target.c (update_current_target): Add ptid argument to to_stop's
type.
(debug_to_stop): Add ptid_t argument.
(debug_to_rcmd): Set to_stop_ptid.
* remote.c (remote_stop): Add ptid_t argument.
(async_remote_interrupt): Add inferior_ptid to target_stop.
* inf-ptrace.c (inf_ptrace_stop): Add ptid argument.
* Makefile.in (thread.o): Depend on $(cli_decode_h).
Diffstat (limited to 'gdb/thread.c')
-rw-r--r-- | gdb/thread.c | 99 |
1 files changed, 72 insertions, 27 deletions
diff --git a/gdb/thread.c b/gdb/thread.c index e2f8cd7..1ae9adf 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -42,6 +42,8 @@ #include "observer.h" #include "annotate.h" +#include "cli/cli-decode.h" + /* Definition of struct thread_info exported to gdbthread.h */ /* Prototypes for exported functions. */ @@ -640,9 +642,12 @@ print_thread_info (struct ui_out *uiout, int requested_thread) int current_thread = -1; /* Backup current thread and selected frame. */ - saved_frame_id = get_frame_id (get_selected_frame (NULL)); - old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id); + if (!is_running (inferior_ptid)) + saved_frame_id = get_frame_id (get_selected_frame (NULL)); + else + saved_frame_id = null_frame_id; + old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id); make_cleanup_ui_out_list_begin_end (uiout, "threads"); prune_threads (); @@ -677,12 +682,18 @@ print_thread_info (struct ui_out *uiout, int requested_thread) ui_out_text (uiout, ")"); } ui_out_text (uiout, " "); - /* That switch put us at the top of the stack (leaf frame). */ - switch_to_thread (tp->ptid); - print_stack_frame (get_selected_frame (NULL), - /* For MI output, print frame level. */ - ui_out_is_mi_like_p (uiout), - LOCATION); + if (tp->running_) + ui_out_text (uiout, "(running)\n"); + else + { + /* The switch below puts us at the top of the stack (leaf + frame). */ + switch_to_thread (tp->ptid); + print_stack_frame (get_selected_frame (NULL), + /* For MI output, print frame level. */ + ui_out_is_mi_like_p (uiout), + LOCATION); + } do_cleanups (chain2); } @@ -698,6 +709,9 @@ print_thread_info (struct ui_out *uiout, int requested_thread) ui_out_field_int (uiout, "current-thread-id", current_thread); } + if (is_running (inferior_ptid)) + return; + /* If case we were not able to find the original frame, print the new selected frame. */ if (frame_find_by_id (saved_frame_id) == NULL) @@ -736,7 +750,11 @@ switch_to_thread (ptid_t ptid) inferior_ptid = ptid; reinit_frame_cache (); registers_changed (); - stop_pc = read_pc (); + + if (!is_executing (ptid)) + stop_pc = read_pc (); + else + stop_pc = ~(CORE_ADDR) 0; } static void @@ -773,7 +791,12 @@ do_restore_current_thread_cleanup (void *arg) { struct current_thread_cleanup *old = arg; restore_current_thread (old->inferior_ptid); - restore_selected_frame (old->selected_frame_id); + + /* A command like 'thread apply all $exec_command&' may change the + running state of the originally selected thread, so we have to + recheck it here. */ + if (!is_running (old->inferior_ptid)) + restore_selected_frame (old->selected_frame_id); xfree (old); } @@ -801,8 +824,7 @@ static void thread_apply_all_command (char *cmd, int from_tty) { struct thread_info *tp; - struct cleanup *old_chain; - struct cleanup *saved_cmd_cleanup_chain; + struct cleanup *old_chain = make_cleanup (null_cleanup, 0); char *saved_cmd; struct frame_id saved_frame_id; ptid_t current_ptid; @@ -812,8 +834,12 @@ thread_apply_all_command (char *cmd, int from_tty) error (_("Please specify a command following the thread ID list")); current_ptid = inferior_ptid; - saved_frame_id = get_frame_id (get_selected_frame (NULL)); - old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id); + + if (!is_running (inferior_ptid)) + saved_frame_id = get_frame_id (get_selected_frame (NULL)); + else + saved_frame_id = null_frame_id; + make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id); /* It is safe to update the thread list now, before traversing it for "thread apply all". MVS */ @@ -822,11 +848,15 @@ thread_apply_all_command (char *cmd, int from_tty) /* Save a copy of the command in case it is clobbered by execute_command */ saved_cmd = xstrdup (cmd); - saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd); + make_cleanup (xfree, saved_cmd); for (tp = thread_list; tp; tp = tp->next) if (thread_alive (tp)) { - switch_to_thread (tp->ptid); + if (non_stop) + context_switch_to (tp->ptid); + else + switch_to_thread (tp->ptid); + printf_filtered (_("\nThread %d (%s):\n"), tp->num, target_tid_to_str (inferior_ptid)); execute_command (cmd, from_tty); @@ -836,12 +866,10 @@ thread_apply_all_command (char *cmd, int from_tty) if (!ptid_equal (current_ptid, inferior_ptid)) thread_has_changed = 1; - do_cleanups (saved_cmd_cleanup_chain); do_cleanups (old_chain); /* Print stack frame only if we changed thread. */ - if (thread_has_changed) + if (thread_has_changed && !is_running (inferior_ptid)) print_stack_frame (get_current_frame (), 1, SRC_LINE); - } static void @@ -865,7 +893,11 @@ thread_apply_command (char *tidlist, int from_tty) error (_("Please specify a command following the thread ID list")); current_ptid = inferior_ptid; - saved_frame_id = get_frame_id (get_selected_frame (NULL)); + + if (!is_running (inferior_ptid)) + saved_frame_id = get_frame_id (get_selected_frame (NULL)); + else + saved_frame_id = null_frame_id; old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id); /* Save a copy of the command in case it is clobbered by @@ -909,7 +941,10 @@ thread_apply_command (char *tidlist, int from_tty) warning (_("Thread %d has terminated."), start); else { - switch_to_thread (tp->ptid); + if (non_stop) + context_switch_to (tp->ptid); + else + switch_to_thread (tp->ptid); printf_filtered (_("\nThread %d (%s):\n"), tp->num, target_tid_to_str (inferior_ptid)); execute_command (cmd, from_tty); @@ -977,7 +1012,10 @@ do_captured_thread_select (struct ui_out *uiout, void *tidstr) if (!thread_alive (tp)) error (_("Thread ID %d has terminated."), num); - switch_to_thread (tp->ptid); + if (non_stop) + context_switch_to (tp->ptid); + else + switch_to_thread (tp->ptid); ui_out_text (uiout, "[Switching to thread "); ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid)); @@ -985,7 +1023,11 @@ do_captured_thread_select (struct ui_out *uiout, void *tidstr) ui_out_text (uiout, target_tid_to_str (inferior_ptid)); ui_out_text (uiout, ")]"); - print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); + if (!tp->running_) + print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); + else + ui_out_text (uiout, "(running)\n"); + return GDB_RC_OK; } @@ -1005,14 +1047,17 @@ void _initialize_thread (void) { static struct cmd_list_element *thread_apply_list = NULL; + struct cmd_list_element *c; - add_info ("threads", info_threads_command, - _("IDs of currently known threads.")); + c = add_info ("threads", info_threads_command, + _("IDs of currently known threads.")); + set_cmd_async_ok (c); - add_prefix_cmd ("thread", class_run, thread_command, _("\ + c = add_prefix_cmd ("thread", class_run, thread_command, _("\ Use this command to switch between threads.\n\ The new thread ID must be currently known."), - &thread_cmd_list, "thread ", 1, &cmdlist); + &thread_cmd_list, "thread ", 1, &cmdlist); + set_cmd_async_ok (c); add_prefix_cmd ("apply", class_run, thread_apply_command, _("Apply a command to a list of threads."), |