上篇文章:Linux操作系统5-进程信号2(信号的4种产生方式,signal系统调用)-CSDN博客
本篇Gitee仓库:myLerningCode/l25 · 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com)
本篇重点:核心转储
目录
一. man 7 signal
二. core dumped 核心转储 ⭐
2.1 核心转储的使用
2.2 看不到核心转储文件的处理方式
三. 自定义所有的信号的行为
四. 信号的相关概念
一. man 7 signal
可以使用 man 7 signal查看信号的具体信息
可以看到在Action这一栏中有很多不同的行为
其中,让进程退出的有两种 Core 与 Term
Core : 异常退出
Term : 正常退出
二. core dumped 核心转储 ⭐
2.1 核心转储的使用
这里通过一份非法访问内存的代码来说明 core dumped
#include <iostream>
#include <unistd.h>
int main()
{
std::cout << "进程pid:" << getpid() << std::endl;
int arr[10];
arr[10000] = 100;
return 0;
}
运行结果如下:
可以看到, 在段错误后面还有一个 core dumped表示异常退出
这里我使用的是云服务器, 如果想要使用核心转储文件, 需要执行下面的命令打开
ulimit -a 查看资源
可以看到核心转储文件是0
ulimit -c 文件大小 即可使用核心转储文件
此时在运行test即可看到一个核心转储文件
核心转储文件的命名为 core.文件名.进程pid
我们可以通过核心转储文件快速定义程序出错的地方
我们对test进行调试, 调试的时候输入 core-filre + 核心转储文件
这种调试的方式称为事后调试
当然也能直接 gdb 调试的程序 + 核心转储文件 直接快速定位错误
如果我们的退出方式是temp, 则不会产生核心转储文件
#include <iostream>
#include <unistd.h>
int main()
{
std::cout << "进程pid:" << getpid() << std::endl;
while(1) sleep(1);
int arr[10];
arr[10000] = 100;
return 0;
}
使用 ctrl c 发送的2号命令是trem 所以不会产生核心转储文件
2.2 看不到核心转储文件的处理方式
如果使用了 ulimt -c 文件大小 还是没有核心转储文件生成的话可见检查核心转储文件的位置
该位置有系统参数core_pattern决定, 使用下面的命令可以查看
cat /proc/sys/kernel/core_pattern
一般这个都以一个管道开头 |
如果想要生成在当前目录下, 可以执行下面的命令
echo "./core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern
三. 自定义所有的信号的行为
如果我们自定义所有信号的行为, 那么进程是不是永远不会退出了?
使用代码来测试一下
#include <iostream>
#include <string>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
void catchSig(int signo)
{
while (true)
{
std::cout << "进程:" << getpid() << " 获取一个信号编号,编号是:" << signo << std::endl;
sleep(1);
}
}
int main()
{
for (int i = 0; i <= 34; i++)
signal(i, catchSig);
while (1)
sleep(1);
return 0;
}
可以看到, 自定义了所有信号的行为, 9号信号仍能结束进程(9号信号无法被自定义)