gdb
Debugging Symbol Table 把编译的二进制代码对应到响应的变量名, 方法名 和 行号. 符号表可以嵌入到二进制程序中或者在一个单独的文件中.
通过 -g 的参数把符号表嵌入到二进制代码中:
gcc -g hello.cc -o hello
# 把 debug 信息分离出来
objcopy --only-keep-debug hello hello.debug
# 或者
cp hello hello.debug
strip --only-keep-debug hello.debug
# 去掉 debug 信息
strip --strip-debug --strip-unneeded hello
# 加入 debug 信息
objcopy --add-gnu-debuglink hello.debug hello
# debug 分离的信息
gdb -s hello.debug -e hello
# 或者 debug 启动之后
gdb
(gdb) exec-file hello
(gdb) symbol-file hello.debug
基本的命令:
file a.out #指定要 debug 的二进制文件
run #启动程序
run 202 "abc" > out.txt # 给要执行的文件参数 并把结果放入 out.txt
break #添加断点到当前行
break myFuction #添加断点到 myFuction
break 5 #添加断点到第五行
break +5 #添加断点到 -> 从当前行往后数5行
info break #查看断点
info threads
watch x == 3 #如果条件满足, 则暂停
delete 5 #删除第五个断点
clear #清除当前函数的断点
continue #继续运行直到下个断点或错误
finish #继续运行直到当前函数结束
step #运行下一行指令, 如果下一行是函数, 直接进入这个函数, 然后暂停
step 5 #运行后边的5条指令
next #运行下一行, 如果下一行是函数, 直接执行完这个函数
print var #打印变量 var 的值
set x = 3 #设置变量 x 的值为3
set x = y #设置变量 x 的值为 y 的值
bt #查看当前栈
up #到上一层帧
down #到下一层帧
stack #查看当前帧
return #从当前函数返回
select-frame 3 #
help list #打印 list 命令帮助
list 210 #打印出当前文件的第210行左右的行代码
list hello.c:43 #打印 hello.c 的第43行左右的代码
list hello.c:test #打印 hello.c 的test 函数
call myFunc() #执行 myFunc 函数
call myFunc(4) #执行 myFunc 函数
call strlen(str) #执行系统函数 strlen
display x #每一步都显示 x 的值
undisplay x #不要再每一步都显示 x 的值
一篇比较好的关于 GDB debug Java native 代码或 JDK 代码的文章:
https://medium.com/@pirogov.alexey/gdb-debug-native-part-of-java-application-c-c-libraries-and-jdk-6593af3b4f3f