文章目录
一、背景
- 程序的发布方式有两种,debug和release模式,要在linux中调试,需要使用到一个工具——gdb调试器。
- gdb调试器类似于VS中的debug模式。
- Linux gcc/g++出来的二进制程序,默认是release模式
- 要使用debug模式,必须在源代码生成二进制程序的时候,加上-g选项!
二、gdb的指令与使用
1.gdb的基本指令。
首先列举下gdb调试器的基本指令。
- list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
- list/l 函数名:列出某个函数的源代码。
- r或run:运行程序。
- n 或 next:单条执行。
- s或step:进入函数调用。
- break(b)行号:在某一行设置断点。
- break 函数名:在某个函数开头设置断点。
- info break :查看断点信息。
- finish:执行到当前函数返回,然后停下来等待命令。
- print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数 。
- p变量:打印变量值。
- set var:修改变量的值。
- continue(或c):从当前位置开始连续而非单步执行程序。
- run(或r):从开始连续而非单步执行程序。
- delete breakpoints:删除所有断点。
- delete breakpoints n:删除序号为n的断点。
- disable breakpoints:禁用断点。
- enable breakpoints:启用断点。
- info(或i) breakpoints:参看当前设置了哪些断点。
- display 变量名:跟踪查看一个变量,每次停下来都显示它的值。
- undisplay:取消对先前设置的那些变量的跟踪。
- until X行号:跳至X行 。
- breaktrace(或bt):查看各级函数调用及参数。
- info(i) locals:查看当前栈帧局部变量的值。
- quit / ctrl+d:退出gdb。
2.gdb指令的简单使用
前面介绍了gdb调试器的一些指令,现在选一些指令实际应用一下。
1.进入gdb模式
1. vim一个简单的sum.c文件:
2. 使用gcc -g指令,生成可以gdb的文件:
3. gdb + 文件名,进入调试模式:
2.实例说明
出现如上界面,表示已经进入了gdb模式,接下来介绍几个gdb下的指令的使用。
-
list/l 行号:输入l+行号则跳到输入行号的位置,只输入l则从第一行开始显示十行内容,在输入l会跳转到后面十行,如图。
-
list/l 函数名:列出某个函数名,以sum.c的sum函数为例。输入l sum。
-
r或run:运行程序。 输入 r,可以看到输出了打印结果:11
-
break/b 行号:在某一行设置断点,例如现在在12,13,14行分别设置断点,设置成功会有提示,并给出断点序号Breakpoint n。
-
info break(i b):查看断点信息,输入info break,可以看到断点信息,地址和所在行号。
-
disable 断点的序号:使断点失效
可以看到,使断点1,2失效后,执行程序直接跳到了断点3处。
7. enable 断点的序号:使断点生效
8. delete breakpoints:删除所有断点
9. delete breakpoints n:删除序号为n的断点,删除断点1后,执行i b,断点1消失。
-
n或next:单条执行,相当于windows中的逐过程执行,VS中的F10(需要先run)
单条执行,不进入函数内部 -
s或step:进入函数调用,相当于windows中的逐语句执行,VS中的F11(需要先run)
执行s后,进入了函数sum内部并逐语句执行。 -
continue©:从当前位置开始连续而非单步执行程序(遇到下一个断点时就会停止运行)
-
print(p):打印变量的值
,首先执行到int a后,执行p a,显示a的值为5
三、调试coredump文件
前提:本质上是在调试程序崩溃之后的内存镜像文件。
产生coredump文件的条件:
1.linux操作系统当中,需要设置core size的大小,使用指令 ulimit -c size,如:
,可执行该语句将core size大小设置为无穷,这样当调试程序崩溃后,就会生成内存镜像文件
2.磁盘大小足够
内存镜像文件保存的是,程序在崩溃的一瞬间内存当中的值
执行gdb [可执行程序][coredump文件],可查看coredump文件的信息,获悉是什么地方发生了错误。
举个例子:
,首先创建一个明显有空指针赋值的错误文件。然后gcc编译并添加-g。
编译完成后,执行编译后的文件testfault,可以发现显示了段错误(吐核)的错误,这个错误就是内存访问越界或者空指针引起的。ls查看列表文件
出现了core.20390的文件 gdb进入,
主要的信息在倒数几行。program terminated with signal 11,Segmentaion fault表示程序收到了11号信号,产生了段错误。
圈出来的地方表示,崩溃的代码出现在testfault.c文件的第七行。
还可以通过:
1. bt:查看调用堆栈
2.f[堆栈序号]:跳转到某一个具体的堆栈
可以看到执行bt后,调用堆栈的信息列出,执行f 0跳到堆栈处,看到错误行。
tips:
- 11信号:解引用空指针,解引用野指针,越界访问内存
- 6号信号:double free