贡献者: addis
set print pretty on 或者直接用 IDE。如果调试显示函数不存在,那就是被优化掉了,无解,只能查看数据成员。g++/gcc 编译时用 -g 选项以用于 debug
r,p,f,s,n,ptype(检查 typename 或者变量的类型)
print &变量 可以显示变量地址
p/r 变量 或者 ptype/r 变量 可以输出非常详细的信息。
Ctrl+R 可以搜索之前输入的命令(退出 gdb 后不会保留命令历史)。
std::tuple 时只能按顺序列出每个值,无法直接 get<>() 查看每个元的详情。
catch throw 可以在任何异常发生时暂停
gdb <exename>,无需 ./。也可以先进入 gdb 然后用 file <exename>
file <execname> 即可重新加载,不用退出 gdb,这样可以保留 breakpoint 和其他设置等。但这时 gdb 调试时显示的源码不会更新,要更新,用 directory 或者 directory <源码路径>
gdb -w 开启 gdb 自带 gui, 如果存在。强烈推荐 guigdb 项目(见我的相关笔记),可以在浏览器中显示一个 gdb 的 gui,也支持 intel 的 gdb-ia
quit or q 退出 gdb
catch throw 命令可以在(c++)程序调用 throw 的时候 break
break <line#> (快捷键 b <line#>) 指定主文件的行号设置 breakpoing
break <file>:<line#> 指定文件和行号设置 breakpoing
break 函数名 在函数体第一行设置 breakpoing
break <line#> if i == 99
cond 3 i == 99
info breakpoints 显示所有 breakpoint(快捷键 info b)
run or r 运行程序,遇到 breakpoint 为止
< 输入 input 文件,打开 gdb 的时候不能指定 input 文件,而是在 gdb 内使用 run < inputfle.
gdb --args 程序 参数1 参数2 ...,不确定是否支持 < input。
next(快捷键 n)运行到下一行
step(快捷键 s)进入函数
print <var/expr> (快捷键 p) 来显示某个变量或执行某个命令,只有在没有被优化掉的函数才可以在调试时执行,所以为了使函数可以被执行,可以把函数定义放到单独的 cpp 文件中,而不要用 inline
print 调用的函数不能有默认变量,函数 overload 大部分情况也不行。
print 字符串的时候会打出一堆东西不方便,用 p str.c_str() 和 p str.size() 即可
p 是一个 char *,printf "%s\n", p+2 可以打印 p[2] 和之后的所有字符,printf "%.3s\n", p+2 可以从 p[2] 打印 3 个字符。
where 用于询问当前执行到哪里(等效于 backtrace 即 bt)
list(快捷键 l)显示 10 行周围的代码,反复使用可以连续列出下文代码
continue(快捷键 c),继续运行直到遇到 breakpoint
clear 清除当前行的 breakpoint
delete <number> 清除编号为 <number> 的 breakpoint
delete 清除所有 breakpoint
<break#> <times> to ignore the breakpoint <break#> for <times> times
finish 命令跳出当前函数(快捷键不是 f)
f 可以显示当前的行号和代码
until <number> 执行到指定行
backtrace 或 bt 显示每层正在执行的子程序的信息(stack frame). 这样就可以追踪当前的 function 是被哪一行调用,直到 main() 程序。调用顺序从下到上,数字从大到小。
up 和 down 可以在 stack 中移动,例如 up 可以移动到调用当前函数的函数中,检查那里面的变量。
frame 2 或 f 2 可以直接跳到 bt 显示的第 2 个 frame。frame 可以显示当前在 stack 中的位置。
shell <command> 来输入命令行命令 <command> 而无需退出 gdb 或者暂停程序
make 命令而无需在前面加 shell
-g3 编译,可以打出宏的信息,用 info macro 宏名,也可以直接 p 宏(...) 执行宏函数
-gdb 或者 gdb3 可以输出更加 gdb 友好的调试信息。
call (void) fflush(stdout),可以 flush 命令行输出的 buffer,有时候 cout 的内容不会立即显示,用这个即可。
dlopen() 加载前无法设置断点)。
dlopen() 打开的,会发生一些麻烦,比如加载之前无法给其中的函数设置断点。
catch load /my/path/file.so 可以在加载动态库的时候 break。也可省略 /my/path/。
gdb-ia 中,V(1:2,1:2,3,4) 这种语法是可以用的。
p V(1,1,1:2,1:2) 提示超过了 max-value-size,就用 set max-value-size unlimited 就可以解决
gdb -tui 或 gdbtui 开启 Text User Interface, 可以同时显示代码,汇编,registers, gdb 命令等等。
gdb 命令行中打 tui enable(或者 tui e)打开,或者 tui disable(tui d)关闭
tui 环境中,layout asm 可以显示汇编码
sudo apt install gdbserver(一般已经随系统安装)。用 -g 选项编译一个程序,然后运行例如 gdbserver localhost:2000 main.x(其中 localhost 不需要替换为真正的 ip)。
gdb,直接运行,不需要编译相同的 main.x(可能会导致 breakpoing 不能使用),但这么做的缺点是运行前要加载一大堆远程系统的 so 文件。然后 target remote xxx.xxx.xxx.xxx:2000。接下来就可以正常使用了 gdb 的各种命令了。如果显示 run 命令不能用,就直接 continue 即可。
gdbserver 会自动结束,本地的 gdb 也会断开链接。也就是说连接一次只能运行一次,需要再次在服务器中运行并连接。
 
 
 
 
 
 
 
 
 
 
 
友情链接: 超理论坛 | ©小时科技 保留一切权利