[ Since a fix was committed corresponding to a problem report submitted to the mailing list, filing a corresponding PR here, for ease of reference. ] https://sourceware.org/ml/gdb/2017-10/msg00020.html: ... There seems to be a problem with execution of "bt" as part of breakpoint commands in MI mode: the output of "bt" is not shown. What I did was invoke GDB as "gdb -i=mi PROGRAM", then set a breakpoint or a watchpoint in that program, and defined the following as its breakpoint commands: bt end When the breakpoint triggers, I don't see the backtrace. I tried other commands, like "up" and "print SOME-VARIABLE", and they do seem to be executed and the output shown. So why doesn't that happen with "backtrace"? Is it a bug or am I missing something? (FWIW, I also tried using -break-commands, with a similar result: the backtrace is not shown when the breakpoint triggers.) This problem prevents "bt" from being useful in breakpoint commands when running with the Emacs GDB front-end, which uses MI. Thanks in advance for any pointers. ...
Fixed by https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=3a87ae656c283e4f46ddf7d92c06ecb8992c2bf6 : ... Use console uiout when executing breakpoint commands As reported here https://sourceware.org/ml/gdb/2017-10/msg00020.html the output of certain commands, like backtrace, doesn't appear anywhere when it is run as a breakpoint command and when using MI. The reason is that the current_uiout is set to the mi_ui_out while these commands run, whereas we want the output as CLI output. Some commands like "print" work, because they use printf_filtered (gdb_stdout, ...) directly, bypassing the current ui_out. The fix I did is to force setting the cli_uiout as the current_uiout when calling execute_control_command. I am not sure if this is the right way to fix the problem, comments about the approach would be appreciated. I enhanced gdb.mi/mi-break.exp to test the backtrace command. Regtested on the buildbot. gdb/ChangeLog: * cli/cli-script.c (execute_control_command): Rename to ... (execute_control_command_1): ... this. (execute_control_command): New function. gdb/testsuite/ChangeLog: * gdb.mi/mi-break.exp (test_breakpoint_commands): Test backtrace as a breakpoint command. ...
Using the mi-break executable, we can minimally reproduce this (when undoing the fix) on the command line by doing: ... gdb \ -ex "interpreter-exec mi \"-break-insert basics.c:callee2\"" \ -ex "interpreter-exec mi \"-break-commands 1 bt\"" \ -ex "interpreter-exec mi \"-exec-run\"" \ -batch \ outputs/gdb.mi/mi-break/mi-break ...
The master branch has been updated by Tom de Vries <vries@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=65d1cd5f9cbcbb2df0b187cb7623949c1668728f commit 65d1cd5f9cbcbb2df0b187cb7623949c1668728f Author: Tom de Vries <tdevries@suse.de> Date: Thu Nov 21 11:02:27 2019 +0100 [gdb] Only force INTERP_CONSOLE ui_out for breakpoint commands in MI mode The problem reported in PR mi/25055 is that the output of the backtrace command, when executed as breakpoint command does not show when executing using the MI interpreter: ... $ gdb a.out Reading symbols from a.out... (gdb) break main Breakpoint 1 at 0x4003c0: file test.c, line 19. (gdb) commands Type commands for breakpoint(s) 1, one per line. End with a line saying just "end". >bt >end (gdb) interpreter-exec mi "-exec-run" ^done Breakpoint 1, main () at test.c:19 19 return foo (4); (gdb) ... Interestingly, the function print_frame is called twice during -exec-run: - once during tui_on_normal_stop where the ui_out is temporarily set to tui->interp_ui_out (), resulting in the part after the comma in "Breakpoint 1, main () at test.c:19" - once during execute_control_command, where the ui_out is the default for the current interpreter: mi_ui_out, which ignores calls to output text. The commit 3a87ae656c2 "Use console uiout when executing breakpoint commands" fixes the problem by temporarily switching to the ui_out of INTERP_CONSOLE in execute_control_command. This however caused a regression in redirection (escaping '#' using '\' for git commit message convenience): ... $ rm -f gdb.txt; gdb a.out Reading symbols from a.out... (gdb) break main Breakpoint 1 at 0x4003c0: file test.c, line 19. (gdb) commands Type commands for breakpoint(s) 1, one per line. End with a line saying just "end". >bt >end (gdb) set logging redirect on (gdb) set logging on Redirecting output to gdb.txt. Copying debug output to gdb.txt. (gdb) run \#0 main () at test.c:19 (gdb) q A debugging session is active. Inferior 1 [process 22428] will be killed. Quit anyway? (y or n) y $ cat gdb.txt Starting program: /data/gdb_versions/devel/a.out Breakpoint 1, main () at test.c:19 19 return foo (4); ... The problem is that the '#0 main () at test.c:19' ends up in the gdb output output rather than in gdb.txt. This is due to the fact that the redirect is setup for the current ui_out (which is tui->interp_ui_out ()), while the backtrace output is printed to the INTERP_CONSOLE ui_out. Fix this by limiting switching to INTERP_CONSOLE ui_out to when INTERP_MI is active. Tested on x86_64-linux. gdb/ChangeLog: 2019-11-21 Tom de Vries <tdevries@suse.de> PR gdb/24956 * cli/cli-script.c (execute_control_command): Only switch to INTERP_CONSOLE's ui_out when INTERP_MI is active. gdb/testsuite/ChangeLog: 2019-11-21 Tom de Vries <tdevries@suse.de> PR gdb/24956 * gdb.base/ui-redirect.exp: Test output of user-defined command. Change-Id: Id1771e7fcc9496a7d97ec2b2ea6b1487596f1ef7