贡献者: addis
set print pretty on
或者直接用 IDE。如果调试显示函数不存在,那就是被优化掉了,无解,只能查看数据成员。g++/gcc
编译时用 -g
选项以用于 debug
r
,p
,f
,s
,n
,ptype
(检查 typename 或者变量的类型)
print &变量
可以显示变量地址
p/r 变量
或者 ptype/r 变量
可以输出非常详细的信息。
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
可以显示当前在 stack 中的位置。
shell <command>
来输入命令行命令 <command>
而无需退出 gdb 或者暂停程序
make
命令而无需在前面加 shell
-g3
编译,可以打出宏的信息,用 info macro 宏名
,也可以直接 p 宏(...)
执行宏函数
-gdb
或者 gdb3
可以输出更加 gdb
友好的调试信息。
call (void) fflush(stdout)
,可以 flush 命令行输出的 buffer,有时候 cout
的内容不会立即显示,用这个即可。
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
也会断开链接。也就是说连接一次只能运行一次,需要再次在服务器中运行并连接。