From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25079 invoked by alias); 30 May 2009 10:51:41 -0000 Received: (qmail 25068 invoked by uid 22791); 30 May 2009 10:51:40 -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; Sat, 30 May 2009 10:51:35 +0000 Received: (qmail 20264 invoked from network); 30 May 2009 10:51:32 -0000 Received: from unknown (HELO orlando.local) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 30 May 2009 10:51:32 -0000 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [RFC] Allowing all threads of all|current process(es) to be resumed [new command + docs] Date: Sat, 30 May 2009 10:51:00 -0000 User-Agent: KMail/1.9.10 Cc: Marc Khouzam MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200905301151.52892.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-05/txt/msg00647.txt.bz2 Hi guys, While moving the linux native multi-forks support ("info forks") into the generic multi-inferior framework I've ran into a little snag. Currently, with the generic framework, if GDB is attached to multiple processes, issuing a "continue", "next", etc., makes GDB resume all threads of all processes. But, with the multi-forks framework, GDB only debugs one of the forks at a given time, while leaving the others stopped. E.g., (gdb) set detach-on-fork off (gdb) catch fork Catchpoint 1 (fork) (gdb) r Starting program: /home/pedro/gdb/sspaces/build/gdb/testsuite/gdb.base/foll-fork Catchpoint 1 (forked process 23902), 0x00007ffff789ac4b in fork () from /lib/libc.so.6 (gdb) A 'continue' command here, will only resume the parent process, and leave the child process stopped. This means that moving multi-forks into multi-inferior framework changes its behaviour. If we make execution commands resume only threads of the current inferior, then we're changing the current default for targets making use of the current multi-inferior framework... So, we've got a conflict, and something's got to give. :-/ Both variants are reasonable and which one is right depends on what you're debugging. I'm thinking that the multi-forks behaviour should be the default, as it seems to be less surprising, and, it was here before... So, I've came up with this new command so that the user can select the behaviour desired. This currently only affects all-stop mode. What do you think of this? I'd prefer that GDB had notion of dynamic thread groups, a-la totalview, but I think we're a bit far for that yet, and it sounds like we'd still make use of something like this to affect the defaults. [Marc, you've guessed it, I'm CCing you because this may affect your current eclipse all-stop multi-process support. If this sticks, you'll just need to issue "set schedule-multiple on" once to get the current behaviour.] -- Pedro Alves 2009-05-30 Pedro Alves * gdb.texinfo (All-Stop): Document new 'set schedule-multiple' command. 2009-05-30 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 "schedule-multiple" command. * inferior.h (sched_multi): Declare. --- gdb/doc/gdb.texinfo | 27 +++++++++++++++++++++ gdb/inferior.h | 2 + gdb/infrun.c | 64 +++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 83 insertions(+), 10 deletions(-) Index: src/gdb/doc/gdb.texinfo =================================================================== --- src.orig/gdb/doc/gdb.texinfo 2009-05-30 10:28:15.000000000 +0100 +++ src/gdb/doc/gdb.texinfo 2009-05-30 11:36:02.000000000 +0100 @@ -4650,6 +4650,33 @@ the current thread away from the thread Display the current scheduler locking mode. @end table +@cindex resume multiple processes +By default, @value{GDBN} allows only threads of the current inferior +to run in response to execution commands such as @code{continue}. +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. You can modify @value{GDBN}'s default behavior +by allowing all threads of all inferiors to be scheduled. + +@table @code +@kindex set schedule-multiple +@item set schedule-multiple +@cindex resume multiple processes +Sets the mode for scheduling multiple processes. When set, all +threads of all processes are allowed to run. When not set (which is +the default), only the threads of the current process are schedulable. + +@item show schedule-multiple +Display the current mode for scheduling multiple processes. +@end table + +The final set of threads that are allowed to run by execution commands +is defined by the union of the restrictions implied by both the +@code{schedule-multiple} and @code{scheduler-locking} modes. E.g., if +the @code{schedule-multiple} mode is set to @code{on}, but the +scheduler locking mode is also set to @code{on}, then only the current +thread is made schedulable. + @node Non-Stop Mode @subsection Non-Stop Mode Index: src/gdb/infrun.c =================================================================== --- src.orig/gdb/infrun.c 2009-05-30 01:36:41.000000000 +0100 +++ src/gdb/infrun.c 2009-05-30 11:35:01.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 || step) && 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); @@ -5573,6 +5596,14 @@ 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, + _("Scheduling multiple processes simultaneously is %s.\n"), + value); +} void _initialize_infrun (void) @@ -5752,6 +5783,19 @@ step == scheduler locked during every si show_scheduler_mode, &setlist, &showlist); + add_setshow_boolean_cmd ("schedule-multiple", class_run, &sched_multi, _("\ +Set mode for scheduling multiple processes simultaneously."), _("\ +Show mode for scheduling multiple processes simultaneously."), _("\ +When set, all threads of all processes are affected by execution\n\ +commands (such as e.g., 'continue'). When not set (which is the\n\ +default), only the threads of the current process are made\n\ +schedulable. The set of threads that are resumed is further\n\ +refined by the scheduler-locking mode (see help set\n\ +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-05-30 01:36:12.000000000 +0100 +++ src/gdb/inferior.h 2009-05-30 01:37:18.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. */