Bug 27770 - crash with interpreter-exec
Summary: crash with interpreter-exec
Status: NEW
Alias: None
Product: gdb
Classification: Unclassified
Component: mi (show other bugs)
Version: 10.1
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-04-23 15:22 UTC by Tom Tromey
Modified: 2023-12-14 06:37 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Tromey 2021-04-23 15:22:01 UTC
In bug #27757, we found out that an interpreter-exec command
using a different MI version caused a crash.
The primary problem in that bug was fixed, but I think the
crash deserves its own bug.
See that bug for reproducer instructions, especially comment #4
Comment 1 Tom Tromey 2022-08-12 18:26:09 UTC
It's as simple as:

$ gdb -nx -i=mi3
...
-interpreter-exec mi2 "-data-evaluate-expression 23"

That is, using different versions of MI at the same time.
Comment 2 vimacs.hacks@gmail.com 2023-05-16 06:04:12 UTC
I encountered the same problem when trying to use GDB in Eclipse (hardcoded to mi2). I use valgrind to debug this problem, and found mi->raw_stdout is uninitialised:

# start gdbserver with "gdbserver :9999 /bin/ls"

$ valgrind ./gdb/gdb --interpreter=mi2
...
GNU gdb (GDB) 14.0.50.20230516-git
...
1-target-select remote 127.0.0.1:9999
...
2-interpreter-exec mi "monitor set debug 1"
&"monitor set debug 1\n"
@"Debug output enabled.\n"
==80114== Use of uninitialised value of size 8
==80114==    at 0x9CA8BB: gdb_puts(char const*, ui_file*) (utils.c:1812)
==80114==    by 0x6DD25C: captured_mi_execute_command(ui_out*, mi_parse*) (mi-main.c:1867)
==80114==    by 0x6DD573: mi_execute_command(char const*, int) (mi-main.c:1942)
==80114==    by 0x6C5B29: mi_execute_command_wrapper(char const*) (mi-interp.c:274)
==80114==    by 0x6C5919: mi_interp::exec(char const*) (mi-interp.c:204)
==80114==    by 0x62D0E0: interp_exec(interp*, char const*) (interps.c:293)
==80114==    by 0x6C5A4C: mi_cmd_interpreter_exec(char const*, char**, int) (mi-interp.c:241)
==80114==    by 0x6C2480: mi_command_mi::invoke(mi_parse*) const (mi-cmds.c:58)
==80114==    by 0x6DDC65: mi_cmd_execute(mi_parse*) (mi-main.c:2114)
==80114==    by 0x6DD0AA: captured_mi_execute_command(ui_out*, mi_parse*) (mi-main.c:1818)
==80114==    by 0x6DD573: mi_execute_command(char const*, int) (mi-main.c:1942)
==80114==    by 0x6C5B29: mi_execute_command_wrapper(char const*) (mi-interp.c:274)
==80114== 
==80114== Invalid read of size 8
==80114==    at 0x9CA8BB: gdb_puts(char const*, ui_file*) (utils.c:1812)
==80114==    by 0x6DD25C: captured_mi_execute_command(ui_out*, mi_parse*) (mi-main.c:1867)
==80114==    by 0x6DD573: mi_execute_command(char const*, int) (mi-main.c:1942)
==80114==    by 0x6C5B29: mi_execute_command_wrapper(char const*) (mi-interp.c:274)
==80114==    by 0x6C5919: mi_interp::exec(char const*) (mi-interp.c:204)
==80114==    by 0x62D0E0: interp_exec(interp*, char const*) (interps.c:293)
==80114==    by 0x6C5A4C: mi_cmd_interpreter_exec(char const*, char**, int) (mi-interp.c:241)
==80114==    by 0x6C2480: mi_command_mi::invoke(mi_parse*) const (mi-cmds.c:58)
==80114==    by 0x6DDC65: mi_cmd_execute(mi_parse*) (mi-main.c:2114)
==80114==    by 0x6DD0AA: captured_mi_execute_command(ui_out*, mi_parse*) (mi-main.c:1818)
==80114==    by 0x6DD573: mi_execute_command(char const*, int) (mi-main.c:1942)
==80114==    by 0x6C5B29: mi_execute_command_wrapper(char const*) (mi-interp.c:274)
==80114==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
Comment 3 vimacs.hacks@gmail.com 2023-12-14 06:37:47 UTC
I seem to know why this can crash. In the following code:

std::unique_ptr<mi_ui_out>
mi_out_new (const char *mi_version)
{
  if (streq (mi_version, INTERP_MI4) ||  streq (mi_version, INTERP_MI))
    return std::make_unique<mi_ui_out> (4);

  if (streq (mi_version, INTERP_MI3))
    return std::make_unique<mi_ui_out> (3);

  if (streq (mi_version, INTERP_MI2))
    return std::make_unique<mi_ui_out> (2);

  return nullptr;
}

Different MI version makes a different mi_ui_out, so when -interpreter-exec gives a different version than the one in command line, the ui_out object cannot be found.