[奇怪の东西]gdb的食用须知
主要是记录一些 gdb
里面的基础操作(不然忘记得很快),一般涉及到不知道的东西才会过来更一下,所以可能有些东西不是很齐,或者例如断点这些我觉得比较杂并且又不需要再多强调的东西就不会写。
让它说话! ¶
数组、变量和函数
对于一个单一变量,操作十分简单,键入 p [variableName]
即可,例如:
(gdb) p n
$1 = 10
这样它就会输出变量 n
的值。
对于数组,如果想要输出数组中的一个元素,同上。如果想要输出连续几个下标的元素,使用 p [firstElement]@[length]
即可,例如:
(gdb) p *f[1][1]@10
$1 = {0, 0, 0, 0, 0, 1, 0, 1, 0, 0}
此处 f
是一个三维数组,我输出了 f[1][1]
这个数组的前 \(10\) 项,注意,默认是 \(0\) 下标开头,如果我想输出 f[1][1][1]
到 f[1][1][10]
的元素,则使用:
(gdb) p f[1][1][1]@10
$1 = {0, 0, 0, 0, 1, 0, 1, 0, 0, 0}
注意,并不是第一个元素的地址,而是第一个元素的引用。
特别地,如果要输出一个 vector<>
数组,那么应该使用 p *([vectorName]._M_impl._M_start)@[length]
,例如:
(gdb) p *(buc._M_impl._M_start)@3
$6 = {0, 0, 1}
当然,下标从 \(0\) 开始,如果你要调整下标,那么使用 p *([vectorName]._M_impl._M_start + [startIndex])@[length]
,也就是把下标移动几位就行了。
当然,还可以输出一个函数的值,假设我有一个函数 trans(s)
,其代码如下:
inline int trans(int s) {
for (int ret = 0; ; ret = ret * 3 + (s % 10), s /= 10)
if (!s) return ret;
}
我可以查看其在 s=12
的情况是否复合我的预期,直接调用 p trans(12)
就可以输出其计算结果,换句话说,可以直接 p [functionName]({Para list})
输出一个函数的参数为 {Para list}
时的结果,同样,{Para list}
中也可以传变量。
(gdb) p trans(12)
$1 = 7
(gdb) p trans(n) // n == 10
$2 = 1
堆栈信息
可以查看当前的堆栈信息,在调递归函数的时候挺好用,命令 backtrace
或者 bt
即可。
(gdb) bt
#0 Deriv (f=..., n=5) at diric.cpp:105
#1 0x00000000004148e1 in Ln (f=..., n=5) at diric.cpp:124
#2 0x000000000040159c in main () at diric.cpp:148
给我代码
当然,有的时候你需要它输出你调试的程序,这个时候使用 list
指令即可。一般默认的是输出当前执行语句的附近几行
(gdb) list
105 namespace Tree1 {
106
107 inline void build() {
108 rep (i, 1, m) readin(Es[i].u, Es[i].v, Es[i].w);
109 sort(Es + 1, Es + m + 1, [](Edges a, Edges b) { return a.w < b.w; });
110 ufs::init();
111 memset(tail, 0xff, sizeof tail);
它的左边还有代码的行号,如果继续输入 list
,他就会接着输出。
还有几种格式,都比较好懂,比如 list [linenum]
(显示程序第 linenum
行的周围的源程序)和 list [function]
(显示函数名为 function
的函数的源程序),总的来说,一般有这些东西:
set listsize [size]
:设置一次显示源代码的行数;list [start_linenum],[end_linenum]
:显示从start_linenum
行到end_linenum
行之间的源代码;list ,[end_linenum]
:显示从当前行到end_linenum
行之间的源代码;list +/-
显示当前行 往后/往前 的源代码;list [linenum]
:显示程序第linenum
行的周围的源程序;list [function]
:示函数名为function
的函数的源程序;
其他的信息
对于其他的一些信息,可以使用 info [KeyName]
获得,比如,我想获得断点信息,就可以 info breakpoint
或者 info b
(gdb) info b
Num Type Disp Enb Address What
4 breakpoint keep y 0x0000000000414e6a in Deriv(std::vector<int, std::allocator<int> >, int) at diric.cpp:104
跳过语句 ¶
主要是四个指令:run
,c
,(即 continue
),fin
(即 finish
) 或者 until
,run
是从程序开头开始执行到断点或程序结尾,continue
是从当前语句开始执行到断点或结尾,而 until
语法为 until [LineId]
,即执行到断点或指定行。而 fin
意为完成当前的函数,直到其返回。