[ This may be a duplicate of PR23439 - "backtrace not logging to file from inside breakpoint command". ] Consider this script that does a backtrace from main using a user-defined command mybt: ... $ cat script-mybt.txt set trace-commands on define mybt bt end set logging redirect on set logging on b main r mybt ... Note that the backtrace output ends up in the gdb output, not in the redirected output in the gdb.txt file: ... $ rm -f gdb.txt; ./gdb.sh a.out -batch -x script-mybt.txt; echo "-------"; cat gdb.txt +define mybt +set logging redirect on +set logging on #0 main () at hello.c:9 ------- +b main Breakpoint 1 at 0x40053b: file hello.c, line 9. +r Breakpoint 1, main () at hello.c:9 9 printf ("hello\n"); +mybt ++bt ... If we do the same test using a script that uses the backtrace command instead of the used-defined mybt: ... $ diff -u script-mybt.txt script-bt.txt --- script-mybt.txt 2019-09-02 15:56:39.245123278 +0200 +++ script-bt.txt 2019-09-02 15:38:30.565291000 +0200 @@ -6,4 +6,4 @@ set logging on b main r -mybt +bt ... we get instead the backtrace output in the redirected output in the gdb.txt file: ... $ rm -f gdb.txt; ./gdb.sh a.out -batch -x script-bt.txt; echo "-------"; cat gdb.txt +define mybt +set logging redirect on +set logging on ------- +b main Breakpoint 1 at 0x40053b: file hello.c, line 9. +r Breakpoint 1, main () at hello.c:9 9 printf ("hello\n"); +bt #0 main () at hello.c:9 ...
The problem disappears when building with --disable-tui. With --enable-tui, the main interpreter is INTERP_TUI, and the redirect is setup for INTERP_TUI, but the bt command is parsed in INTERP_CONSOLE mode and that is the reason it doesn't work. With --disable-tui, the main interpreter is INTERP_CONSOLE, so the redirect is setup for INTERP_CONSOLE, and the bt command is parsed in INTERP_CONSOLE mode, and the redirect works.
Tentative patch, fixes the test-case and doesn't regress gdb.tui/*.exp: ... diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c index 4fc9c70259..a5608036f9 100644 --- a/gdb/cli/cli-script.c +++ b/gdb/cli/cli-script.c @@ -1192,12 +1192,22 @@ read_command_lines (const char *prompt_arg, int from_tty, int parse_comm ands, /* Reading commands assumes the CLI behavior, so temporarily override the current interpreter with CLI. */ counted_command_line head (nullptr, command_lines_deleter ()); - if (current_interp_named_p (INTERP_CONSOLE)) + if ( +#if TUI + current_interp_named_p (INTERP_TUI) +#else + current_interp_named_p (INTERP_CONSOLE) +#endif + ) head = read_command_lines_1 (read_next_line, parse_commands, validator); else { +#if TUI + scoped_restore_interp interp_restorer (INTERP_TUI); +#else scoped_restore_interp interp_restorer (INTERP_CONSOLE); +#endif head = read_command_lines_1 (read_next_line, parse_commands, validator); ...
Maybe a better/cleaner approach: ... diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c index ee581a2ff6..29e1f513e7 100644 --- a/gdb/tui/tui-io.c +++ b/gdb/tui/tui-io.c @@ -43,6 +43,7 @@ #include "gdbsupport/filestuff.h" #include "completer.h" #include "gdb_curses.h" +#include "interps.h" #include <map> /* This redefines CTRL if it is not already defined, so it must come @@ -870,7 +871,8 @@ tui_initialize_io (void) tui_out = tui_out_new (tui_stdout); /* Create the default UI. */ - tui_old_uiout = cli_out_new (gdb_stdout); + struct interp *interp = interp_lookup (current_ui, "console"); + tui_old_uiout = (cli_ui_out *)interp->interp_ui_out(); #ifdef TUI_USE_PIPE_FOR_READLINE /* Temporary solution for readline writing to stdout: redirect ...
(In reply to Tom de Vries from comment #3) > Maybe a better/cleaner approach: > ... > diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c > index ee581a2ff6..29e1f513e7 100644 > --- a/gdb/tui/tui-io.c > +++ b/gdb/tui/tui-io.c > @@ -43,6 +43,7 @@ > #include "gdbsupport/filestuff.h" > #include "completer.h" > #include "gdb_curses.h" > +#include "interps.h" > #include <map> > > /* This redefines CTRL if it is not already defined, so it must come > @@ -870,7 +871,8 @@ tui_initialize_io (void) > tui_out = tui_out_new (tui_stdout); > > /* Create the default UI. */ > - tui_old_uiout = cli_out_new (gdb_stdout); > + struct interp *interp = interp_lookup (current_ui, "console"); > + tui_old_uiout = (cli_ui_out *)interp->interp_ui_out(); > > #ifdef TUI_USE_PIPE_FOR_READLINE > /* Temporary solution for readline writing to stdout: redirect > ... submitted: https://sourceware.org/ml/gdb-patches/2019-09/msg00048.html
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
Patch with fix and test-case update committed, marking resolved-fixed.
$ git br --contains 65d1cd5f9cbcbb2df0b187cb7623949c1668728f -r \ | grep "origin/gdb-.*-branch" origin/gdb-9-branch Setting target milestone 9.1.