C++利用SIGSEGV信号处理实现发生segment fault后不崩溃的代码

devtools/2024/9/24 1:22:10/

C++代码在内存越界或线程竞争情况下很容易出现未定义行为段错误,导致程序崩溃挂掉生成coredump,但如果想让程序遇到这种情况仍然可以继续运行,不中断服务呢?这里展示了一种方法。

C++代码发生段错误后系统会抛出SIGSEGV 信号 ,之后 调用默认的信号处理函数 ,产生core文件 ,然后关闭程序。让程序不挂掉的办法就是捕获这个中断信号,调用自定义的信号处理函数,并且叠加一些代码跳转的方法。

单纯捕捉信号不做特殊处理,虽然进程仍然在,但是会一直报错阻塞主线程,程序完全不可用。

有效的做法是在发生段错误的代码之前保存程序执行上下文,信号捕捉后通过跳转函数直接跳过段错误的代码,从而达到程序继续执行的目的。

这里用到两个函数sigsetjmp和siglongjmp,前者会保存当前的信号屏蔽表 (signal mask),后者跳转的时候会恢复线程的屏蔽表。通过设置的参数传递上下文信息。

代码:

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <stdarg.h>
#include <thread>
#include <chrono>sigjmp_buf env;void handle_signal(int sig)
{printf("# handle_signal %d\n", sig);// jump to continue code pointsiglongjmp(env, 1);
}
int main(int argc,char** argv)
{// global register signal handlesignal(SIGSEGV, handle_signal);for (int i = 0; i < 10; i++){// save contextint r = sigsetjmp(env, 1);if(r == 0){// execute different code dynamicallyif (i % 2){printf("execute the bad code\n");int* p = nullptr;*p = 7;}else{printf("execute the good code\n");int p = 7;}}else{// jump from signal handleprintf("skip the bad code, i = %d\n", i);}}while(true){printf("--- I am alive ---\n");std::this_thread::sleep_for(std::chrono::seconds(1));}return 0;
}

执行结果:

execute the good code
execute the bad code
# handle_signal 11
skip the bad code, i = 1
execute the good code
execute the bad code
# handle_signal 11
skip the bad code, i = 3
execute the good code
execute the bad code
# handle_signal 11
skip the bad code, i = 5
execute the good code
execute the bad code
# handle_signal 11
skip the bad code, i = 7
execute the good code
execute the bad code
# handle_signal 11
skip the bad code, i = 9
--- I am alive ---
--- I am alive ---
--- I am alive ---
--- I am alive ---

http://www.ppmy.cn/devtools/56086.html

相关文章

初学51单片机之长短键应用定时炸弹及扩展应用

51单片机RAM区域划分 51单片机的RAM分为两个部分&#xff0c;一块是片内RAM&#xff0c;一块是片外RAM。 data&#xff1a; 片内RAM从 0x00 ~0x7F 寻址范围&#xff08;0-127&#xff09; 容量共128B idata: 片外RAM从 0x00~0xFF 寻址范围(0-255) 容量共256B pdata&am…

从复用性角度阐述中台建设

目录 复用性中台定义深思中台建设产品线形态何时演变中台能力落地中台 业务中台架构总结 技术学习永不止步&#xff0c;最近也是看了很多关于架构设计相关的专栏&#xff0c;慢慢总结出来一部分知识&#xff0c;代入自己的思考与理解&#xff0c;以及结合并反思自己之前公司的架…

MCGS仿真教学3:动画的平移

目录 一、绘制图形和按钮功能二、移动动画三、添加功能变量四、添加循环脚本![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/f42c6b18e1cb4dbf8075c389878d3ae7.gif)五、完成演示 一、绘制图形和按钮功能 全部由单个矩形组成 二、移动动画 三、添加功能变量 四、…

Vue项目生产环境的打包优化

Vue项目生产环境的打包优化 前言 在这篇文章我们讨论Vue项目生产环境的打包优化&#xff0c;并按步骤展示实际优化过程中的修改和前后对比。 背景 刚开始的打包体积为48.71M 优化 步骤一&#xff1a;删除viser-vue viser-vue底层依赖antv/g2等库一并被删除&#xff0c;…

iptables(10)target(REJECT、LOG)

简介 前面文章介绍iptables的匹配条件,并且已经用到了一些常用动作,比如ACCEPT、DROP、REJECT等。 以下是 iptables 中常用的一些目标(target)及其原理和时机:ACCEPT 原理:允许数据包通过,并停止对后续规则的匹配。 时机:当你想允许特定的数据包通过防火墙时。DROP 原…

Omni 动画核心运动包 - 为 Unity 游戏开发者带来卓越体验

Omni 动画核心运动包 前言资源包内容领取兑换码 前言 亲爱的 Unity 游戏开发者们&#xff0c;今天要向大家介绍一款令人瞩目的动画资源 - Omni 动画核心运动包。 这个运动包包含了多达 74 个 mocap 运动动画&#xff0c;每一个动画都是由专业演员通过我们先进的人工智能驱动动…

【uniapp】HBuilderx中uniapp项目运行到微信小程序报错Error: Fail to open IDE

HBuilderx中uniapp项目运行到微信小程序报错Error: Fail to open IDE 问题描述 uniapp开发微信小程序&#xff0c;在HBuilderx中运行到微信开发者工具时报错Error: Fail to open IDE 解决方案 1. 查看微信开发者工具端服务端口是否开放 打开微信开发者工具选择&#xff1…

数据恢复篇:适用于Windows 的顶级数据恢复软件

适用于Windows的免费和付费的最佳数据恢复软件 **嘿&#xff0c;我要和大家一起泄露所有的测试工具。在评论中留下您的想法和最喜欢的选择&#xff01; 适用于 Windows 的最佳数据恢复软件 1.奇客数据恢复 奇客数据恢复版是Microsoft操作系统的顶级数据恢复软件应用程序之一&a…