From d4db2f362ffff0e4a55e2e0c5382204e3e59a476 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Thu, 11 Jun 2009 11:57:46 +0000 Subject: [PATCH] gdb/ * infrun.c (sched_multi): New global. (resume): If sched_multi is set, resume only threads of the current inferior. (prepare_to_proceed): Don't switch over to wait_ptid if we're resuming a different inferior, and sched_multi is off. (show_schedule_multiple): New. (_initialize_infrun): Register new "set schedule-multiple" command. * inferior.h (sched_multi): Declare. * NEWS: Mention new "schedule-multiple" setting. gdb/doc/ * gdb.texinfo (All-Stop): Document new 'set schedule-multiple' command. --- gdb/ChangeLog | 12 +++++++++ gdb/NEWS | 5 ++++ gdb/doc/ChangeLog | 5 ++++ gdb/doc/gdb.texinfo | 30 ++++++++++++++++++++++ gdb/inferior.h | 2 ++ gdb/infrun.c | 62 +++++++++++++++++++++++++++++++++++++-------- 6 files changed, 106 insertions(+), 10 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5b23ea78ffe..b296122a04c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2009-06-11 Pedro Alves + + * infrun.c (sched_multi): New global. + (resume): If sched_multi is set, resume only threads of the + current inferior. + (prepare_to_proceed): Don't switch over to wait_ptid if we're + resuming a different inferior, and sched_multi is off. + (show_schedule_multiple): New. + (_initialize_infrun): Register new "set schedule-multiple" command. + * inferior.h (sched_multi): Declare. + * NEWS: Mention new "schedule-multiple" setting. + 2009-06-11 Pedro Alves * varobj.c (varobj_create): Properly restore the selected frame. diff --git a/gdb/NEWS b/gdb/NEWS index d0188855f05..98065324cb6 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -305,6 +305,11 @@ show libthread-db-search-path Control list of directories which GDB will search for appropriate libthread_db. +set schedule-multiple (on|off) +show schedule-multiple + Allow GDB to resume all threads of all processes or only threads of + the current process. + * New native configurations x86/x86_64 Darwin i[34567]86-*-darwin* diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index d4c574a98b6..ff1ffd027e8 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2009-06-11 Pedro Alves + + * gdb.texinfo (All-Stop): Document new 'set schedule-multiple' + command. + 2009-06-07 Pedro Alves * gdbint.texinfo (TARGET_HAS_HARDWARE_WATCHPOINTS): Delete all diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 6f5fb9a7b27..c4459e3c39a 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -4650,6 +4650,36 @@ the current thread away from the thread that you are debugging. Display the current scheduler locking mode. @end table +@cindex resume threads of multiple processes simultaneously +By default, when you issue one of the execution commands such as +@code{continue}, @code{next} or @code{step}, @value{GDBN} allows only +threads of the current inferior to run. For example, if @value{GDBN} +is attached to two inferiors, each with two threads, the +@code{continue} command resumes only the two threads of the current +inferior. This is useful, for example, when you debug a program that +forks and you want to hold the parent stopped (so that, for instance, +it doesn't run to exit), while you debug the child. In other +situations, you may not be interested in inspecting the current state +of any of the processes @value{GDBN} is attached to, and you may want +to resume them all until some breakpoint is hit. In the latter case, +you can instruct @value{GDBN} to allow all threads of all the +inferiors to run with the @w{@code{set schedule-multiple}} command. + +@table @code +@kindex set schedule-multiple +@item set schedule-multiple +Set the mode for allowing threads of multiple processes to be resumed +when an execution command is issued. When @code{on}, all threads of +all processes are allowed to run. When @code{off}, only the threads +of the current process are resumed. The default is @code{off}. The +@code{scheduler-locking} mode takes precedence when set to @code{on}, +or while you are stepping and set to @code{step}. + +@item show schedule-multiple +Display the current mode for resuming the execution of threads of +multiple processes. +@end table + @node Non-Stop Mode @subsection Non-Stop Mode diff --git a/gdb/inferior.h b/gdb/inferior.h index 60d59137ba4..31764d2f088 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -135,6 +135,8 @@ extern void clear_proceed_status (void); extern void proceed (CORE_ADDR, enum target_signal, int); +extern int sched_multi; + /* When set, stop the 'step' command if we enter a function which has no line number information. The normal behavior is that we step over such function. */ diff --git a/gdb/infrun.c b/gdb/infrun.c index 885e3257db7..a3cbd744ded 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1091,6 +1091,11 @@ set_schedlock_func (char *args, int from_tty, struct cmd_list_element *c) } } +/* True if execution commands resume all threads of all processes by + default; otherwise, resume only threads of the current inferior + process. */ +int sched_multi = 0; + /* Try to setup for software single stepping over the specified location. Return 1 if target_resume() should use hardware single step. @@ -1201,13 +1206,25 @@ a command like `return' or `jump' to continue execution.")); { ptid_t resume_ptid; - resume_ptid = RESUME_ALL; /* Default */ - /* If STEP is set, it's a request to use hardware stepping facilities. But in that case, we should never use singlestep breakpoint. */ gdb_assert (!(singlestep_breakpoints_inserted_p && step)); + /* Decide the set of threads to ask the target to resume. Start + by assuming everything will be resumed, than narrow the set + by applying increasingly restricting conditions. */ + + /* By default, resume all threads of all processes. */ + resume_ptid = RESUME_ALL; + + /* Maybe resume only all threads of the current process. */ + if (!sched_multi && target_supports_multi_process ()) + { + resume_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid)); + } + + /* Maybe resume a single thread after all. */ if (singlestep_breakpoints_inserted_p && stepping_past_singlestep_breakpoint) { @@ -1224,9 +1241,8 @@ a command like `return' or `jump' to continue execution.")); to support, and has no value. */ resume_ptid = inferior_ptid; } - - if ((step || singlestep_breakpoints_inserted_p) - && tp->trap_expected) + else if ((step || singlestep_breakpoints_inserted_p) + && tp->trap_expected) { /* We're allowing a thread to run past a breakpoint it has hit, by single-stepping the thread with the breakpoint @@ -1240,8 +1256,7 @@ a command like `return' or `jump' to continue execution.")); breakpoint, not just the one at PC. */ resume_ptid = inferior_ptid; } - - if (non_stop) + else if (non_stop) { /* With non-stop mode on, threads are always handled individually. */ @@ -1394,11 +1409,19 @@ prepare_to_proceed (int step) || (scheduler_mode == schedlock_step && step)); + /* Don't switch over to WAIT_PTID if scheduler locking is on. */ + if (schedlock_enabled) + return 0; + + /* Don't switch over if we're about to resume some other process + other than WAIT_PTID's, and schedule-multiple is off. */ + if (!sched_multi + && ptid_get_pid (wait_ptid) != ptid_get_pid (inferior_ptid)) + return 0; + /* Switched over from WAIT_PID. */ if (!ptid_equal (wait_ptid, minus_one_ptid) - && !ptid_equal (inferior_ptid, wait_ptid) - /* Don't single step WAIT_PID if scheduler locking is on. */ - && !schedlock_enabled) + && !ptid_equal (inferior_ptid, wait_ptid)) { struct regcache *regcache = get_thread_regcache (wait_ptid); @@ -5567,6 +5590,13 @@ show_non_stop (struct ui_file *file, int from_tty, value); } +static void +show_schedule_multiple (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("\ +Resuming the execution of threads of all processes is %s.\n"), value); +} void _initialize_infrun (void) @@ -5746,6 +5776,18 @@ step == scheduler locked during every single-step operation.\n\ show_scheduler_mode, &setlist, &showlist); + add_setshow_boolean_cmd ("schedule-multiple", class_run, &sched_multi, _("\ +Set mode for resuming threads of all processes."), _("\ +Show mode for resuming threads of all processes."), _("\ +When on, execution commands (such as 'continue' or 'next') resume all\n\ +threads of all processes. When off (which is the default), execution\n\ +commands only resume the threads of the current process. The set of\n\ +threads that are resumed is further refined by the scheduler-locking\n\ +mode (see help set scheduler-locking)."), + NULL, + show_schedule_multiple, + &setlist, &showlist); + add_setshow_boolean_cmd ("step-mode", class_run, &step_stop_if_no_debug, _("\ Set mode of the step operation."), _("\ Show mode of the step operation."), _("\ -- 2.30.2