Skip to content

2.63 对GDB内部命令的输出进行文本处理

https://scz.617.cn/unix/201805152224.txt

Q:

Solaris的mdb、Windows的cdb,其内部命令的输出可以交由外部命令进行文本处理, 比如:


!

将mdb命令的输出通过惊叹号转向给外部shell命令,以进一步处理。

|

将前一条mdb命令的输出做为后一条mdb命令的输入

::kmem_cache ! egrep vn_cache

.shell -ci "!peb" findstr ImageFile:

*nix的gdb有无类似能力或变通方案?

A: scz 2023-03-31

高版本gdb内置pipe命令

(gdb) help pipe pipe, | Send the output of a gdb command to a shell command. Usage: | [COMMAND] | SHELL_COMMAND Usage: | -d DELIM COMMAND DELIM SHELL_COMMAND Usage: pipe [COMMAND] | SHELL_COMMAND Usage: pipe -d DELIM COMMAND DELIM SHELL_COMMAND

Executes COMMAND and sends its output to SHELL_COMMAND.

The -d option indicates to use the string DELIM to separate COMMAND from SHELL_COMMAND, in alternative to |. This is useful in case COMMAND contains a | character.

With no COMMAND, repeat the last executed command and send its output to SHELL_COMMAND.

(gdb) pipe info proc mappings | grep vdso 0x7ffe2597d000 0x7ffe2597f000 0x2000 0x0 r-xp [vdso]

(gdb) | info proc mappings | grep vdso 0x7ffe2597d000 0x7ffe2597f000 0x2000 0x0 r-xp [vdso]

A: merlin2011 2018-05-15

https://stackoverflow.com/questions/7120673/gdb-pipe-output-of-internal-command-to-the-shell-command

$ vi ShellPipeCommand.py


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 = arg.split( "|", 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()

这个脚本过去只能在Python3上跑,小改了一下,现在同时适用于Python2、3。

$ cat /dev/urandom > /dev/null

$ gdb -q -nx -p $(pgrep -ox cat)

(gdb) show version GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git

(gdb) python print(sys.version) 3.9.1+ (default, Jan 20 2021, 14:49:22) [GCC 10.2.1 20210110]

(gdb) source /tmp/ShellPipeCommand.py

或者

$ gdb -q -nx -x /tmp/ShellPipeCommand.py -p $(pgrep -ox cat)

(gdb) sp info proc mappings | grep vdso 0xb7ef2000 0xb7ef4000 0x2000 0x0 [vdso]

D: scz@nsfocus

不能在GDB之外的Python解释器中直接"import gdb",会报错:

import gdb Traceback (most recent call last): File "", line 1, in ModuleNotFoundError: No module named 'gdb'

只能在GDB中导入gdb模块:

(gdb) py import gdb

为了在GDB中导入gdb模块,无需执行:

python3 -m pip install gdb

$ python3 -m pip list | grep gdb (无输出)