gdb 调试
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gdb 调试相关的知识,希望对你有一定的参考价值。
Gdb调试
在Linux下进行C++程序的调试,其中gdb是非常强大的工具,不再使用LOG_INFO这种使用输出来观察数据的正确性,及如何面对段错误,这种非常难以定位的问题,在gdb中都能够给予非常好的支持,其具体使用方法如下:
1. 设置断点
整个程序如下:
#include <stdio.h> int nGlobalVar = 0; int tempFunction(int a, int b) { printf("tempFunction is called, a = %d, b = %d \n", a, b); return (a + b); } int main() { int n; n = 1; n++; n--; nGlobalVar += 100; nGlobalVar -= 12; printf("n = %d, nGlobalVar = %d \n", n, nGlobalVar); n = tempFunction(1, 2); int i=0; for(;i<10;++i) { printf("data is %d\n",i); } printf("n = %d\n", n); return 0; }
1) Break
断点位置的设置,可以包括行号、函数:
指定的行号 :b 12
指定的文件行号:b test:12
指定的函数:b fun
指定文件的函数:b test:fun
根据条件设置断点:b 21 if i==5
Breakpoint 1 at 0x4008b6: file /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/swap_1.cc, line 21. (gdb) r Starting program: /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/bin/gdb_test n = 1, nGlobalVar = 88 tempFunction is called, a = 1, b = 2 data is 0 data is 1 data is 2 data is 3 data is 4 |
在i为5的时候程序停止
2) Watch 观察点
- 设置断点之后,b 18 使得程序可以在18行:Int i=0;处停止
- r 命令,让程序再18行停止
- watch i设置观察点
- 使用c(ontinue)观察设置的观察点是否有变化
得到的结果为:
Breakpoint 2, main () at /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/swap_1.cc:18 18 int i=0; (gdb) watch i Hardware watchpoint 4: i (gdb) c Continuing. data is 0 Hardware watchpoint 4: i
Old value = 0 New value = 1 0x00000000004008ce in main () at /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/swap_1.cc:19 19 for(;i<10;++i) |
可以看到变量发生变化前后的值。
3) tbreak
与Break之间的区别在于它是一个temp的断点,运行一次之后该断点将会被删除。
2. 打印数据
- 打印变量的值: p n
- 打印变量地址:p &n
- 查看当前运行的行及文件:backtrace,可以简写为bt。
如果要调试一个core文件,当程序奔溃之后生成一个core文件,然后直接定位到发生程序奔溃的位置,可以采用:ulimit -c unlimited生成core文件。
问题:对core文件如何的调试?
在gdb 命令中使用:gdb core文件
- 以不同的进制显示变量值:p /x var (使用16进制显示变量),其中d为10进制,f为浮点型,t为二进制格式
- 显示变量的类型,whatis a
whatis i
type = int
添加一个结构体,在main中添加一个类变量 TestA _test A;
class testA { public: int a; int b; TestA() { a = 2; b = 5; } }; |
设置断点:b 29,r运行,p _testA,得到:
$6 = {a = -7296, b = 32767}
执行whatis _testA,得到:
type=TestA
想要更详细的信息:ptype _testA,结果为:
type = class TestA { public: int a; int b; TestA(void); } |
可以观察到,在每个print后面都会给输出的变量加一个变量标号,所以,可以使用该标记输出,而不同输出冗长的变量名,比如:
(gdb) p nGlobalVar $1 = 88 (gdb) p $1 $2 = 88 |
- 显示调用函数值
print tempFunction(2,3)将得到5
- 查看文件中的变量:p ‘tets.c’::n,
- 查看函数中的变量: 使用作用域,如果是与全局的变量发生冲突的时候
- 显示数组:p *[email protected]
- 设置参数值:set variable n=13
- 立即执行完当前的函数:直接使用finish,将跳出当前的函数。
- 执行完当前的循环:until 循环外面的行号,然后c,将会达到循环外面。比如设置until 到下面这行,代码将直接跳出循环。
3. 设置
4. 执行代码
printf("n = %d\n", n);
- 程序继续运行直到遇到断点或者程序结束:c
- 下一条语句:n(ext),step over
- 下一步:s(tep), step in
- 运行:r,继续往下运行,直到一个断点停下来
- 调用程序中的函数:call tempFunction(3,7)
- 列出所有的断点:info b
- 列出某个断点:info break的断点号
- 列出函数 list tempFunction(int,int)
- List 默认显示10行
- List 0,20 列出0-20行之间的源码
- 删除断点,由于gdb会给每个断点设置一个序号,所以,可以利用这个序号删除指定的断点,比如我们列出info b得到下面的结果:
5. 列出所有的断点
6. 列出源代码
7. 删除断点
Num Type Disp Enb Address What 1 breakpoint keep y 0x0000000000400854 in main() at /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/swap_1.cc:14 breakpoint already hit 1 time 2 breakpoint keep y 0x00000000004008b6 in main() at /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/swap_1.cc:26 stop only if i==4 3 breakpoint keep y <PENDING> i==5 4 breakpoint keep y 0x00000000004008b6 in main() at /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/swap_1.cc:26 stop only if i==5 |
- 对断点3进行删除:delete 3
再次执行info b之后,该断点已经被删除,但是后面的断点的序号并不会发生改变,整个断点的序号变为:1,2,4
- 删除一个连续的断点,使用断点号来描述,比如,删除1-2号断点,得到结果为:
(gdb) delete 1-2 (gdb) info b Num Type Disp Enb Address What 4 breakpoint keep y 0x00000000004008b6 in main() at /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/swap_1.cc:26 stop only if i==5 |
可以看到只有4号断点了
- 删除某个函数内的所有断点:clear fun
- 删除某个文件中的所有断点:clear test.c
- 删除文件中的某个函数的断点:clear test.c:fun
- 删除行号的断点:clear 行号,注意:可能在某种情况下我们会在同一行设置多个断点,但是这些断点也许不是连续的,如果使用delete,会显得有点麻烦,利用clear命令会将该行中所有的断点都删除。
- 删除某文件中行号的所有断点:clear test.c:行号
- 是否有删除所有的断点,其命令为:delete ,后面不带任何的参数,在执行之后会询问是否删除所有的断点。
- 显示在当前文件中包含text串的下一行:Search text
- 显示包含text的前一行:reverse-search text
8. 查找文本
9. 其它辅助
1. 列出当前的目录:pwd
2. 改变运行的目录:cd
3. Info program 查看程序是否在运行
以上是关于gdb 调试的主要内容,如果未能解决你的问题,请参考以下文章