MI commands with --thread (--frame?) do not preserve user selected thread / frame

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

MI commands with --thread (--frame?) do not preserve user selected thread / frame

Jan Vrany
Hi,

I was debugging a multithreaded program and realized that using --thread option to
verious MI command silently changes user selected thread - here's an example using
separate UI and CLI chahhel (tested on commit 6f5601c4d0)

Step 1: CLI info thread + info frame
====================================
--- CLI channel
(gdb) info thread
  Id   Target Id                                           Frame
* 1    Thread 0x7ffff7c30740 (LWP 10185) "user-selected-c" main () at /home/jv/Projects/gdb/origin_master/gdb/testsuite/gdb.mi/user-selected-context-sync.c
:60
  2    Thread 0x7ffff7c2f700 (LWP 10186) "user-selected-c" child_sub_function () at /home/jv/Projects/gdb/origin_master/gdb/testsuite/gdb.mi/user-selected-context-sync.c
:30
  3    Thread 0x7ffff742e700 (LWP 10187) "user-selected-c" futex_wait (private=0, expected=0, futex_word=0x555555558084 <barrier+4>) at ../sysdeps/unix/sysv/linux/futex-internal.h
:61
(gdb) info frame
Stack level 0, frame at 0x7fffffffdee0:
 rip = 0x555555555207 in main (/home/jv/Projects/gdb/origin_master/gdb/testsuite/gdb.mi/user-selected-context-sync.c:60); saved rip = 0x7ffff7c5709b
 source language c.
 Arglist at 0x7fffffffded0, args:
 Locals at 0x7fffffffded0, Previous frame's sp is 0x7fffffffdee0
 Saved registers:
  rbp at 0x7fffffffded0, rip at 0x7fffffffded8

--- MI channel
 <no input no output>



Step 2: MI -stack-info-depth --thread 3
=======================================
-- CLI channel
 <no input no output>

--- MI channel
(gdb)
-stack-info-depth --thread 3
^done,depth="6"
(gdb)




Step 3:  CLI info thread + info frame (same as in Step 1)
=========================================================
-- CLI channel
(gdb) info thread
  Id   Target Id                                           Frame
  1    Thread 0x7ffff7c30740 (LWP 10185) "user-selected-c" main () at /home/jv/Projects/gdb/origin_master/gdb/testsuite/gdb.mi/user-selected-context-sync.c
:60
  2    Thread 0x7ffff7c2f700 (LWP 10186) "user-selected-c" child_sub_function () at /home/jv/Projects/gdb/origin_master/gdb/testsuite/gdb.mi/user-selected-context-sync.c
:30
* 3    Thread 0x7ffff742e700 (LWP 10187) "user-selected-c" futex_wait (private=0, expected=0, futex_word=0x555555558084 <barrier+4>) at ../sysdeps/unix/sysv/linux/futex-internal.h
:61
(gdb) info frame
Stack level 0, frame at 0x7ffff742dee0:
 rip = 0x7ffff7f8612e in futex_wait (../sysdeps/unix/sysv/linux/futex-internal.h:61); saved rip = 0x555555555183
 inlined into frame 1
 source language c.
 Arglist at unknown address.
 Locals at unknown address, Previous frame's sp in rsp
(gdb)  

--- MI channel
 <no input no output>



As you can see, there was no `frame`, `thread`, `-select-frame` or `-thread-select` command between
first and second info thread / frame commands on CLI, yet the selected thread / frame changed (silently).

Is this intended behavior? If so what's the rationale?

Thanks!

Jan

Reply | Threaded
Open this post in threaded view
|

Re: MI commands with --thread (--frame?) do not preserve user selected thread / frame

Jan Vrany
On Wed, 2019-06-19 at 11:53 +0100, Jan Vrany wrote:
> Hi,
>
> I was debugging a multithreaded program and realized that using --thread option to
> verious MI command silently changes user selected thread - here's an example using
> separate UI and CLI chahhel (tested on commit 6f5601c4d0)
>
>
...
>
>
> As you can see, there was no `frame`, `thread`, `-select-frame` or `-thread-select` command between
> first and second info thread / frame commands on CLI, yet the selected thread / frame changed (silently).
>
> Is this intended behavior? If so what's the rationale?
>

Simple patch that preserves user selected context:

---

diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 13c310d494..ac3969f1b4 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -2060,6 +2060,7 @@ mi_cmd_execute (struct mi_parse *parse)
       set_current_program_space (inf->pspace);
     }
 
+  gdb::optional<scoped_restore_current_thread> thread_saver;
   if (parse->thread != -1)
     {
       thread_info *tp = find_thread_global_id (parse->thread);
@@ -2070,9 +2071,11 @@ mi_cmd_execute (struct mi_parse *parse)
       if (tp->state == THREAD_EXITED)
        error (_("Thread id: %d has terminated"), parse->thread);
 
+      thread_saver.emplace ();
       switch_to_thread (tp);
     }
 
+  gdb::optional<scoped_restore_selected_frame> frame_saver;
   if (parse->frame != -1)
     {
       struct frame_info *fid;
@@ -2080,8 +2083,11 @@ mi_cmd_execute (struct mi_parse *parse)
 
       fid = find_relative_frame (get_current_frame (), &frame);
       if (frame == 0)
-       /* find_relative_frame was successful */
-       select_frame (fid);
+        {
+          /* find_relative_frame was successful */
+          frame_saver.emplace ();
+          select_frame (fid);
+        }
       else
        error (_("Invalid frame id: %d"), frame);
     }

Reply | Threaded
Open this post in threaded view
|

Re: MI commands with --thread (--frame?) do not preserve user selected thread / frame

Simon Marchi-4
On 2019-06-19 11:10 a.m., Jan Vrany wrote:

> On Wed, 2019-06-19 at 11:53 +0100, Jan Vrany wrote:
>> Hi,
>>
>> I was debugging a multithreaded program and realized that using --thread option to
>> verious MI command silently changes user selected thread - here's an example using
>> separate UI and CLI chahhel (tested on commit 6f5601c4d0)
>>
>>
> ...
>>
>>
>> As you can see, there was no `frame`, `thread`, `-select-frame` or `-thread-select` command between
>> first and second info thread / frame commands on CLI, yet the selected thread / frame changed (silently).
>>
>> Is this intended behavior? If so what's the rationale?

No, this is indeed a known bug:

https://sourceware.org/bugzilla/show_bug.cgi?id=20684

> Simple patch that preserves user selected context:
>
> ---
>
> diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
> index 13c310d494..ac3969f1b4 100644
> --- a/gdb/mi/mi-main.c
> +++ b/gdb/mi/mi-main.c
> @@ -2060,6 +2060,7 @@ mi_cmd_execute (struct mi_parse *parse)
>        set_current_program_space (inf->pspace);
>      }
>  
> +  gdb::optional<scoped_restore_current_thread> thread_saver;
>    if (parse->thread != -1)
>      {
>        thread_info *tp = find_thread_global_id (parse->thread);
> @@ -2070,9 +2071,11 @@ mi_cmd_execute (struct mi_parse *parse)
>        if (tp->state == THREAD_EXITED)
>         error (_("Thread id: %d has terminated"), parse->thread);
>  
> +      thread_saver.emplace ();
>        switch_to_thread (tp);
>      }
>  
> +  gdb::optional<scoped_restore_selected_frame> frame_saver;
>    if (parse->frame != -1)
>      {
>        struct frame_info *fid;
> @@ -2080,8 +2083,11 @@ mi_cmd_execute (struct mi_parse *parse)
>  
>        fid = find_relative_frame (get_current_frame (), &frame);
>        if (frame == 0)
> -       /* find_relative_frame was successful */
> -       select_frame (fid);
> +        {
> +          /* find_relative_frame was successful */
> +          frame_saver.emplace ();
> +          select_frame (fid);
> +        }
>        else
>         error (_("Invalid frame id: %d"), frame);
>      }
>

This is what I get:

i th
&"i th\n"
~"  Id   Target Id                                          Frame \n"
~"* 1    Thread 0x7f792bce6e40 (LWP 4439) \"gnome-calculato\" 0x00007f7929316bf9 in poll () from /lib/x86_64-linux-gnu/libc.so.6\n"
~"  2    Thread 0x7f791d00b700 (LWP 4441) \"gmain\"           0x00007f7929316bf9 in poll () from /lib/x86_64-linux-gnu/libc.so.6\n"
~"  3    Thread 0x7f791c80a700 (LWP 4442) \"gdbus\"           0x00007f7929316bf9 in poll () from /lib/x86_64-linux-gnu/libc.so.6\n"
~"  4    Thread 0x7f7917981700 (LWP 4443) \"dconf worker\"    0x00007f7929316bf9 in poll () from /lib/x86_64-linux-gnu/libc.so.6\n"
^done
(gdb)
-stack-info-depth --thread 3
^done,depth="7"
~"[Switching to thread 1 (Thread 0x7f792bce6e40 (LWP 4439))]\n"
~"#0  0x00007f7929316bf9 in poll () from /lib/x86_64-linux-gnu/libc.so.6\n"
=thread-selected,id="1",frame={level="0",addr="0x00007f7929316bf9",func="poll",args=[],from="/lib/x86_64-linux-gnu/libc.so.6",arch="i386:x86-64"}
(gdb)
i th
&"i th\n"
~"  Id   Target Id                                          Frame \n"
~"* 1    Thread 0x7f792bce6e40 (LWP 4439) \"gnome-calculato\" 0x00007f7929316bf9 in poll () from /lib/x86_64-linux-gnu/libc.so.6\n"
~"  2    Thread 0x7f791d00b700 (LWP 4441) \"gmain\"           0x00007f7929316bf9 in poll () from /lib/x86_64-linux-gnu/libc.so.6\n"
~"  3    Thread 0x7f791c80a700 (LWP 4442) \"gdbus\"           0x00007f7929316bf9 in poll () from /lib/x86_64-linux-gnu/libc.so.6\n"
~"  4    Thread 0x7f7917981700 (LWP 4443) \"dconf worker\"    0x00007f7929316bf9 in poll () from /lib/x86_64-linux-gnu/libc.so.6\n"
^done
(gdb)

So it seems to work (at least for a simple case, there might be some edge cases I don't recall).  I
think that the CLI and MI events about the thread change should not appear though, since the goal is
to make it appear as if there is no user selection changes.

Simon
Reply | Threaded
Open this post in threaded view
|

Re: MI commands with --thread (--frame?) do not preserve user selected thread / frame

Jan Vrany
On Wed, 2019-06-19 at 11:54 -0400, Simon Marchi wrote:

> On 2019-06-19 11:10 a.m., Jan Vrany wrote:
> > On Wed, 2019-06-19 at 11:53 +0100, Jan Vrany wrote:
> > > Hi,
> > >
> > > I was debugging a multithreaded program and realized that using --thread option to
> > > verious MI command silently changes user selected thread - here's an example using
> > > separate UI and CLI chahhel (tested on commit 6f5601c4d0)
> > >
> > >
> > ...
> > >
> > > As you can see, there was no `frame`, `thread`, `-select-frame` or `-thread-select` command between
> > > first and second info thread / frame commands on CLI, yet the selected thread / frame changed (silently).
> > >
> > > Is this intended behavior? If so what's the rationale?
>
> No, this is indeed a known bug:
>
> https://sourceware.org/bugzilla/show_bug.cgi?id=20684
>

Ah, I see.

> >
> So it seems to work (at least for a simple case, there might be some edge cases I don't recall).  I
> think that the CLI and MI events about the thread change should not appear though, since the goal is
> to make it appear as if there is no user selection changes.

I agree, the event should not be emitted. This was just a quick hack whether
it'd help in my case. If you think this is an acceptable way of "fixing" it,
I'm happy to improve this patch and submit.

Jan

Reply | Threaded
Open this post in threaded view
|

Re: MI commands with --thread (--frame?) do not preserve user selected thread / frame

Simon Marchi-4
On 2019-06-19 12:04 p.m., Jan Vrany wrote:

> On Wed, 2019-06-19 at 11:54 -0400, Simon Marchi wrote:
>> On 2019-06-19 11:10 a.m., Jan Vrany wrote:
>>> On Wed, 2019-06-19 at 11:53 +0100, Jan Vrany wrote:
>>>> Hi,
>>>>
>>>> I was debugging a multithreaded program and realized that using --thread option to
>>>> verious MI command silently changes user selected thread - here's an example using
>>>> separate UI and CLI chahhel (tested on commit 6f5601c4d0)
>>>>
>>>>
>>> ...
>>>>
>>>> As you can see, there was no `frame`, `thread`, `-select-frame` or `-thread-select` command between
>>>> first and second info thread / frame commands on CLI, yet the selected thread / frame changed (silently).
>>>>
>>>> Is this intended behavior? If so what's the rationale?
>>
>> No, this is indeed a known bug:
>>
>> https://sourceware.org/bugzilla/show_bug.cgi?id=20684
>>
>
> Ah, I see.
>
>>>
>> So it seems to work (at least for a simple case, there might be some edge cases I don't recall).  I
>> think that the CLI and MI events about the thread change should not appear though, since the goal is
>> to make it appear as if there is no user selection changes.
>
> I agree, the event should not be emitted. This was just a quick hack whether
> it'd help in my case. If you think this is an acceptable way of "fixing" it,
> I'm happy to improve this patch and submit.
>
> Jan

Note to gdb@, the conversion continues here:

https://sourceware.org/ml/gdb-patches/2019-06/msg00392.html

Simon