Michy
Michy

Reputation: 623

gdb - pipe output of internal command to the shell command

Is there any way how to pipe output of internal gdb command to some shell command like grep - the variant of [cmd] ! grep in mdb?

To be more clear: in solaris mdb you can e.g. write

main::dis ! grep call

to detect which functions are called from the main (or grep some register names to see how it is changed). I am interested if there is such possibility to do so just in gdb without necessarity to switching from gdb.

Upvotes: 5

Views: 8092

Answers (3)

Abhijit
Abhijit

Reputation: 344

A new GDB command has been introduced, namely pipe. If you want to process the output of a GDB command using some shell command or some script, that can be done using this new command.

https://sourceware.org/gdb/onlinedocs/gdb/Shell-Commands.html

pipe [command] | shell_command

Upvotes: 4

merlin2011
merlin2011

Reputation: 75555

Seven years later, I still have not found a native way to do this, so I wrote the shell-pipe gdb extension. Its complete source code is replicated here for completeness.

from __future__ import print_function

import gdb
import string
import subprocess
import sys


class ShellPipe (gdb.Command):
    "Command to pipe gdb internal command output to external commands."

    def __init__(self):
        super (ShellPipe, self).__init__("shell-pipe",
                gdb.COMMAND_DATA,
                gdb.COMPLETE_NONE, True)
        gdb.execute("alias -a sp = shell-pipe", True)

    def invoke(self, arg, from_tty):
        arg = arg.strip()
        if arg == "":
            print("Argument required (gdb_command_and_args | externalcommand..).")
            return

        gdb_command, shell_commands = None, None

        if '|' in arg:
            gdb_command, shell_commands = arg.split("|", maxsplit=1)
            gdb_command, shell_commands = gdb_command.strip(), shell_commands.strip()
        else:
            gdb_command = arg

        # Collect the output and feed it through the pipe
        output = gdb.execute(gdb_command, True, True)
        if shell_commands:
            shell_process = subprocess.Popen(shell_commands, stdin=subprocess.PIPE, shell=True)
            shell_process.communicate(output.encode('utf-8'))
        else:
            sys.stdout.write(output)

ShellPipe()

After sourcing ShellPipeCommand.py in $HOME/.gdbinit, one can now pipe internal gdb commands to external shell commands.

    (gdb) shell-pipe disas | grep main
    0x0000000000400527 <+1>:     mov    %rsp,%rbp
    0x000000000040052e <+8>:     movq   $0x4005e4,-0x8(%rbp)
 => 0x0000000000400536 <+16>:    mov    -0x8(%rbp),%rax
    0x000000000040053a <+20>:    mov    %rax,%rdi

Upvotes: 5

Kamath
Kamath

Reputation: 4664

I am not sure if I have understood your question correctly. If you want to a log results of your GDB commands that you ran during a debug session, then Yes there is support for this from GDB.

show logging                    # displays weather logging is on / off
set logging on                  # enable logging
set logging off                 # disable logging
set logging file log-file.txt   # set name for log file, default is gdb.txt

the log file will be generated in your current directory.

Further you can append logs of debug sessions or create new on every debug session using

set logging overwrite <on/off>

Upvotes: 4

Related Questions