Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Guinevere Larsen <guinevere@redhat.com>
To: Andrew Burgess <aburgess@redhat.com>, gdb-patches@sourceware.org
Subject: Re: [PATCHv2] gdb: notify of inferior switch when needed from 'thread' command
Date: Tue, 17 Mar 2026 16:41:07 -0300	[thread overview]
Message-ID: <93ef9c09-1269-43ae-aa3f-28aff7aadaa1@redhat.com> (raw)
In-Reply-To: <106ee09a80eac0dcc72d134dbf02f567de7163ce.1769435821.git.aburgess@redhat.com>

On 1/26/26 10:58 AM, Andrew Burgess wrote:
> In v2:
>
>    - Rebased and retested.
>
>    - Reworked commit message to try and address Pedro's concerns.
>
> Thanks,
> Andrew
>
> ---

Hi Andrew!

I've taken a look at this patch and it looks pretty good, and I think it 
is a good change.

I know you're waiting for Pedro's feedback, but hopefully this message 
acts as a ping for him as well as a review for you

Reviewed-By: Guinevere Larsen <guinevere@redhat.com>

>
> While working on the commit:
>
>    commit 9959019545d8d6d71d927f20f088efba944b1e9c
>    Date:   Sun Sep 28 16:16:53 2025 +0100
>
>        gdb: fix for 'set suppress-cli-notifications on' missed case
>
> I spotted this message in the gdb.mi/user-selected-context-sync.exp
> test script:
>
>    # Idea for the future: selecting a thread in a different inferior.  For now,
>    # GDB doesn't show an inferior switch, but if it did, it would be a nice
>    # place to test it.
>
> What this message is talking about is this behaviour:
>
>    (gdb) info threads
>      Id   Target Id                              Frame
>      1.1  Thread 0xf7dbc700 (LWP 818430) "thr" 0xf7eb2888 in clone () from /lib/libc.so.6
>      1.2  Thread 0xf7dbbb40 (LWP 818433) "thr" 0xf7fd0579 in __kernel_vsyscall ()
>      1.3  Thread 0xf73ffb40 (LWP 818434) "thr" breakpt () at thr.c:19
>      2.1  Thread 0xf7dbc700 (LWP 818456) "thr" 0xf7eb2888 in clone () from /lib/libc.so.6
>      2.2  Thread 0xf7dbbb40 (LWP 818457) "thr" breakpt () at thr.c:19
>    * 2.3  Thread 0xf73ffb40 (LWP 818458) "thr" breakpt () at thr.c:19
>    (gdb) inferior 1
>    [Switching to inferior 1 [process 818430] (/home/andrew/tmp/thr)]
>    [Switching to thread 1.1 (Thread 0xf7dbc700 (LWP 818430))]
>    #0  0xf7eb2888 in clone () from /lib/libc.so.6
>    (gdb) thread 2.2
>    [Switching to thread 2.2 (Thread 0xf7dbbb40 (LWP 818457))]
>    #0  breakpt () at thr.c:19
>    19	  while (stop)
>    (gdb)
>
> Notice that when we switch from thread 2.3 to 1.1 using the 'inferior
> 1' command, GDB tells us that the inferior has changed, and that the
> thread has changed (and also that the frame has changed).
>
> But, when we switch from 1.1 to 2.2 using the 'thread 2.2' command, we
> are only told about the thread change.
>
> The 'Switching to inferior ...' line includes some useful information,
> the process PID and the executable name, and I think it is a shame
> that these are not presented when using the 'thread' command to switch
> inferior.
>
> So, this commit addresses this issue.
>
> A question that came up during review, and which I'm clarifying here:
> this change only effects the output of GDB when the thread command is
> also used to switch inferiors.  I am (in effect) arguing that the
> command 'thread 2.2' should be treated as a shorthand for 'inferior 2;
> thread 2', and should display all of the associated output.  If the
> user is only switching threads within a single inferior then it is not
> necessary to re-display the inferior information.
>
> I acknowledge that this does mean the output of the 'thread' command
> will now be different depending on whether the user changes inferior
> or not.  However, I think this is better than the alternative, having
> the 'thread' command always re-print the inferior information.  I
> think this would introduce excess noise that is not useful.
>
> There are changes in basically two areas.  The easy part is in
> thread_command (thread.c).  Here we spot when the inferior has changed
> as a result of the 'thread' command, and included
> USER_SELECTED_INFERIOR in the set of state passed to the
> notify_user_selected_context_changed function.
>
> The change in mi/mi-main.c is a little more involved.  In the
> mi_cmd_execute function we use an instance of user_selected_context to
> spot if any inferior state (frame, thread, or inferior) changes after
> an MI command, this is then used to decide if there should be a call
> to notify_user_selected_context_changed.
>
> Currently, in mi_cmd_execute, notify_user_selected_context_changed is
> always passed 'USER_SELECTED_THREAD | USER_SELECTED_FRAME'.  This
> makes sense, the MI doesn't allow "switching inferiors" as a command,
> instead, an MI frontend must switch threads, and the inferior is
> switched as a consequence.  But this does mean that if a user has a
> CLI and MI interpreter running, and the MI switches threads, the CLI
> will only receive the thread switch style notifications, that is,
> there will be no "Switching to inferior ..." line.
>
> What I've done is rename user_selected_context::has_changed to
> user_selected_context::what_changed, this function is now responsible
> for returning the set of USER_SELECTED_* flags that indicate what
> changed.
>
> If anything has changed then we always return USER_SELECTED_THREAD |
> USER_SELECTED_FRAME as a minimum.  This retains the existing
> behaviour, but is possibly more aggressive that we need to be; the
> -stack-select-frame command can only change the frame, so maybe in
> this case we should only return USER_SELECTED_FRAME?  I've left that
> for the future though.
>
> However, the important change is that in ::what_changed, I now spot
> when the inferior has changed and include USER_SELECTED_INFERIOR in
> the set of flags that are returned.
>
> In mi_cmd_execute we now call the new what_changed function, and use
> the set of flags returned when calling
> notify_user_selected_context_changed.  This means that the CLI will
> now receive inferior changed notifications when appropriate.
>
> The gdb.mi/user-selected-context-sync.exp script has been updated,
> replacing the comment I quoted above with an actual test that the
> inferior change is announced correctly.
> ---
>   gdb/mi/mi-main.c                              | 44 ++++++++++++---
>   .../gdb.mi/user-selected-context-sync.exp     | 56 ++++++++++++++++---
>   gdb/thread.c                                  | 13 ++++-
>   3 files changed, 93 insertions(+), 20 deletions(-)
>
> diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
> index 77e56bc9fc8..a18209366ff 100644
> --- a/gdb/mi/mi-main.c
> +++ b/gdb/mi/mi-main.c
> @@ -538,6 +538,11 @@ mi_cmd_thread_select (const char *command, const char *const *argv, int argc)
>   
>     thread_select (argv[0], thr);
>   
> +  /* We don't call print_selected_inferior here as this never prints
> +     anything when the output is MI like (as it is now).  MI consumers are
> +     expected to derive the inferior change from the global thread-id
> +     included in the print_selected_thread_frame output.  */
> +
>     print_selected_thread_frame (current_uiout,
>   			       USER_SELECTED_THREAD | USER_SELECTED_FRAME);
>   }
> @@ -1968,12 +1973,30 @@ struct user_selected_context
>   
>     /* Return true if the user selected context has changed since this object
>        was created.  */
> -  bool has_changed () const
> +  user_selected_what what_changed () const
>     {
> +    /* If anything changed then we report both the thread and frame at a
> +       minimum.  We optionally add the inferior if we know that it
> +       changed.
> +
> +       This means that for pure frame changes, e.g. -stack-select-frame, we
> +       still report both a thread and a frame, which isn't ideal, but
> +       there's also the cases where -thread-select is used to re-select the
> +       current thread, in this case we'd still like to see the thread
> +       reported, at least, that's what we have historically done.  */
> +    user_selected_what state
> +      = USER_SELECTED_THREAD | USER_SELECTED_FRAME;
> +
>       /* Did the selected thread change?  */
>       if (m_previous_ptid != null_ptid && inferior_ptid != null_ptid
>   	&& m_previous_ptid != inferior_ptid)
> -      return true;
> +      {
> +	/* Did the inferior change too?  */
> +	if (m_previous_ptid.pid () != inferior_ptid.pid ())
> +	  state |= USER_SELECTED_INFERIOR;
> +
> +	return state;
> +      }
>   
>       /* Grab details of the currently selected frame, for comparison.  */
>       frame_id current_frame_id;
> @@ -1982,7 +2005,7 @@ struct user_selected_context
>   
>       /* Did the selected frame level change?  */
>       if (current_frame_level != m_previous_frame_level)
> -      return true;
> +      return state;
>   
>       /* Did the selected frame id change?  If the innermost frame is
>          selected then the level will be -1, and the frame-id will be
> @@ -1991,10 +2014,10 @@ struct user_selected_context
>          other than the innermost frame selected.  */
>       if (current_frame_level != -1
>   	&& current_frame_id != m_previous_frame_id)
> -      return true;
> +      return state;
>   
>       /* Nothing changed!  */
> -    return false;
> +    return 0;
>     }
>   private:
>     /* The previously selected thread.  This might be null_ptid if there was
> @@ -2098,10 +2121,13 @@ mi_cmd_execute (struct mi_parse *parse)
>   
>     parse->cmd->invoke (parse);
>   
> -  if (!parse->cmd->preserve_user_selected_context ()
> -      && current_user_selected_context.has_changed ())
> -    interps_notify_user_selected_context_changed
> -      (USER_SELECTED_THREAD | USER_SELECTED_FRAME);
> +  if (!parse->cmd->preserve_user_selected_context ())
> +    {
> +      user_selected_what what
> +	= current_user_selected_context.what_changed ();
> +      if (what != 0)
> +	notify_user_selected_context_changed (what);
> +    }
>   }
>   
>   /* See mi-main.h.  */
> diff --git a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
> index 3434ffa2a46..4f02b950f6e 100644
> --- a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
> +++ b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
> @@ -698,9 +698,21 @@ proc_with_prefix test_cli_thread { mode } {
>   	}
>       }
>   
> -    # Idea for the future: selecting a thread in a different inferior.  For now,
> -    # GDB doesn't show an inferior switch, but if it did, it would be a nice
> -    # place to test it.
> +    with_test_prefix "thread 2.2" {
> +	# Select a thread in a different inferior.  This should trigger an
> +	# 'inferior changed' and 'thread changed' notification on the CLI,
> +	# and a single MI async notification.
> +	set mi_re [make_mi_re $mode 5 0 event]
> +	set cli_re [make_cli_re $mode 2 2.2 0]
> +
> +	with_spawn_id $gdb_main_spawn_id {
> +	    gdb_test "thread 2.2" $cli_re "select thread"
> +	}
> +
> +	with_spawn_id $mi_spawn_id {
> +	    match_re_or_ensure_no_output $mi_re "select thread, event on MI"
> +	}
> +    }
>   }
>   
>   # Test frame selection from CLI.
> @@ -995,9 +1007,22 @@ proc_with_prefix test_mi_thread_select { mode } {
>   	}
>       }
>   
> -    # Idea for the future: selecting a thread in a different inferior.  For now,
> -    # GDB doesn't show an inferior switch, but if it did, it would be a nice
> -    # place to test it.
> +    with_test_prefix "thread 2.2" {
> +	# Select a thread in a different inferior.  This should trigger an
> +	# 'inferior changed' and 'thread changed' notification on the CLI,
> +	# and a single MI async notification.
> +	set mi_re [make_mi_re $mode 5 0 response]
> +	set cli_re [make_cli_re $mode 2 2.2 0]
> +
> +	with_spawn_id $mi_spawn_id {
> +	    mi_gdb_test "-thread-select 5" $mi_re "-thread-select"
> +	}
> +
> +	with_spawn_id $gdb_main_spawn_id {
> +	    match_re_or_ensure_no_output "$cli_re\r\n" "-thread-select, event on CLI"
> +	}
> +
> +    }
>   }
>   
>   proc_with_prefix test_mi_stack_select_frame { mode } {
> @@ -1290,9 +1315,22 @@ proc_with_prefix test_cli_in_mi_thread { mode cli_in_mi_mode } {
>   	}
>       }
>   
> -    # Idea for the future: selecting a thread in a different inferior.  For now,
> -    # GDB doesn't show an inferior switch, but if it did, it would be a nice
> -    # place to test it.
> +    with_test_prefix "thread 2.2" {
> +	# Select a thread in a different inferior.  This should trigger an
> +	# 'inferior changed' and 'thread changed' notification on the CLI,
> +	# and a single MI async notification.
> +	set command [make_cli_in_mi_command $cli_in_mi_mode "thread 2.2"]
> +	set mi_re [make_cli_in_mi_re $command $cli_in_mi_mode $mode 1 2 2.2 5 0]
> +	set cli_re [make_cli_re $mode 2 2.2 0]
> +
> +	with_spawn_id $mi_spawn_id {
> +	    mi_gdb_test $command $mi_re "select thread"
> +	}
> +
> +	with_spawn_id $gdb_main_spawn_id {
> +	    match_re_or_ensure_no_output "$cli_re\r\n" "select thread, event on CLI"
> +	}
> +    }
>   }
>   
>   # Test selecting the frame using a CLI command in the MI channel.
> diff --git a/gdb/thread.c b/gdb/thread.c
> index 0788bea235a..9ca1a8d973a 100644
> --- a/gdb/thread.c
> +++ b/gdb/thread.c
> @@ -1983,10 +1983,19 @@ thread_command (const char *tidstr, int from_tty)
>       }
>     else
>       {
> +      inferior *previous_inferior = current_inferior ();
> +
>         thread_select (tidstr, parse_thread_id (tidstr, NULL));
>   
> -      notify_user_selected_context_changed
> -	(USER_SELECTED_THREAD | USER_SELECTED_FRAME);
> +      user_selected_what selection = (USER_SELECTED_THREAD
> +				      | USER_SELECTED_FRAME);
> +
> +      /* If the inferior changed as a consequence of the thread change,
> +	 then let the user know.  */
> +      if (previous_inferior != current_inferior ())
> +	selection |= USER_SELECTED_INFERIOR;
> +
> +      notify_user_selected_context_changed (selection);
>       }
>   }
>   
>
> base-commit: 449035c35f2169e0c690d83f28306275ab7f7463


-- 
Cheers,
Guinevere Larsen
It/she


  reply	other threads:[~2026-03-17 19:41 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-08  8:48 [PATCH] " Andrew Burgess
2025-10-09 18:59 ` Pedro Alves
2025-10-10 14:47   ` Andrew Burgess
2025-11-03 16:12     ` Aktemur, Tankut Baris
2025-11-03 17:57       ` Andrew Burgess
2026-01-06 13:37     ` Andrew Burgess
2026-01-26 13:58 ` [PATCHv2] " Andrew Burgess
2026-03-17 19:41   ` Guinevere Larsen [this message]
2026-03-18 14:34     ` Andrew Burgess
2026-04-17 14:54   ` [PATCHv3] " 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=93ef9c09-1269-43ae-aa3f-28aff7aadaa1@redhat.com \
    --to=guinevere@redhat.com \
    --cc=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /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