21

I noticed that in GDB, when issuing commands with long output like info variables, the output is displayed one page at time, pressing enter to go down and q to quit.

Is it possible to replace the default pager with another one, such as less, so that I can navigate up and down, quitting, searching, etc?

AkiRoss
  • 11,745
  • 6
  • 59
  • 86

6 Answers6

10

Is it possible to replace the default pager with another one

No: GDB doesn't call into external program to display the output, it simply pauses the output every screenfull (and you can make it not pause by set height 0).

In addtion to running inside emacs, you could also use screen or tmux (learning them will generally help you in a lot of other situations), or ask GDB to log output (set logging on) and then search in gdb.txt with any $PAGER you want.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • Perfect: I suspected it was something like this, but did not know about the height 0. I am already using `tmux`, so this is the best option! Thanks! – AkiRoss Apr 21 '13 at 15:47
7

Starting with version 9.1, GDB has a pipe command, so you can send a command's output to the pager of your choice. From the documentation:

pipe [command] | shell_command
Executes command and sends its output to shell_command. Note that no space is needed around |. If no command is provided, the last command executed is repeated.

Mark Plotnick
  • 9,598
  • 1
  • 24
  • 40
  • 1
    Any way to get GDB to apply styling when `pipe`'d? So you can get colored output on things like `pipe info threads | less -SR`. – genpfault Feb 02 '22 at 18:54
4

run gdb inside of emacs and you should be able to use emacs' paging commands.

  1. run emacs
  2. type M-x gdb return (M stands for meta - alt key or option on Macs)
  3. The Emacs message bar will now display the message: Run gdb (like this): gdb

More information is available here: http://tedlab.mit.edu/~dr/gdbintro.html

HTH

race_carr
  • 1,387
  • 12
  • 21
4

you can put the following user-defined commands in ~/.gdbinit, then

% cat ~/.gdbinit
python import os
define less1
    python os.popen("less","w").write(gdb.execute("$arg0",to_string=True))
end

define less2
    python os.popen("less","w").write(gdb.execute("$arg0 $arg1",to_string=True))
end
...
% gdb
(gdb) less2 info var
...
(gdb) less1 disass
...
yichun
  • 121
  • 1
  • 7
  • `Traceback (most recent call last): File "", line 1, in NameError: name 'os' is not defined Error while executing Python code.` –  Nov 22 '15 at 08:04
  • Please add "python import os" in your .gdbinit first. – yichun Nov 24 '15 at 14:36
  • 1
    It looks like GDB 8.0 might have changed how `python` and `$arg` interpolation inside a `define` work. Has anyone got this working in GDB 8? – Jeremy Muhlich Aug 15 '18 at 15:40
2

It is a bit old thread, but I think it is worth to add. @yichun gave a very nice idea here, but to be more practical it can be extended to any number of arguments:

define less
    python import os
    python os.popen("less","w").write(gdb.execute(' '.join(["$arg{0}".format(i) for i in range(0, argc)]), to_string=True))
end

Then it can also woth adding exceptions handling and waiting for processes to terminate to avoid keyboard glitches and we have something like that:

% cat ~/.gdbinit
define less

python argc = $argc
python
import os
f = None
try:
    f = os.popen("less","w")
    f.write(gdb.execute(' '.join(["$arg{0}".format(i) for i in range(0, argc)]), to_string=True))
except Exception as e:
    if f:
        f.write(str(e))
    else:
        print (str(e))
finally:
    if f:
        f.close()

end

end
Yuri Nudelman
  • 2,874
  • 2
  • 17
  • 24
2

In gdb 8.1.1 this code in .gdbinit adds the required functionality:

python
import os

class Less(gdb.Command):
    def __init__(self):
        super().__init__("less", gdb.COMMAND_USER, gdb.COMPLETE_COMMAND)

    def invoke(self, argstr, from_tty):

        with os.popen("less","w") as pipe:
            try:
                pipe.write(gdb.execute(argstr, to_string=True))
            except Exception as e:
                pipe.write(str(e))

Less()
end

Usage

(gdb) less info breakpoints
(gdb) less backtrace

Information: Commands In Python.

MiniMax
  • 983
  • 2
  • 8
  • 24