Bug 25055 - breakpoint command output not visible in MI mode
Summary: breakpoint command output not visible in MI mode
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: mi (show other bugs)
Version: 8.0.1
: P2 normal
Target Milestone: 8.1
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-10-02 08:49 UTC by Tom de Vries
Modified: 2019-11-21 10:03 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-10-02 08:49:08 UTC
[ 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.
...
Comment 1 Tom de Vries 2019-10-02 08:52:26 UTC
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.
...
Comment 2 Tom de Vries 2019-10-02 08:57:45 UTC
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
...
Comment 3 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