2008-05-09 Pedro Alves Add "continue /a" option for non-stop mode. * infcmd.c (proceed_thread_callback, do_context_switch_to): New. (continue_command): Add "/a" option. --- gdb/infcmd.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 11 deletions(-) Index: src/gdb/infcmd.c =================================================================== --- src.orig/gdb/infcmd.c 2008-05-08 14:23:26.000000000 +0100 +++ src/gdb/infcmd.c 2008-05-08 18:34:53.000000000 +0100 @@ -607,16 +607,36 @@ start_command (char *args, int from_tty) run_command_1 (args, from_tty, 1); } +static int +proceed_thread_callback (struct thread_info *thread, void *arg) +{ + if (is_running (thread->ptid)) + return 0; + + context_switch_to (thread->ptid); + clear_proceed_status (); + proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); + return 0; +} + +static void +do_context_switch_to (void *arg) +{ + ptid_t *ptid = arg; + context_switch_to (*ptid); +} + +/* continue [/a] [proceed-count] [&] */ void -continue_command (char *proc_count_exp, int from_tty) +continue_command (char *args, int from_tty) { int async_exec = 0; + int all_threads = 0; ERROR_NO_INFERIOR; - ensure_not_running (); /* Find out whether we must run in the background. */ - if (proc_count_exp != NULL) - async_exec = strip_bg_char (&proc_count_exp); + if (args != NULL) + async_exec = strip_bg_char (&args); /* If we must run in the background, but the target can't do it, error out. */ @@ -631,9 +651,27 @@ continue_command (char *proc_count_exp, async_disable_stdin (); } - /* If have argument (besides '&'), set proceed count of breakpoint - we stopped at. */ - if (proc_count_exp != NULL) + if (args != NULL) + { + if (strncmp (args, "/a", sizeof ("/a") - 1) == 0) + { + all_threads = 1; + args += sizeof ("/a") - 1; + if (*args == '\0') + args = NULL; + } + } + + if (!non_stop && all_threads) + error (_("/a is meaningless in all-stop mode.")); + + if (args != NULL && all_threads) + error (_("\ +Can't resume all threads and specify proceed count simultaneously.")); + + /* If we have an argument left, set proceed count of breakpoint we + stopped at. */ + if (args != NULL) { bpstat bs = stop_bpstat; int num, stat; @@ -643,7 +681,7 @@ continue_command (char *proc_count_exp, if (stat > 0) { set_ignore_count (num, - parse_and_eval_long (proc_count_exp) - 1, + parse_and_eval_long (args) - 1, from_tty); /* set_ignore_count prints a message ending with a period. So print two spaces before "Continuing.". */ @@ -662,9 +700,24 @@ continue_command (char *proc_count_exp, if (from_tty) printf_filtered (_("Continuing.\n")); - clear_proceed_status (); + if (non_stop && all_threads) + { + /* Don't error out current thread is running, because there may + be other stopped threads. */ - proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); + ptid_t current_ptid = inferior_ptid; + struct cleanup *old_chain + = make_cleanup (do_context_switch_to, ¤t_ptid); + iterate_over_threads (proceed_thread_callback, NULL); + /* Restore selected ptid. */ + do_cleanups (old_chain); + } + else + { + ensure_not_running (); + clear_proceed_status (); + proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); + } } /* Step until outside of current statement. */ @@ -2332,7 +2385,12 @@ This command is a combination of tbreak Continue program being debugged, after signal or breakpoint.\n\ If proceeding from breakpoint, a number N may be used as an argument,\n\ which means to set the ignore count of that breakpoint to N - 1 (so that\n\ -the breakpoint won't break until the Nth time it is reached).")); +the breakpoint won't break until the Nth time it is reached).\n\ +\n\ +If non-stop mode is enabled, continue only the current thread,\n\ +otherwise all the threads in the program are continued. To \n\ +continue all stopped threads in non-stop mode, use the /a option.\n\ +Specifying /a and an ignore count simultaneously is an error.")); add_com_alias ("c", "cont", class_run, 1); add_com_alias ("fg", "cont", class_run, 1);