linux下gdb使用core文件调试程序,解决“段错误核心已转储“的问题

一、core文件介绍以及用途:

1、core文件是什么?

core文件包含了程序运行时的内存状态、寄存器状态、堆栈指针、内存管理信息以及各个函数使用堆栈信息等等;
当程序运行过程中出现段错误(Segmentation Fault),程序将停止运行,由操作系统把程序当前的内存状况存储在一个 core 文件中,即核心转储文件(Coredump File),core 文件是程序运行状态的内存映象。

2、使用场景,段错误

使用程序的时候,总会遇到

“段错误(核心已转储)”

这样的错误提示信息,通过gdb与core文件便可以查看程序错误的地方。

3、造成段错误的原因

主要以下几个方面

内存访问越界
多线程使用了线程不安全的函数
非法指针
堆栈溢出
多线程读写的程序没有加锁保护

二、core文件调试举例

1、举例一个用了空指针的程序

这里我们故意使用一个空指针,然后造成段错误,去演示如何使用core文件调试程序

#include <iostream>

int main()
{
    
    
*(char *) 0 = 0;//使用一个空指针,会报段错误
	int num;
	std::cout<<"please enter a number:";
	std::cin>>num;
	for (int i = 0; i < 10; i ++)
	{
    
    
		num += i;
		std::cout<<"number + i = "<<num <<std::endl;
	}
	return 0;
}

2、设置core文件大小

因为默认的core文件大小是0 ;也就是默认不保存这个文件;所以需要我们设置一下;
使用下面的命令去查看以及设置:

ulimit -c 
 //查看core文件大小默认是0;
 //此时不生成core文件
ulimit -c unlimited 
 //不限制生成core文件的大小

但是如果你是普通用户,这样的操作一般都会报错误:“不允许的操作”;

bash: ulimit:core file size:无法修改limit值:不允许的操作

遇到这样的问题应该怎么解决呢?

1、用root用户去使用上述:ulimit -c unlimited命令
2、返回普通用户再使用一次:ulimit -c unlimited

PS:像使用命令 "sudo vi /etc/security/limits.conf "的这个方法,自己也有尝试过,但是好像没有效果,也写出来供大家参考参考吧!

sudo vi /etc/security/limits.conf"

找到下图的soft core,
在这里插入图片描述

把 0 改为 unlimited;
在这里插入图片描述

3、设置core文件的保存位置以及文件名字格式信息

使用 echo 更巧妙一点:

echo "/home/kylin/Core_P/core-%e" > /proc/sys/kernel/core_pattern

修改文件的格式信息,有利于core文件的保存和查看,名字的格式可以参考下面的:

%p - 添加pid(进程id)
%u - 添加当前uid(用户id)
%g - 添加当前gid(用户组id)
%s - 添加导致产生core的信号
%t - 添加core文件生成时的unix时间
%h - 添加主机名
%e - 添加导致产生core的命令名

PS:另外使用的方法,算是踩的一个坑。
就是通过编辑文件去设置保存位置与信息

sudo vim /proc/sys/kernel/core_pattern

在这里插入图片描述
结果就是一直有:

"警告:此文件自读入后已发生改动!!!"
"core pattern" E667:同步失败的信息

所以使用 echo的方法,可以解决上面的问题,而且是有效的!

4、使用core文件查看错误

由于程序里面故意写了一个空指针,所以运行的时候肯定会有"段错误(核心已转储)";
但是不同的是,这个时候的core文件的存在的,而且保存在上面刚刚设置的地方
在这里插入图片描述
使用 : ”gdb + [exec file] + [core file] “调试core文件
结果能够显示出错的函数、出错的行数,并显示该行代码
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43473694/article/details/109633178