Bug 24956 - backtrace in user-defined command not redirected
Summary: backtrace in user-defined command not redirected
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: 9.1
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-09-02 17:11 UTC by Tom de Vries
Modified: 2020-02-14 13:19 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 de Vries 2019-09-02 17:11:49 UTC
[ 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
...
Comment 1 Tom de Vries 2019-09-02 17:29:01 UTC
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.
Comment 2 Tom de Vries 2019-09-02 17:44:11 UTC
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);
...
Comment 3 Tom de Vries 2019-09-03 09:41:47 UTC
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
...
Comment 4 Tom de Vries 2019-09-05 09:59:57 UTC
(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
Comment 5 Sourceware Commits 2019-11-21 10:03:08 UTC
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
Comment 6 Tom de Vries 2019-11-21 10:04:57 UTC
Patch with fix and test-case update committed, marking resolved-fixed.
Comment 7 Tom de Vries 2020-02-14 13:19:08 UTC
$ git br --contains 65d1cd5f9cbcbb2df0b187cb7623949c1668728f -r \
  | grep "origin/gdb-.*-branch"
  origin/gdb-9-branch

Setting target milestone 9.1.