gdb调试 与 coredump

本文详细介绍了GDB调试器在C/C++编程中的应用,涵盖了启动程序、设置断点、监视变量、代码优化影响、使用help命令以及处理coredump和多线程问题。重点讲解了如何配置调试信息、设置优化级别,以及调试时跟踪信号和堆栈情况。
摘要由CSDN通过智能技术生成

gdb 调试

GDB是编译语言的源代码级调试器,主要是C和c++。
四个方面的功能:
1、按照自定义的方式启动运行需要调试的程序。
2、可以使用指定位置和条件表达式的方式来设置断点。
3、程序暂停时的值的监视。
4、动态改变程序的执行环境。

gdb 相关

-g 调试级别

需要用调试符号编译要调试的代码。
GCC为此提供了两个选项:-g-ggdb
后者添加特定于GDB的调试信息,而前者则为正在使用的任何目标操作系统以适当的格式生成信息,使其成为更具可移植性的选项。Linux,使用-g还是-ggdb没有什么区别。
两个选项都允许指定调试信息的级别,从0到3:
0:不产生任何调试信息,相当于省略-g-ggdb开关。
1:这产生最少的信息,但包括函数名和外部变量,这足以产生回溯。
2:这是默认值,包含有关局部变量和行号的信息,以便您可以执行源代码级调试和单步执行代码。
3:这包括额外的信息,除其他事项外,意味着GDB可以正确处理宏扩展

-O 代码优化级别

编译器优化倾向于破坏源代码行和机器码行之间的关系,这使得遍历源代码变得不可预测。如果遇到这样的问题,很可能需要在不进行优化的情况下进行编译,省略-O编译开关,或者使用-Og,该开关启用不会干扰调试的优化。

gdb 使用

在这里插入图片描述

获取帮助命令 help

在这里插入图片描述

断点

break 命令用于设置断点,命令接受行号或者函数名作为参数。
在这里插入图片描述
break也可设置条件断点:
如: break sayHello if count<1
使用info break 可以查看断点
使用 clear 可以清除断点
使用run命令(缩写为 r)运行程序至断点
next 命令(缩写为 n)单步执行程序
继续运行,可以使用continue 命令(缩写为 c )指导 gdb 继续运行程序,直至遇到下一个断点。

如果想继续单步执行,可以继续使用 next,也是以使用 step (缩写为 s), stepnext 的最大的区别在于,step 遇到函数是会进入到内部,而next 不会进入内部。

监视变量

调试程序最基本的需求就是监视变量的值,可以使用 print 命令(缩写为 p) 显示指定变量的值。
在这里插入图片描述
如果要时刻监视某个变量的值,那么每次使用 print 就不方便。比较人性化的是,gdb 提供了watch 命令,用于设置另一种断点:“观察点”。
用法是: watch 变量名或表达式作为参数,一但值发生变化,就停下来。

临时修改变量

当某些特殊情况下,想让程序进入一些特殊的流程时,gdb允许用户在程序运行时改变变量的值,通过 set var 命令实现这一点。
在这里插入图片描述

查看堆栈情况

每次程序调用一个函数,函数的地址、参数、函数内部变量都会被压入“栈”(Stack) 中,运行时堆栈信息对于程序员非常重要,使用 “bt”命令可以看到当前运行时栈的情况。
在这里插入图片描述

退出 gdb

试完毕,使用quit命令(缩写为q) 退出 gdb程序。
在这里插入图片描述

gdb的查看源码

可以用list命令来打印程序的源代码:
list <linenum>:显示程序第linenum行的周围的源程序。
list <function>:显示函数名为function的函数的源程序。
list:显示当前行后面的源程序。
list -:显示当前行前面的源程序。

可以定制显示的范围,使用下面命令可以设置一次显示源程序的行数:
setlistsize <count>:设置一次显示源代码的行数。
showlistsize:查看当前listsize的设置。

list命令还有下面的用法:
list <first>, :显示从first行到last行之间的源代码。
list ,<last>:显示从当前行到last行之间的源代码。
list +:往后显示源代码。

coredump

Coredump 叫做核心转储,它是进程运行时在突然崩溃的那一刻的一个内存快照
操作系统在程序发生异常而异常在进程内部又没有被捕获的情况下,会把进程此刻内存、寄存器状态、运行堆栈等信息转储保存在一个文件里,该文件也是二进制文件。

设置

在l inux 和 Solaris下是需要进行设置的。可以使用ulimit -a来看这些设置
在这里插入图片描述
ulimit -c 可以设置core文件的大小,如果这个值为0。则不会产生core文件,这个值太小,则core文件也不会产生,因为 core文件一般都比较大。
使用ulimit -c unlimited来设置无限大,则任意情况下都会产生core文件。

缺省情况下,内核在coredump时所产生的core文件放在与该程序相同的目录中,并且文件名固定为core。很显然,如果有多个程序产生core文件,或者同一个程序多次崩溃,就会重复覆盖同一个core文件。
通过修改 kernel 的参数,可以指定内核所生成的 coredump 文件的文件名。例如,Easwy使 用下面的命令使 kernel 生成名字为 core_filename_time_pid 格式的 core dump 文件:

echo /corefile/core_%e_%t_%p > /proc/sys/kernel/core_pattern

在这里插入图片描述
echo 后面内容最好不要带上引号,有的系统会把引号也带入,这样,系统是不识别该内容的,也就会导致程序coredump而不会生成core文件。
可以在 core_pattern 模板中使用变量见下面的列表:

%%单个%字符
%p所dump进程的进程ID
%u所dump进程的实际用户ID
%g所dump进程的实际组ID
%s导致本次core dump的信号
%t core dump的时间 (由1970年1月1日计起的秒数)
%h主机名
%e程序文件名

产生 core dump 的可能原因

1.内存访问越界;
2.多线程程序使用了线程不安全的函数;
3.多线程读写的数据未加锁保护;
4.非法指针;
5.堆栈溢出。

如何调试

1)编译的时候添加-g选项,增加调试信息
2)gdb program core_file
bt或者where查看调用栈信息
如果你要查看某一层的信息,你需要切换当前的栈,一般来说,程序停止时,最顶层的栈就是当前栈,如果你要查看栈下面层的详细信息,首先要做的是切换当前栈。

frame <n> 
f <n> 

n是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame 1,表示栈的第二层。

up <n>

表示向栈的上面移动n层,可以不打n,表示向上移动一层。

 down <n> 

表示向栈的下面移动n层,可以不打n,表示向下移动一层。

上面的命令,都会打印出移动到的栈层的信息。如果你不想让其打出信息。你可以使用这三个命令:

select-frame <n> 

对应于 frame 命令。

up-silently <n> 

对应于 up 命令。

down-silently <n> 

对应于 down 命令。

查看当前栈层的信息,你可以用以下GDB命令:

frame 或 f 

会打印出这些信息:栈的层编号,当前的函数名,函数参数值,函数所在文件及行号,函数执行到的语句。

info frame 
info f 

这个命令会打印出更为详细的当前栈层的信息,只不过,大多数都是运行时的内内地址。比如:函数地址,调用函数的地址,被调用函数的地址,目前的函数是由什么样的程序语言写成的、函数参数地址及值、局部变量的地址等等。

info args

打印出当前函数的参数名及其值。

info locals

打印出当前函数中所有局部变量及其值。

一些常用signal的含义

SIGABRT:调用abort函数时产生此信号。进程异常终止。
SIGBUS:指示一个实现定义的硬件故障。
SIGEMT:指示一个实现定义的硬件故障。EMT这一名字来自PDP-11的emulator trap 指令。
SIGFPE:此信号表示一个算术运算异常,例如除以0,浮点溢出等。
SIGKILL:此信号指示进程已执行一条非法硬件指令。4.3BSD由abort函数产生此信号。SIGABRT现在被用于此。
SIGIOT:这指示一个实现定义的硬件故障。IOT这个名字来自于PDP-11对于输入/输出TRAP(input/outputTRAP)指令的缩写。系统V的早期版本,由abort函数产生此信号。SIGABRT现在被用于此。
SIGQUIT:当用户在终端上按退出键(一般采用Ctrl-/)时,产生此信号,并送至前台进程组中的所有进程。此信号不仅终止前台进程组(如SIGINT所做的那样),同时产生一个core文件。
SIGSEGV:指示进程进行了一次无效的存储访问。名字SEGV表示“段违例(segmentationviolation)”。
SIGSYS:指示一个无效的系统调用。由于某种未知原因,进程执行了一条系统调用指令,但其指示系统调用类型的参数却是无效的。
SIGTRAP:指示一个实现定义的硬件故障。此信号名来自于PDP-11的TRAP指令。
SIGXCPU:SVR4和4.3+BSD支持资源限制的概念。如果进程超过了其软CPU时间限制,则产生此信号。
SIGXFSZ:如果进程超过了其软文件长度限制,则SVR4和4.3+BSD产生此信号。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞大圣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值