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
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.
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
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.