你无法游向新的地平线,直到你有勇气告别海岸。(by 威廉·福克纳)
前言
小羊啊,咱们那个视觉抓拍程序执行过程中报了个“段错误(吐核)”的异常你来处理,十分紧急,尽快处理下。
排查
1.首先理解下啥是段错误(吐核)/Segmentation fault (core dumped)?
段故障(通常简称为segfault)是计算机软件运行过程中可能出现的一种特殊错误情况。简而言之,当程序试图访问不允许访问的内存位置,或试图以不允许的方式访问内存位置时,就会发生段错误。
A segmentation fault (often shortened to segfault) is a particular error condition that can occur during the operation of computer software. In short, a segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed[1]
2. 产生段错误(吐核)的原因是什么呢?
在引用.so文件时以下几类做法容易导致段错误,基本都是我们给C程序传入了错误参数造成的。
解引用空指针
C语言中,如果一个指针变量的值为NULL,解引用这个指针时,会导致程序崩溃(Segmentation fault)。
访问不可访问的内存空间(如内核空间)
例如系统保护的内存地址写数据最常见就是给一个指针以0地址
访问不存在的内存地址
例如内存越界(数组越界,变量类型不一致等)
等等其他(左羊调查有其他情况在做补充)
3. 如何排查产生段错误(吐核)的原因呢?
左羊在这里准备了一个复现错误的程序供大家测试。这里左羊采用的是解引用空指针的形式复现。
#include <stdio.h>
int main(void)
{
printf("Hello_c/r/n");
int *helloWorld = NULL;
*helloWorld = 1;
}
复制
3.1. 可以获取到.so 文件源码的情况下,我们可以使用gcc -g 的方式编译.c文件,然后使用gdb ./appname的方式进入debug模式排查。
gcc -g -rdynamic HelloC.c
复制
a.out是咱们的执行文件,执行它即可复现问题。中文输出为【段错误(吐核)】英文输出为【Segmentation fault (core dumped)】它们的意思是一样的。
./a.out
复制
下面咱们使用gdb ./appname的方式来排除出现问题的原因
gdb ./a.out
复制
(gdb)输入run以debug的方式运行程序
(gdb)run
复制
到这里咱们就能够发现是哪里出现了问题,问题的原因是代码中出现了解引用空指针的情况,处理掉即可。
3.2. 在无法获取到.so 文件源码的情况下,我们因该怎么办呢。左羊此次就属于无法获取到.so 文件源码的情况。
首先我们发现在没有使用gdb的方式运行时,系统给我们抛出了“段错误(吐核)/Segmentation fault (core dumped)”信息提示。
什么是吐核/Core Dump?
Core的意思是内存, Dump的意思是扔出来, 堆出来.
开发和使用Unix程序时, 有时程序莫名其妙的down了, 却没有任何的提示(有时候会提示core dumped). 这时候可以查看一下有没有形如core.进程号的文件生成, 这个文件便是操作系统把程序down掉时的内存内容扔出来生成的, 它可以做为调试程序的参考.core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump。[2]
如何使用core文件?
gdb appname 核心转储文件名
gdb appname core.****
复制
复制
ulimit -a
复制
这里的【core file size】指的就是核心转储文件,参数为0代表无法写入,我们来修改其大小即可
ulimit -c 1024 单位是字节
ulimit -c unlimited 为无上限
复制
这里我们已经设置为无上限了,接下来我们再次执行下程序看看有没有核心转储文件生成。
core即为核心转储文件,我们通过gdb命令查看下报错信息。
这样我们即可定位问题了
小结
其实左羊这里的段错误(吐核)就是:
Python在调用.so文件时向其发送了一个非法的虚拟地址,通知操作系统内核给进程发送11号信号,进程收到了一个11号信号,导致进程异常终止。找出调用位置,重新检查参数就处理啦~
参考资料:
[1]段错误(吐核)的解释:https://stackoverflow.com/questions/30126079/a-segmentation-fault
[2]Core Dump解释:https://www.cnblogs.com/wuxi/archive/2013/05/04/3060319.html
复制
[
END
]

关注左羊公社