## 加载core ```bash gdb oSan core.XXXX ``` ## 调试带命令行参数程序 ```bash gdb --args ./prog arg1 arg2 ``` ## 使用源代码对照调试窗口 在有源代码的环境下,在gdb调试状态,使用ctrl + X,A可以切换到源代码对照调试窗口。 ![gdb](../../../../ff_internal_upload/img/2019/971599436.png) 此时会分上下屏显示源代码和命令窗口,使用以下命令可以将设置当前键盘操作窗口: ```txt (gdb) focus src (gdb) focus cmd ``` ## 冻结当前线程之外其它线程 在多线调试环境时,有时为了单步调试时,避免被其它线程打断,可以冻结其它线程: ```txt (gdb) set scheduler-locking on ``` 解冻其它线程: ```txt (gdb) set scheduler-locking off ``` ## 数据断点 为了跟踪某块内存在是哪里被修改了,可以设置数据断点,例如,假设希望在0x12345678这个4字节的内存区域在被修改时中断,可以: ```txt (gdb) watch *(int*)0x12345678 ``` 那么,当上述4字节内存区域被修改时,触发中断。 ## 条件断点 当指定的条件满足时break。例如,假设希望osan\_lpc\_submit\_io函数在满足p\_io->lunset\_id为0时中断: ```txt (gdb) b osan_lpc_submit_io if p_io->lunset_id==0 ``` ## 格式化显示 按十六进制打印变量val: ```txt (gdb) p/x val ``` #### 打印数组多个元素的值: ```txt (gdb) p *array@len ``` ### 按二进制打印变量val: ```txt (gdb) p/t val ``` #### 格式化打印结构体: ```txt (gdb) set print pretty on ``` ## 反汇编 ```txt (gdb) set disassembly-flavor intel # 使用intel格式,默认为AT&T格式。 (gdb) disassemble main # 反汇编 (gdb) disassemble /m main # 反汇编与源码对照 ``` ## gdb启动时执行调试命令 例如,gdb启动时给main函数打断点“b main”: ```txt gdb ./test -ex "b main" ``` ## gdb启动时执行调试命令脚本 假设有一个脚本文件~/my_gdb,内容如下: ```txt b main b start_fun r ``` ## gdb启动时执行该脚本 ```bash gdb ./test -e ~/my_gdb ``` ## gdbinit(gdb初始化脚本) 分三个级别: ```txt /etc/gdbinit: System-wide initialization file. It is executed unless user specified GDB option "-nx" or "-n". ~/.gdbinit: User initialization file. It is executed unless user specified GDB options "-nx", "-n" or "-nh". ./.gdbinit: Initialization file for current directory. ``` ## gdbinit应用举例 set scheduler-locking on和set scheduler-locking off这样的gdb指令有点长,如果经常使用不太方便,我们可定义一个短一点的命令替代之。 编辑~/.gdbinit文件,增加内容: ```gdb def lkon set scheduler-locking on end def lkoff set scheduler-locking off end ``` 这样以后就可以使用lkon和lkoff代替前面的长命令了。 ## 查看所用线程堆栈信息 ```txt (gdb) thread apply all bt ``` ## 结果输出到文件 ```txt (gdb) set logging file (gdb) set logging on (gdb) 。。。。。。 (gdb) set logging off ``` ## gdb非交互式 ```bash gdb -q --batch --ex "set height 0" --ex "bt" [core] [exe] ``` ## 不分页 ```bash (gdb) set height 0 ``` ## 打印长文本 ```txt (gdb) set print elements 0 (gdb) show print elements ``` ## Dump内存区到文件: ```txt (gdb) dump binary memory <文件名> 内存起始地址 内存结束地址 ``` ## 捕捉异常 ```txt gdb> catch throw catch catch ``` 当异常抛出时中断。 ## 加速gdb调试so时的加载速度 如果gdb index很大,那么gdb调试时,load时间会很长,那么可以在编译时使用以下命令,把gdb index追加到.so文件,这样在gdb调试时,减少了index计算时间。 ```bash gdb-add-index libtest.so ``` 成功后,可以查验新增的段head信息: ```bash [fairyfar@test-4 seaboxmpp2]$ objdump ../node_bin/lib/libvecengined.so -h ../node_bin/lib/libvecengined.so: file format elf64-x86-64 Sections: Idx Name Size VMA LMA File off Algn 0 .note.gnu.build-id 00000024 0000000000000200 0000000000000200 00000200 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .gnu.hash 002c4f74 0000000000000228 0000000000000228 00000228 2**3 …… 33 .gdb_index 0d8a5df2 0000000000000000 0000000000000000 3ad86f2c 2**0 CONTENTS, READONLY, DEBUGGING ``` ## strip 去除release版本程序的符号库。 ```bash strip sql/mysqld ``` ## 禁止gdb截获SIGINT信号 ```txt handle SIGINT nostop print pass ``` ## 刷新TUI 当TUI界面执行到printf时,窗口会错乱,两种方式可以刷新窗口: 一是执行: ``` refresh ``` 二是使用快捷键: Ctrl + L