Re: How to Read Program Architecture from GDB/MI?

Paramjot Oberoi
2016-07-26T06:27:36Z

Thank you for the quick response, it got me down the right track.
Unfortunately simply commenting out that if() won't work for me as the
output will no longer have the GDB/MI request IDs. It would be the
same as if I did "interpreter-exec mi "show architecture." I believe
the correct fix will require some proper planning. I've spent a few
hours looking at GDB's source code and I can't think of a clean way to
implement it.

The core issue is the output from "show architecture" and
"interpreter-exec mi "-gdb-show architecture"" do not match in the
case that the architecture is not set or is set to auto. If you
manually set the architecture ("set architecture i386") the GDB/MI
output is correct. As you mentioned the c->show_value_func
(show_architecture) only gets called for the console output case, and
not for the GDB/MI. It is the source of the difference.

Console output:
(gdb) show architecture
The target architecture is set automatically (currently i386) --->
set_architecture_string is NULL, but output correctly says the target
architecture is auto, and prints out the current architecture
(gdb) set architecture auto
The target architecture is set automatically (currently i386)
(gdb) show architecture
The target architecture is set automatically (currently i386) --->
set_architecture_string is "auto", and prints out the current
architecture

GDB/MI output:
(gdb) interpreter-exec mi "-gdb-show architecture"
^done ---> set_architecture_string is NULL so nothing is output, does
not print out the current architecture
(gdb) set architecture auto
The target architecture is set automatically (currently i386)
(gdb) interpreter-exec mi "-gdb-show architecture"
^done,value="auto" ---> set_architecture_string is "auto", does not
print out the current architecture

c->show_value_func (show_architecture) is what handles the special
logic for having "auto" or uninitialized architectures:

static void
show_architecture (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
if (target_architecture_user == NULL)
fprintf_filtered (file, _("The target architecture is set "
"automatically (currently %s)\n"),
gdbarch_bfd_arch_info (get_current_arch ())->printable_name);
else
fprintf_filtered (file, _("The target architecture is assumed to be %s\n"),
set_architecture_string);
}

There is no such equivalent callback for the GDB/MI case. I can't
think of a way to do this that wouldn't be hackish. One thought was to
modify the if() else to specifically look for this case:

if (ui_out_is_mi_like_p (uiout))
{
if(c->show_value_func == show_architecture)
{
// reimplement the logic of show_architecture() here, but for MI
// we would need to wipe the existing stb because it might already
have the word "auto" in there

}
ui_out_field_stream (uiout, "value", stb);
}
else
{
...
...
}

Again this doesn't seem like a good way to do it. Please let me know
what your thoughts are. Thanks in advance.

On Mon, Jul 25, 2016 at 1:27 PM, dwk <dwks42@gmail.com> wrote:
> This is a bug in gdb/cli/cli-setshow.c. The current code reads
>
> 647 /* FIXME: cagney/2005-02-10: Need to split this in half: code to
> 648 convert the value into a string (esentially the above); and
> 649 code to print the value out. For the latter there should be
> 650 MI and CLI specific versions. */
> 651
> 652 if (ui_out_is_mi_like_p (uiout))
> 653 ui_out_field_stream (uiout, "value", stb);
> 654 else
> 655 {
> 656 char *value = ui_file_xstrdup (stb, NULL);
> 657
> 658 make_cleanup (xfree, value);
> 659 if (c->show_value_func != NULL)
> 660 c->show_value_func (gdb_stdout, from_tty, c, value);
> 661 else
> 662 deprecated_show_value_hack (gdb_stdout, from_tty, c, value);
> 663 }
>
> The if statement is a special case for GDB/MI. It seems to prepare to
> generate a value but then never write anything. My guess is that this
> code was supposed to generate a nicely parsable version of the string. In
> the case of "-gdb-show architecture", there is a c->show_value_func
> (show_architecture) to call which prints "unfriendly" output. I tried
> playing with different code here but the simplest fix seems to be to
> disable the if statement entirely (add 0&& to its test). Then your
> "show architecture" command works correctly.
>
> (gdb) interpreter-exec mi "-gdb-show architecture"
> ~"The target architecture is set automatically (currently i386)\n"
> ^done
> (gdb)
>
> I don't know what cagney was worrying about when this split occurred,
> but given that it was in 2005 it may no longer be an issue. Perhaps
> try disabling the if statement as I suggested and see if other problems
> crop up.
>
> diff --git a/gdb/cli/cli-setshow.c b/gdb/cli/cli-setshow.c
> index eb17158..8d9b691 100644
> --- a/gdb/cli/cli-setshow.c
> +++ b/gdb/cli/cli-setshow.c
> @@ -649,7 +649,7 @@ do_show_command (const char *arg, int from_tty,
> struct cmd_list_element *c)
> code to print the value out. For the latter there should be
> MI and CLI specific versions. */
>
> - if (ui_out_is_mi_like_p (uiout))
> + if (0 && ui_out_is_mi_like_p (uiout))
> ui_out_field_stream (uiout, "value", stb);
> else
> {
>
>
> Cheers.
>
> ~~ dwk
>
> On Mon, Jul 25, 2016 at 1:30 AM, Paramjot Oberoi <paramjot@gmail.com> wrote:
>> Hi all,
>>
>> I am attempting to get the CPU architecture of the currently debugged
>> program via a GDB/MI command. I'm not sure what's I'm doing wrong:
>>
>> Console interpreter looks good:
>> (gdb) show architecture
>> The target architecture is set automatically (currently i386)
>>
>> MI interpreter succeeds without any data:
>> (gdb) interpreter-exec mi "-gdb-show architecture"
>> ^done
>>
>> If I set the arch to auto, then query with MI I get "auto" back...:
>> (gdb) set arch auto
>> The target architecture is set automatically (currently i386)
>> (gdb) interpreter-exec mi "-gdb-show architecture"
>> ^done,value="auto"
>>
>> Any advice on how I can query the architecture in GDB/MI mode? Thanks
>> in advance, I appreciate it.