参考:
http://dustymabe.com/2012/10/14/trace-function-calls-using-gdb/
可以使用下面的脚本来把 gdb 作为一个函数跟踪器。
#!/bin/sh
# Make a function call trace using GDB. This is stupid, but it should work
if [ "$*" = "" ]; then
echo âusage: $0 [args]â
exit
fi
_CMDFILE=/tmp/`basename $0`.$$
_PROG=$1
shift
echo "Writing GDB commands file"
# Write the temporary GDB commands file
echo "set args $*" > $_CMDFILE
for i in $(nm -f posix $_PROG | awk '$2 == "T" {print $1}'); do
(echo break $i
echo command
echo silent
echo backtrace 1
echo continue
echo end
echo
) >> $_CMDFILE
done
echo run >> $_CMDFILE
echo q >> $_CMDFILE
# Now do the run
echo Starting GDB
gdb -quiet -command=$_CMDFILE $_PROG
# and clean up
echo GDB run finished
rm -f $_CMDFILE
代码的简单说明:
使用 nm 获取对应程序的函数信息保存到一个临时文件里。
该临时文件会对每一个函数设置断点,并在执行到该断点时打印一下对应的 backtrace ,因为设置成1,所以就打印当前的函数位置信息。
示例如下:
$ sh gdb-trace.sh /tmp/foo
Writing GDB commands file
Starting GDB
Reading symbols from /tmp/foo…done.
Breakpoint 1 at 0x400560
Breakpoint 2 at 0x4004d0
Breakpoint 3 at 0x4005a8
Breakpoint 4 at 0x400390
Breakpoint 5 at 0x4003d0
Breakpoint 6 at 0x4004b8: file foo.c, line 5.
Breakpoint 7 at 0x4004c3: file foo.c, line 10.
#0 _init (argc=1, argv=0x7fffffffde48, envp=0x7fffffffde58) at ../sysdeps/unix/sysv/linux/x86_64/../init-first.c:53
#0 0x00000000004003d0 in _start ()
#0 0x00000000004004d0 in __libc_csu_init ()
#0 0x0000000000400390 in _init ()
#0 main () at foo.c:10
#0 foo () at foo.c:5
#0 0x00000000004005a8 in _fini ()
[Inferior 1 (process 31474) exited normally]
GDB run finished