From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21875 invoked by alias); 8 Jun 2009 11:59:05 -0000 Received: (qmail 21506 invoked by uid 22791); 8 Jun 2009 11:59:02 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_37,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 08 Jun 2009 11:58:54 +0000 Received: (qmail 29515 invoked from network); 8 Jun 2009 11:58:51 -0000 Received: from unknown (HELO orlando.local) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 8 Jun 2009 11:58:51 -0000 From: Pedro Alves To: gdb-patches@sourceware.org, Eli Zaretskii Subject: Re: [RFC] Allowing all threads of all|current process(es) to be resumed [new command + docs] Date: Mon, 08 Jun 2009 11:59:00 -0000 User-Agent: KMail/1.9.10 References: <200905301151.52892.pedro@codesourcery.com> <200905301701.53207.pedro@codesourcery.com> <83d49q4is6.fsf@gnu.org> In-Reply-To: <83d49q4is6.fsf@gnu.org> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200906081259.54338.pedro@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-06/txt/msg00169.txt.bz2 On Saturday 30 May 2009 18:12:09, Eli Zaretskii wrote: > Thanks, the new patch for the manual and the NEWS entry are fine with > me, but please consider the two remaining issues mentioned above. Certainly! I'd really like you to be happy with this and here's my next attempt at that. I've given a short example of why you'd want either behaviour; used "resuming the execution", and switched to mentioning the scheduler-locking precedence instead. -- Pedro Alves 2009-06-08 Pedro Alves * gdb.texinfo (All-Stop): Document new 'set schedule-multiple' command. 2009-06-08 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. --- gdb/NEWS | 5 ++++ gdb/doc/gdb.texinfo | 30 +++++++++++++++++++++++++ gdb/inferior.h | 2 + gdb/infrun.c | 62 +++++++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 89 insertions(+), 10 deletions(-) Index: src/gdb/doc/gdb.texinfo =================================================================== --- src.orig/gdb/doc/gdb.texinfo 2009-06-08 12:11:55.000000000 +0100 +++ src/gdb/doc/gdb.texinfo 2009-06-08 12:50:38.000000000 +0100 @@ -4650,6 +4650,36 @@ the current thread away from the thread Display the current scheduler locking mode. @end table +@cindex resume threads of multiple processes simultaneously +By default, @value{GDBN} allows only threads of the current inferior +to run in response to execution commands such as @code{continue}, +@code{next} or @code{step}. E.g., 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 debugging a program that forks, and you want to hold the +fork parent stopped (so that for instance it doesn't run to exit), +while debugging the child. In other ocasions, you are not interested +in inspecting the current state of none of the processes @value{GDBN} +is attached to, and you want to resume them all until any reports a +breakpoint hit. You can modify @value{GDBN}'s default behavior by +instead allowing all threads of all 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 Index: src/gdb/infrun.c =================================================================== --- src.orig/gdb/infrun.c 2009-06-08 12:11:55.000000000 +0100 +++ src/gdb/infrun.c 2009-06-08 12:54:00.000000000 +0100 @@ -1091,6 +1091,11 @@ set_schedlock_func (char *args, int from } } +/* 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 con { 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 con 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 con 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); @@ -5551,6 +5574,13 @@ show_non_stop (struct ui_file *file, int 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) @@ -5730,6 +5760,18 @@ step == scheduler locked during every si 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."), _("\ Index: src/gdb/inferior.h =================================================================== --- src.orig/gdb/inferior.h 2009-06-08 12:11:55.000000000 +0100 +++ src/gdb/inferior.h 2009-06-08 12:11:57.000000000 +0100 @@ -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. */ Index: src/gdb/NEWS =================================================================== --- src.orig/gdb/NEWS 2009-06-08 12:11:55.000000000 +0100 +++ src/gdb/NEWS 2009-06-08 12:11:57.000000000 +0100 @@ -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*