public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Jan Vrany <jan.vrany@labware.com>
To: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
Subject: Re: [PATCH] MI: PR20684, preserve user selected thread and frame when invoking MI commands
Date: Wed, 14 Apr 2021 16:27:45 +0100	[thread overview]
Message-ID: <7901c56cd5e8d71893038e66b71f7f6d56205b96.camel@labware.com> (raw)
In-Reply-To: <e4a751d5-e7c4-f62c-73a2-c5965aadb434@polymtl.ca>

On Thu, 2021-03-25 at 14:25 -0400, Simon Marchi wrote:
> 
> 
> > 
> > This was problematic for frontends that provide access to CLI
> > because UI
> > may silently change the context for CLI commands (as demonstrated
> > above).
> 
> Hi Jan,
> 
> Sorry for not getting at this sooner, I was away for a while.
> 
> We'll definitely want a test for this, because it's something that
> can
> easily break unexpectedly.

Hi Simon, 

Sorry for not getting at this sooner, this time I was away. 

I have written some tests, though I do not test notifications
when having separate CLI and MI channel. I tried to look at 
user-selected-context-sync.exp but failed to understand how 
it works. 

> 
> One behavior change with this patch is: assuming thread 1 is
> selected,
> if you do:
> 
>     -thread-select --thread 2 3
> 
> Before: thread 3 becomes selected
> After: thread 1 stays selected
> 
> Even though it looks a bit silly, I think we should keep the "before"
> behavior.  An existing frontend may add `--thread X` to every
> command,
> including -thread-select.  So let's say you click on thread 4 in the
> interface, it sends to GDB:
> 
>     -thread-select --thread 4 4
> 
> With this patch, the selection change wouldn't work.

Good catch, thanks! It did not occur to me someone might do that. 
Similar thing may happen for frame and -frame-select. 

The only way fixing it I can think of now is to special-case it like:

@@ -2034,7 +2034,12 @@ mi_cmd_execute (struct mi_parse *parse)
       if (tp->state == THREAD_EXITED)
        error (_("Thread id: %d has terminated"), parse->thread);
 
-      thread_saver.emplace ();
+      /* The -thread-select and -select-frame are the only commands
+         that change the currently selected thread, so do not restore
+         thread after executing any of them.  */
+      if (parse->cmd->argv_func != mi_cmd_thread_select
+         && parse->cmd->argv_func != mi_cmd_stack_select_frame)
+       thread_saver.emplace ();
       switch_to_thread (tp);
     }

This fixes your usecase, but is there a better way? I need to 
think of it. 
 
> 
> > gdb/Changelog
> > 
> >         PR 20684
> >         * gdb/mi/mi-main.c (mi_cmd_execute): Preserve user selected
> > thread
> 
> Remove leading "gdb/".
> 
> >         and frame when invoking MI commands.
> > ---
> >  gdb/ChangeLog    |  6 ++++++
> >  gdb/mi/mi-main.c | 36 +++++++++++++++---------------------
> >  2 files changed, 21 insertions(+), 21 deletions(-)
> > 
> > diff --git a/gdb/ChangeLog b/gdb/ChangeLog
> > index e67668d315c..ea232ff1b3f 100644
> > --- a/gdb/ChangeLog
> > +++ b/gdb/ChangeLog
> > @@ -1,3 +1,9 @@
> > +2021-02-09  Jan Vrany  <jan.vrany@labware.com>
> > +
> > +       PR 20684
> > +       * gdb/mi/mi-main.c (mi_cmd_execute): Preserve user selected
> > thread
> > +       and frame when invoking MI commands.
> > +
> >  2021-02-08  Shahab Vahedi  <shahab@synopsys.com>
> >  
> >         PR tdep/27369
> > diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
> > index 9a14d78e1e2..c5103800314 100644
> > --- a/gdb/mi/mi-main.c
> > +++ b/gdb/mi/mi-main.c
> > @@ -1971,25 +1971,13 @@ mi_execute_command (const char *cmd, int
> > from_tty)
> >              again.  */
> >           && !command_notifies_uscc_observer (command.get ()))
> >         {
> > -         int report_change = 0;
> > -
> > -         if (command->thread == -1)
> > -           {
> > -             report_change = (previous_ptid != null_ptid
> > -                              && inferior_ptid != previous_ptid
> > -                              && inferior_ptid != null_ptid);
> > -           }
> > -         else if (inferior_ptid != null_ptid)
> > -           {
> > -             struct thread_info *ti = inferior_thread ();
> > -
> > -             report_change = (ti->global_num != command->thread);
> > -           }
> > -
> > -         if (report_change)
> > -           {
> > -             gdb::observers::user_selected_context_changed.notify
> > -               (USER_SELECTED_THREAD | USER_SELECTED_FRAME);
> > +         if (command->thread == -1
> > +             && previous_ptid != null_ptid
> > +             && inferior_ptid != previous_ptid
> > +             && inferior_ptid != null_ptid)
> > +            {
> > +              gdb::observers::user_selected_context_changed.notify
> > +                      (USER_SELECTED_THREAD |
> > USER_SELECTED_FRAME);
> 
> Can you explain the what and why of this change?  It's not obvious to
> me.

I actually wrote this patch a long time ago and using it since then,
but I believe the reason for removing 

     else if (inferior_ptid != null_ptid)
       {
         ...
       }


branch was that if --thread is specified, we do not want any
notifications that context has changed. Imagine the currently
selected thread is 1, frontend passes --thread 2 to a command. 
Then 

    report_change = (ti->global_num != command->thread);

will be true (because 1 != 2) and CLI channel (if any) would get
notification which is not what we want [1]

[1]: https://sourceware.org/legacy-ml/gdb/2019-06/msg00057.html

Thanks! 

Jan


      reply	other threads:[~2021-04-14 15:27 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-09 10:08 Jan Vrany
2021-02-23 11:20 ` [PING] " Jan Vrany
2021-03-02 10:36   ` Jan Vrany
2021-03-02 17:39     ` Jonah Graham
2021-03-09 12:04     ` Jan Vrany
2021-03-17 14:47       ` Jan Vrany
2021-03-23 13:31         ` Jan Vrany
2021-03-25 18:25 ` Simon Marchi
2021-04-14 15:27   ` Jan Vrany [this message]

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=7901c56cd5e8d71893038e66b71f7f6d56205b96.camel@labware.com \
    --to=jan.vrany@labware.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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).