It is often desirable to parse the output of a gdb
command and then feed it to a following command (pipe).
in the following example, I want to get the start address of ld-linux-x86-64.so.2
and use it as the
second parameter of add-symbol-file
.
Redirect the command output to a file then process the file with what tools you have. and create a gdb file with desirable command inside, source it in.
Here we define the helper functions to capture the output.
##~/.gdbinit ##
define CAPTURE_OUTPUT_BEGIN
set logging overwrite on
set logging file $arg0
set logging on
end
document CAPTURE_OUTPUT_BEGIN
Capture output by logging begin
end
define CAPTURE_OUTPUT_END
set logging off
end
document CAPTURE_OUTPUT_END
Capture output by logging end
end
define CAPTURE_OUTPUT_CLEAN
shell rm $arg0
end
document CAPTURE_OUTPUT_CLEAN
Remove temporary files
end
script to automate the process,
## auto.gdb ##
file main.exe
start
#now add shared library symbols
CAPTURE_OUTPUT_BEGIN _output.tmp
info sharedlibrary
CAPTURE_OUTPUT_END
shell awk '/ld/ {printf("add-symbol-file /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.13.so %s\n", $1);}' _output.tmp > _gdb.tmp
source _gdb.tmp
CAPTURE_OUTPUT_CLEAN _output.tmp
CAPTURE_OUTPUT_CLEAN _gdb.tmp
and execution output,
[hfu@oneiric:plt]$ gdb -q -x auto.gdb
Temporary breakpoint 1 at 0x400678: file main.c, line 4.
Temporary breakpoint 1, main () at main.c:4
4 xyz = 100;
From To Syms Read Shared Object Library
0x00007ffff7ddcaf0 0x00007ffff7df555a Yes (*) /lib64/ld-linux-x86-64.so.2
0x00007ffff7bda500 0x00007ffff7bda628 Yes /home/hfu/codes/plt/libtest.so
0x00007ffff7859b80 0x00007ffff797ff6c Yes /lib/x86_64-linux-gnu/libc.so.6
(*): Shared library is missing debugging information.
add symbol table from file "/usr/lib/debug/lib/x86_64-linux-gnu/ld-2.13.so" at
.text_addr = 0x7ffff7ddcaf0
_dl_runtime_resolve in section .text of /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.13.so
(gdb)
Works, but UGLY …
Scripting gdb is possible with python, but capturing the output of gdb.execute() to a string is only available in gdb 7.2 and later.
script to automate the process,
## auto.py.gdb ##
file main.exe
start
info sharedlibrary
python import gdb
python addr = [e for e in gdb.execute("info sharedlibrary", False, True).splitlines() if e.find("ld") != -1][0].split()[0]
python gdb.execute("add-symbol-file /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.13.so %s" % addr)
info symbol _dl_runtime_resolve
the execution output,
[hfu@oneiric:plt]$ gdb -q -x auto.py.gdb
Temporary breakpoint 1 at 0x400678: file main.c, line 4.
Temporary breakpoint 1, main () at main.c:4
4 xyz = 100;
From To Syms Read Shared Object Library
0x00007ffff7ddcaf0 0x00007ffff7df555a Yes (*) /lib64/ld-linux-x86-64.so.2
0x00007ffff7bda500 0x00007ffff7bda628 Yes /home/hfu/codes/plt/libtest.so
0x00007ffff7859b80 0x00007ffff797ff6c Yes /lib/x86_64-linux-gnu/libc.so.6
(*): Shared library is missing debugging information.
add symbol table from file "/usr/lib/debug/lib/x86_64-linux-gnu/ld-2.13.so" at
.text_addr = 0x7ffff7ddcaf0
_dl_runtime_resolve in section .text of /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.13.so
(gdb)
Looks better…