From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 54724 invoked by alias); 27 Jun 2019 15:43:14 -0000 Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org Received: (qmail 54716 invoked by uid 89); 27 Jun 2019 15:43:14 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,HTML_MESSAGE autolearn=ham version=3.3.1 spammy=solo, STEP, HX-Envelope-From:sk:natalia, incompatibility X-HELO: mga11.intel.com Received: from mga11.intel.com (HELO mga11.intel.com) (192.55.52.93) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 27 Jun 2019 15:43:11 +0000 Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Jun 2019 08:43:09 -0700 Received: from irsmsx109.ger.corp.intel.com ([163.33.3.23]) by fmsmga004.fm.intel.com with ESMTP; 27 Jun 2019 08:43:08 -0700 Received: from irsmsx106.ger.corp.intel.com ([169.254.8.222]) by IRSMSX109.ger.corp.intel.com ([169.254.13.220]) with mapi id 14.03.0439.000; Thu, 27 Jun 2019 16:43:07 +0100 From: "Saiapova, Natalia" To: "gdb@sourceware.org" CC: "Metzger, Markus T" Subject: Proposal: scheduler-locking during inferior calls Date: Thu, 27 Jun 2019 15:43:00 -0000 Message-ID: <0684A59A727D094BB8A375CE8D2ED8A963F66B75@IRSMSX106.ger.corp.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2019-06/txt/msg00070.txt.bz2 Dear All, In multithreaded program, when several threads are stopped at a breakpoint = and scheduler-locking mode is not 'on', there might be unexpected thread switch= es during an inferior call evaluation. If such thread switching occurs, the evaluation of the inferior call is abandoned: ~~~ (gdb) run Thread 1 "a.out" hit Breakpoint 2, main._omp_fn.0(void) () at multi-omp.cpp= :18 18 std::cout << omp_get_thread_num(= ); (gdb) call do_something() [Switching to Thread 0x7ffff6327700 (LWP 32498)] Thread 3 "a.out" hit Breakpoint 2, main._omp_fn.0(void) () at multi-omp.cpp= :18 18 std::cout << omp_get_thread_num(= ); The program stopped in another thread while making a function call from GDB. Evaluation of the expression containing the function (do_something()) will be abandoned. When the function is done executing, GDB will silently stop. ~~~ The similar problem happens with stepping commands, however, for these we h= ave 'step' scheduler-locking mode. We could add a new scheduler locking mode th= at will handle inferior calls. But it is highly likely, that this mode would be used together with 'step'. If we blend step locking into the new mode, one might also want to include the replay, and then the number of possible combinations explodes. It does not seem to be flexible and scalable solutio= n. And if the new mode locks only inferior calls, it will not be user-friendly, since then a user will be forced to switch modes during the debugging. I would like to propose a change of existing scheduler-locking mechanism, w= hich will give a user fine-granular control over the scheduler lock. The user wi= ll define his or her own mode based on options that he or she could set independently: ~~~ (gdb) set scheduler-locking step on (gdb) set scheduler-locking eval on (gdb) set scheduler-locking replay on (gdb) set scheduler-locking run off (gdb) show scheduler-locking Scheduler-locking mode: step on eval on replay on run off ~~~ Here 'eval' represents inferior calls, and 'run' represents 'continue' and 'finish' commands. However, these will not be backward compatible with the current 'set/show scheduler-locking' commands. As I am not sure, that pros of this change will outweigh the backward incompatibility, I have added a command 'set scheduler-locking-eval' as a work-around. It toggles scheduler locking for inferior calls and coexists with current scheduler-locking modes (so it could be used together with or without step or replay modes). I would appreciate other opinions about this problem and its possible solut= ions. Here is an example diff for the set scheduler-locking-eval command. ~~~ diff --git a/gdb/infrun.c b/gdb/infrun.c index c2ce532..84fa225 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -2214,6 +2214,12 @@ static const char *const scheduler_enums[] =3D { schedlock_replay, NULL }; + +static struct { + /* If true, scheduler locking is on during inferior calls. */ + int eval =3D 1; +} scheduler_locking; + static const char *scheduler_mode =3D schedlock_replay; static void show_scheduler_mode (struct ui_file *file, int from_tty, @@ -2264,6 +2270,7 @@ ptid_t user_visible_resume_ptid (int step) { ptid_t resume_ptid; + thread_info * tp =3D find_thread_ptid (current_inferior (), inferior_pti= d); if (non_stop) { @@ -2272,7 +2279,8 @@ user_visible_resume_ptid (int step) resume_ptid =3D inferior_ptid; } else if ((scheduler_mode =3D=3D schedlock_on) - || (scheduler_mode =3D=3D schedlock_step && step)) + || (scheduler_mode =3D=3D schedlock_step && step) + || (scheduler_locking.eval && tp->control.in_infcall)) { /* User-settable 'scheduler' mode requires solo thread resume. */ @@ -3021,8 +3029,7 @@ thread_still_needs_step_over (struct thread_info *tp) return what; } -/* Returns true if scheduler locking applies. STEP indicates whether - we're about to do a step/next-like command to a thread. */ +/* Returns true if scheduler locking applies to thread TP. */ static int schedlock_applies (struct thread_info *tp) @@ -3032,7 +3039,8 @@ schedlock_applies (struct thread_info *tp) && tp->control.stepping_command) || (scheduler_mode =3D=3D schedlock_replay && target_record_will_replay (minus_one_ptid, - execution_direction))); + execution_direction)) + || (scheduler_locking.eval && tp->control.in_infcall)); } extern void switch_to_inferior_no_thread (inferior *inf); @@ -9487,6 +9495,13 @@ infrun_async_inferior_event_handler (gdb_client_data= data) inferior_event_handler (INF_REG_EVENT, NULL); } +static void +show_schedlock_eval (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Scheduler locking during function evaluations= is %s.\n"), value); +} + void _initialize_infrun (void) { @@ -9703,6 +9718,16 @@ replay =3D=3D scheduler locked in replay mode and un= locked during normal execution." show_scheduler_mode, &setlist, &showlist); + add_setshow_boolean_cmd ("scheduler-locking-eval", class_run, + &scheduler_locking.eval, _("\ +Set mode for locking scheduler during function evaluation."), _("\ +Show mode for locking scheduler during function evaluation."), _("\ +off =3D=3D no locking (threads may preempt during inferior calls)\n\ +on =3D=3D no thread except the current thread may run during inferior = calls."), + NULL, + show_schedlock_eval, + &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."), _("\ ~~~ --Natalia Intel Deutschland GmbH Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Christin Eisenschmid, Gary Kershaw Chairperson of the Supervisory Board: Nicole Lau Registered Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928