linux 段错误 吐核 崩溃 简介

目录

错误现象

错误原因

错误演示

吐核解释

崩溃文件查找

崩溃文件调试


错误现象

我们在Linux环境下编程中,有时执行编译好的文件时会出现段错误(吐核),这是经常出现的一个错误。
在这里插入图片描述

错误原因

  1. 解引用空指针
  2. 访问不可访问的内存空间(如内核空间)
  3. 访问不存在的内存地址
  4. 试图写一个只读内存空间(如代码段)
  5. 栈溢出(函数递归调用)
  6. 使用未初始化的指针(定义时没有初始化或者已经回收)

错误演示

对一个空指针进行解引用 

在这里插入图片描述

吐核解释

吐出了一个“核心转储文件”(coredump文件)即崩溃文件

程序确认出现错误时的“临终遗言” 写入核心转储文件,也是使用gdb调试器最常用到的场景

崩溃文件查找

我们尝试ls -a查看全部文件 (包含默认隐藏的文件)发现也并没有相关的新文件产生

其实操作系统有限制,默认不允许随意吐核,在一个工程中coredump文件有可能会特别大,多次吐核过于占存,这样随意吐核会影响机器性能,一定要慎用。

我们通过指令查看与程序相关的属性,其中会包含核心转储文件信息

在这里插入图片描述

 第一条core file就是coredump—— 核心转储文件,size0表示不允许吐核,更改一下文件大小就可以顺利产出吐核文件了。

通过指令更改为大小为无限制 ulimit -c unlimited

我们再执行./main,再次吐核。
之后 ls 就会出现core.3616文件,数字后缀不同机器会不一样,这个不用在意。这个就是核心转储文件,我们成功通过操作查看到了。
在这里插入图片描述
仔细查看文件详情,发现文件确实占存很大:
在这里插入图片描述
那么我们通过vim进入文件内部,看看它究竟是什么样子的:
在这里插入图片描述
果然如我们所料看不太懂,不知所云,这时候就借助我们老搭档gdb调试器的力量

崩溃文件调试

 gdb 可执行文件名 + 核心转储文件名

核心转储文件通过不同的可执行文件可能吐出不同的核,所以要带上可执行文件名,告诉操作系统这个核心转储文件是哪个可执行文件吐出的。

在这个程序中我们就输入gdb main core.3616,回车后就可以定位程序错误原因了:

在这里插入图片描述

 红色方框中显示了在main.c文件中的Add函数中第6行对应的*p = 100;这句代码有问题,导致程序异常终止,因为空指针不能解引用。

蓝色方框是一个比较重要的概念,11号信号,它是段错误(Segmentation fault)的典型图腾。

那么这错误的第6行代码到底是怎么执行的?
  可以通过bt指令查看函数调用栈:

在这里插入图片描述
所以是因为main函数调用Add函数再调用Add2函数,就在第6行出现了错误。这就是它的调用情况。

猜你喜欢

转载自blog.csdn.net/whatday/article/details/120794124