[奇怪の东西]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) 或者 untilrun 是从程序开头开始执行到断点或程序结尾,continue 是从当前语句开始执行到断点或结尾,而 until 语法为 until [LineId],即执行到断点或指定行。而 fin 意为完成当前的函数,直到其返回。

posted @ 2021-12-25 12:12  Arextre  阅读(101)  评论(0编辑  收藏  举报