GDB 常用命令
info
info process显示进程info thread显示线程info b显示所有断点info locals显示当前临时变量info var显示全局变量及静态变量info watch显示watch状态info display显示autodisplay的信息
debug
b+functionname 设置断点set breakpoint pending on可以避免动态载入库的断点提示clear+b 删除断点del+id 删除断点 www.jianshu.com/p/169e84a79…r/run重启程序start重启程序并且停在mainc/continue继续运行到下一个断点s/step跳进函数n/next单步执行finish结束当前函数q/quit退出程序p+变量名 打印变量return强制当前函数返回bt显示调用栈up/down可以在不同的frame之间切换watch+变量名 当这个变量发生变化时,程序会听着在这里display+变量名 每次运行结束时,自动打印,省去了每次printprint+变量名 检查变量call/print+ functions 强制调函数, 两者有细微的差别list查看当前位置的代码set var XX=xx将某个变量强制赋值
layout
ctrl+x,ctrl+a显示源代码ctrl+x, o可以将焦点在src与调试窗口之间切换refresh/ctrl+l乱码刷新layout src源代码模式layout asm汇编模式layout regs寄存器模式layout split,ctrl+x,1,ctrl+x,2可以组合模式
跟踪子进程
set follow-fork-mode childset follow-fork-mode parent
- 由于gdb只能跟踪一个进程,在程序进程fork的时候,需要选择跟踪父进程还是子进程,选择其中一个(默认父进程 ),另外一个是行为是自由/不受控的。
- 这个可以动态改变,比如程序不断fork到某个child的时候,再设置为parent
attach进程
gdb -p pidgdb && attach to pid
- 可能还需要插入可执行程序的路径。
处理signal
info handle可以看到signal的处理。handle SIGINT stop pass可以进入ctrl c的函数
- stop: 当收到这个信号时,gdb是否stop/break
- print: 当收到这个信号时,gdb是否print message
- pass: gdb 是否允许这个signal传送到相关的程序(这关系到信号处理函数是否被调用)
- Reference: sourceware.org/gdb/onlined…
- Reference: stackoverflow.com/questions/3…
当软件重新编译的时候,gdb的r可以自动运行新程序,但是gdb调试的时候,源文件不会自动重载,需要运行directory命令。 Reference: www.jianshu.com/p/6cdd79ed7…
远程debug
server
gdbserver host:2345 exe arg1 arg2clientgdb exetarget remote hostip:2345
gdb 可以控制程序执行流程,但是输出还是在target的机器上。 gdb server并没有使用安全协议,不能再开放网络使用 gdb server 不需要符号,可以运行strip的二进制,但是gdb client 需要。
自启动命令
- ~/.gdbinit
- ./.gdbinit
- 可以通过
-x指定其他额外的文件,上面两个照样执行-nx可以禁止脚本的自动运行- 防止恶意的脚本执行,需要配置
add-auto-load-safe-path /yourdir/.gdbinit来自动加载local的gdbinit,或者使用set auto-load safe-path /关闭安全检查。 sourceware.org/gdb/onlined…
符号文件
符号文件就是建立(源代码<->汇编指令)的关系,这样便于调试。在windows里为pdb文件,linux里面与二进制集成在一起。
但是符号文件,直接只是映射关系,不包括源代码,例如:0x12345 -> function at main.cpp:10.调试的时候,还是需要源文件的。
lx-symbols
(重新)载入 kernel 以及 loaded module的符号文件。
- 这个moudule需要已经load,这里才会加载它的符号文件。对于gdb而言,需要先在target上执行
insmod abc.ko,然后执行lx-symbols ../- 会对指定目录进行递归检查
dir /directory
可以重新指定目录,并且刷新。