Linux下使用gdb调试C/C++程序

原文链接:Linux下使用gdb调试C/C++程序
发布时间:2015-08-27 14:55:29

在笔者工作实践中,使用gdb调试C++程序和调试C程序,他们稍有不同,下面是使用总结。

一、编译选项

1
2
3
4
5
-g         生成调试信息

-gstabs+ 以stabs格式生成调试信息,并且包含仅供gdb使用的额外调试信息生成调试信息,是阻止编译器将局部变量优化的寄存器里,

笔者在调试C++程序时,不加这个选项,所有的变量都打印不出来,gdb提示说没有这个符号

二、打断点

对于C程序,代码都是函数封装,打断点很容易,但是C++代码都是类封装,而且函数还可以重载前2种打断点的方式主要用于C程序,后3种多用于C++程序

1
2
3
4
5
6
7
8
9
1、b funcName 即在函数入口处打断点

2、b lineNum 在某一行打断点

3、b className::funcName或者 b className::funcName(type,type) 在某个类的某个函数入口打断点,由于类的函数有重载,可以在函数名内加上参数类型

4、b fileName:lineNum 在某个源文件的某一行打断点

5、b fileName:funcName 在某个源文件的某个函数入口打断点

三、常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1、finish            一直执行到当前函数返回,即跳出当前函数

2、r 运行程序(run)

3、n 执行下一条语句(next 不会进入函数内部)

4、s 执行下一条语句(step 会进入函数内部)

5、回车键 重复执行上一条命令

6、c 继续执行直到下一个断点(continue)

7、p 打印变量的值(print)

8、bt 查看函数堆栈(backtrce)

9、q 退出gdb调试(quit)

10、info break 查看断点信息

11、delete breakNum 删除某个断点

四、bt命令调试段错误

在Linux下编程,一不下心就会出现段错误(Segmentation fault),关于段错误的产生,笔者目前只是大概知道是内存的非法访问造成的,比如访问空指针,指针越界访问都会造成段错误,关于本质原因,还需要研究Linux内存管理、进程空间等知识,这方面有待后续深入研究。下面演示如何利用 core文件定位程序段错误。

测试代码:segfault.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*************************************************************************
> File Name: segfault.c
> Author: KentZhang
> Mail: zhchk2010@qq.com
> Created Time: Thu 27 Aug 2015 02:48:37 PM CST
************************************************************************/
#include<stdio.h>

void test_seg_fault()
{
printf("test_seg_fault() start.\n");
char *p=NULL;
*p = 'a';
printf("test_seg_fault() end.\n");
}

void main()
{
test_seg_fault();
}

1、编译程序生成可执行文件

1
gcc -g segfault.c -o segfault

2、生成Core文件

1
ulimit  -c  unlimited

执行程序:./segfault

1
2
3
[root@localhost MyDir]# ls

core.8450 segfault segfault.c

3、启动gdb,打印栈信息

1
gdb  ./segfault  ./core.8450

然后执行:bt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Loaded symbols for /lib64/ld-linux-x86-64.so.2

Core was generated by `./segfault'.

Program terminated with signal 11, Segmentation fault.

#0 0x00000000004004e2 in test_seg_fault () at segfault.c:13

13 *p = 'a';

Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6.x86_64

(gdb) bt

#0 0x00000000004004e2 in test_seg_fault () at segfault.c:13

#1 0x00000000004004ff in main () at segfault.c:19

(gdb)

4、分析结果

          本实例中,程序崩溃后,保留了2层栈的信息,#0 栈,是程序发生崩溃时所在的栈,即是在test_seg_fault函数内发生崩溃,在segfault.c文件的第13行,这一句发生段错误,到此定位完成。其实函数每调用一层,就会有一层栈的信息,最上面的总是 #0 号栈,即程序当前所在的栈,这很符合压栈操作。

由于笔者的水平有限,出错在所难免,恳请读者拍砖指正,谢谢阅读