From: "Aktemur, Tankut Baris via Gdb-patches" <gdb-patches@sourceware.org>
To: Andrew Burgess <andrew.burgess@embecosm.com>,
"gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
Subject: RE: [PATCHv4 1/2] gdb: Restore previously selected thread when switching inferior
Date: Mon, 9 Nov 2020 15:02:56 +0000 [thread overview]
Message-ID: <SN6PR11MB289383D7E70CFDF0B8B5F3DCC4EA0@SN6PR11MB2893.namprd11.prod.outlook.com> (raw)
In-Reply-To: <0533d83bd928223a521bd523df9df30c2f68eeed.1604703416.git.andrew.burgess@embecosm.com>
On Saturday, November 7, 2020 12:02 AM, Andrew Burgess wrote:
> This commit adds a new option that allows the user to control how GDB
> behaves when switching between multi-threaded inferiors.
>
> Currently (and this remains the default after this commit) when
> switching between inferiors GDB would select the first non-exited
> thread from the inferior being switched to.
>
> This commit adds the following new commands:
>
> set restore-selected-thread on|off
> show restore-selected-thread
>
> This option is off by default in order to retain the existing
> behaviour, but, when switched on GDB will remember which thread was
> selected in each inferior. As the user switches between inferiors GDB
> will attempt to restore the previously selected thread.
>
> If the previously selected thread is no longer available, for example,
> if the thread has exited, then GDB will fall back on the old
> behaviour.
>
> I did consider, but eventually didn't implemented, adding a warning
> when switching inferiors if the previously selected thread is no
> longer available. My reasoning here is that GDB should already have
> informed the user that the thread has exited, and there is already a
> message indicating which thread has been switched too, so adding an
> extra warning felt like unneeded clutter.
>
> In order to store the thread within the inferior I store a pointer to
> the thread_info object of the previously selected thread. When
> fetching the thread_info it is important that we do actually have a
> current thread otherwise this happens:
>
> $ gdb
> (gdb) add-inferior
> (gdb) inferior 2
> ./gdb/thread.c:95: internal-error: thread_info* inferior_thread(): Assertion
> `current_thread_ != nullptr' failed.
>
> To avoid this I added a check that inferior_ptid is not null_ptid.
> Though it is not always the case, there are plenty of places in GDB
> where a call to inferior_thread () is guarded by such a check.
>
> There's a new test for this functionality.
>
> gdb/ChangeLog:
>
> * inferior.c (inferior_command): Store current thread_info before
> switching inferiors. Reselect the previous thread_info if
> possible after switching to the new inferior.
> (initialize_inferiors): Register restore-selected-thread option.
> * inferior.h (class inferior) <previous_thread_info>: New member
> variable.
> * NEWS: Mention new feature.
>
> gdb/testsuite/ChangeLog:
>
> * gdb.threads/restore-thread.c: New file.
> * gdb.threads/restore-thread.exp: New file.
>
> gdb/doc/ChangeLog:
>
> * gdb.texinfo (Inferiors Connections and Programs): Mention thread
> tracking within the inferior command.
> (Threads): Mention thread tracking in the general thread
> discussion.
> ---
> gdb/ChangeLog | 10 +
> gdb/NEWS | 9 +
> gdb/doc/ChangeLog | 7 +
> gdb/doc/gdb.texinfo | 19 +-
> gdb/inferior.c | 58 ++++-
> gdb/inferior.h | 10 +
> gdb/testsuite/ChangeLog | 5 +
> gdb/testsuite/gdb.threads/restore-thread.c | 248 +++++++++++++++++++
> gdb/testsuite/gdb.threads/restore-thread.exp | 219 ++++++++++++++++
> 9 files changed, 583 insertions(+), 2 deletions(-)
> create mode 100644 gdb/testsuite/gdb.threads/restore-thread.c
> create mode 100644 gdb/testsuite/gdb.threads/restore-thread.exp
>
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 3e08aee7c6f..5a900b8a678 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -27,6 +27,15 @@ set debug event-loop
> show debug event-loop
> Control the display of debug output about GDB's event loop.
>
> +set restore-selected-thread on|off
> +show restore-selected-thread
> + This new option is off by default. When turned on GDB will record
> + the currently selected thread in each inferior. When switching
> + between inferiors GDB will attempt to restore the previously
> + selected thread in the inferior being switched too. If the
> + previously selected thread is no longer available then GDB falls
> + back to selecting the first non-exited thread.
> +
> * Changed commands
>
> break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM]
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index 52701560006..c5819bde7ae 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -3247,11 +3247,25 @@
> To switch focus between inferiors, use the @code{inferior} command:
>
> @table @code
> +@anchor{inferior command}
> @kindex inferior @var{infno}
> @item inferior @var{infno}
> Make inferior number @var{infno} the current inferior. The argument
> @var{infno} is the inferior number assigned by @value{GDBN}, as shown
> in the first field of the @samp{info inferiors} display.
> +
> +When switching between inferiors with multiple threads
> +(@pxref{Threads}) @value{GDBN} will select the first non-exited thread
> +in the inferior being switched to and make this the current thread.
> +
> +@kindex set restore-selected-thread
> +@kindex show restore-selected-thread
> +@item set restore-selected-thread @r{[}on|off@r{]}
> +@item show restore-selected-thread
> +When this option is on @value{GDBN} will record the currently selected
> +thread in each inferior. When switching between inferior @value{GDBN}
> +will try to restore the previously selected thread in the inferior
> +being switched to. This option is off by default.
> @end table
>
> @vindex $_inferior@r{, convenience variable}
> @@ -3633,7 +3647,10 @@
>
> If you're debugging multiple inferiors, @value{GDBN} displays thread
> IDs using the qualified @var{inferior-num}.@var{thread-num} format.
> -Otherwise, only @var{thread-num} is shown.
> +Otherwise, only @var{thread-num} is shown. When switching between
> +inferiors @value{GDBN} will select a suitable thread in the inferior
> +being switched to, see @ref{inferior command,,the @code{inferior}
> +command} for further details on how to control this behaviour.
>
> If you specify the @samp{-gid} option, @value{GDBN} displays a column
> indicating each thread's global thread ID:
> diff --git a/gdb/inferior.c b/gdb/inferior.c
> index d4a783b3e6d..4961bc467fd 100644
> --- a/gdb/inferior.c
> +++ b/gdb/inferior.c
> @@ -631,6 +631,23 @@ switch_to_inferior_no_thread (inferior *inf)
> set_current_program_space (inf->pspace);
> }
>
> +/* When this is true GDB restores the inferiors previously selected thread
"inferiors" -> "inferior's".
I also think that a comma is need after "true".
> + each time the inferior is changed (where possible). */
> +
> +static bool restore_selected_thread_per_inferior = false;
> +
> +/* Implement 'show restore-selected-thread'. */
> +
> +static void
> +show_restore_selected_thread_per_inferior (struct ui_file *file, int from_tty,
> + struct cmd_list_element *c,
> + const char *value)
> +{
> + fprintf_filtered (file,
> + _("Restoring the selected thread is currently %s.\n"),
> + value);
> +}
> +
> static void
> inferior_command (const char *args, int from_tty)
> {
> @@ -643,11 +660,38 @@ inferior_command (const char *args, int from_tty)
> if (inf == NULL)
> error (_("Inferior ID %d not known."), num);
>
> + /* We can only call INFERIOR_THREAD if the inferior is known to have an
> + active thread, which it wont if the inferior is currently exited. So,
> + first check if we currently have a thread selected. */
> + if (inferior_ptid != null_ptid)
> + {
> + /* Now take a strong reference to the current thread_info and store
> + it within the inferior, this prevents the thread_info from being
> + deleted until the inferior has released the reference. */
> + thread_info *tp = inferior_thread ();
> + tp->incref ();
> + current_inferior ()->previous_thread_info.reset (tp);
> + }
> +
> if (inf->pid != 0)
> {
> if (inf != current_inferior ())
> {
> - thread_info *tp = any_thread_of_inferior (inf);
> + thread_info *tp = nullptr;
> +
> + if (restore_selected_thread_per_inferior
> + && inf->previous_thread_info != nullptr)
> + {
> + /* Release the reference to the previous thread. We don't
> + switch back to this thread if it is already exited
> + though. */
> + tp = inf->previous_thread_info.release ();
> + tp->decref ();
> + if (tp->state == THREAD_EXITED)
> + tp = nullptr;
> + }
> + if (tp == nullptr)
> + tp = any_thread_of_inferior (inf);
> if (tp == NULL)
> error (_("Inferior has no threads."));
>
> @@ -1025,5 +1069,17 @@ Show printing of inferior events (such as inferior start and
> exit)."), NULL,
> show_print_inferior_events,
> &setprintlist, &showprintlist);
>
> + add_setshow_boolean_cmd ("restore-selected-thread",
> + no_class, &restore_selected_thread_per_inferior,
> + _("\
> +Set whether GDB restores the selected thread when switching inferiors."), _("\
> +Show whether GDB restores the selected thread when switching inferiors."), _("\
> +When this option is on GDB will record the currently selected thread for\n\
A comma after "on" could improve the sentence, IMHO.
> +each inferior, and restore the selected thread whenever GDB switches inferiors."),
> + nullptr,
> + show_restore_selected_thread_per_inferior,
> + &setlist,
> + &showlist);
> +
> create_internalvar_type_lazy ("_inferior", &inferior_funcs, NULL);
> }
> diff --git a/gdb/inferior.h b/gdb/inferior.h
> index d016161fb05..517180e48e2 100644
> --- a/gdb/inferior.h
> +++ b/gdb/inferior.h
> @@ -543,6 +543,16 @@ class inferior : public refcounted_object
> /* Data related to displaced stepping. */
> displaced_step_inferior_state displaced_step_state;
>
> + /* This field is updated when GDB switches away from this inferior to
> + some other inferior, a reference to a thread_info is stored in here,
It feels like there should be a period after "inferior", instead of a comma, to
end the sentence.
Also, the comment "a reference to a thread_info is stored in here..." is possibly
redundant, because the type "thread_info_ref" implies this.
> + the ref count for the thread_info should be non-zero to prevent the
> + thread_info being deleted.
> +
> + When the user switches back to this inferior the thread_info is taken
> + out of this reference and used to (possibly) switch back to this
> + thread. */
> + thread_info_ref previous_thread_info;
> +
> /* Per inferior data-pointers required by other GDB modules. */
> REGISTRY_FIELDS;
>
Thanks.
-Baris
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
next prev parent reply other threads:[~2020-11-09 15:03 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-25 22:24 [PATCHv3 0/3] Restore thread and frame patches Andrew Burgess
2020-09-25 22:24 ` [PATCHv3 1/3] gdb: unify two copies of restore_selected_frame Andrew Burgess
2020-09-25 22:24 ` [PATCHv3 2/3] gdb: Restore previously selected thread when switching inferior Andrew Burgess
2020-09-26 6:09 ` Eli Zaretskii via Gdb-patches
2020-09-25 22:24 ` [PATCHv3 3/3] gdb: Track the current frame for each thread Andrew Burgess
2020-09-26 6:16 ` Eli Zaretskii via Gdb-patches
2020-09-26 8:31 ` Andreas Schwab
2020-09-26 8:54 ` Eli Zaretskii via Gdb-patches
2020-10-08 9:59 ` [PATCHv3 0/3] Restore thread and frame patches Andrew Burgess
2020-11-06 23:02 ` [PATCHv4 0/2] " Andrew Burgess
2020-11-06 23:02 ` [PATCHv4 1/2] gdb: Restore previously selected thread when switching inferior Andrew Burgess
2020-11-09 15:02 ` Aktemur, Tankut Baris via Gdb-patches [this message]
2020-11-06 23:02 ` [PATCHv4 2/2] gdb: Track the current frame for each thread Andrew Burgess
2020-11-12 11:59 ` [PATCHv5 0/2] Restore thread and frame patches Andrew Burgess
2020-12-10 11:39 ` [PATCHv6 " Andrew Burgess
2020-12-10 11:39 ` [PATCHv6 1/2] gdb: Restore previously selected thread when switching inferior Andrew Burgess
2020-12-10 11:39 ` [PATCHv6 2/2] gdb: Track the current frame for each thread Andrew Burgess
2020-12-18 8:43 ` Aktemur, Tankut Baris via Gdb-patches
2021-01-04 15:07 ` Andrew Burgess
2021-01-04 16:08 ` Eli Zaretskii via Gdb-patches
2021-01-07 10:25 ` [PATCHv6 0/2] Restore thread and frame patches Andrew Burgess
2021-02-12 18:20 ` [PATCHv7 " Andrew Burgess
2021-02-12 18:20 ` [PATCHv7 1/2] gdb: Restore previously selected thread when switching inferior Andrew Burgess
2021-02-12 18:20 ` [PATCHv7 2/2] gdb: Track the current frame for each thread Andrew Burgess
2021-03-23 11:13 ` [PATCHv8] gdb: Restore previously selected thread when switching inferior Andrew Burgess
2021-03-23 11:43 ` Eli Zaretskii via Gdb-patches
2020-11-12 11:59 ` [PATCHv5 1/2] " Andrew Burgess
2020-11-12 11:59 ` [PATCHv5 2/2] gdb: Track the current frame for each thread Andrew Burgess
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=SN6PR11MB289383D7E70CFDF0B8B5F3DCC4EA0@SN6PR11MB2893.namprd11.prod.outlook.com \
--to=gdb-patches@sourceware.org \
--cc=andrew.burgess@embecosm.com \
--cc=tankut.baris.aktemur@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox