当前位置: 首页 > news >正文

C++ SEH结构化异常捕获处理(双平台支持 Linux、Windows)。

测试:

    try_ctor();try_call([](){printf("1111111111111111111111\r\n");int* p = NULL;*p = 100;throw 1;// try_eeh();}, [](){printf("2222222222222222222222\r\n");});

设置NULL指针P的值引发程式崩溃,可以被正确捕获(catch)处理,不支持 finally,可以自己改改,这是一个相对来说较为简洁的实现,该实现的代码可以在WIN、LINUX平台上编译通过且正常就绪运行。

##

try_call 保护代码快调用类似 lua 的 xpcall,try_ctor,注册所需的信号,try_eeh 是回到当前压入栈顶的结构化的异常处理器,vc++ 的seh 结构化处理也是这个处理,可以参考易语言seh结构化异常处理,写这个小哥是用汇编来写的,或者自己反调试看看seh展开的机器代码,思想上这个东西都差不多,但 try_catch 也有缺点,如果栈坏的很彻底就没法恢复了,比如C#.NET,单一时间内异常抛多了,catch 是捕获不了的,毕竟不是java 这类型的语言。

实现:

class __try_context__ final {
public:jmp_buf                                                         __try_jmp_buf;bool                                                            __try_jmp_flg;public:std::function<void()>                                           __try_block;std::function<void()>                                           __try_catch;public:inline __try_context__(): __try_jmp_flg(false) {}
};static thread_local std::list<std::shared_ptr<__try_context__>>     __try_contexts__;
static thread_local std::shared_ptr<__try_context__>                __try_eeh__;static std::shared_ptr<__try_context__> try_seh_pop_context() noexcept {auto tail = __try_contexts__.begin();auto endl = __try_contexts__.end();if (tail == endl) {return NULL;}std::shared_ptr<__try_context__> context = std::move(*tail);__try_contexts__.erase(tail);return context;
}static void try_seh_pop() noexcept {std::shared_ptr<__try_context__> context = try_seh_pop_context();context.reset();
}static void try_seh_eeh_clear() noexcept {__try_eeh__ = NULL;
}static void try_seh_linux(__try_context__* context) noexcept {int32_t signo = setjmp(context->__try_jmp_buf);if (signo == 0) {context->__try_jmp_flg = true;context->__try_block();try_seh_pop();}else {context = __try_eeh__.get();context->__try_catch();}try_seh_eeh_clear();
}#ifdef _MSC_VER
static void try_seh_windows(__try_context__* context) {__try {try_seh_linux(context);}__except (sehCrashFilter(GetExceptionCode(), GetExceptionInformation())) { /* GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH */context->__try_catch();try_seh_pop();try_seh_eeh_clear();}
}
#endifvoid try_call(std::function<void()>&& __try_block, std::function<void()>&& __try_catch) {if (NULL == __try_block) {throw std::runtime_error("__try_block argument not allow is NULL.");}__try_context__* context = NULL;if (NULL == __try_catch) {throw std::runtime_error("__try_catch argument not allow is NULL.");}else{std::shared_ptr<__try_context__> try_context = std::make_shared<__try_context__>();if (NULL == try_context) {throw std::runtime_error("unable to make try context.");}else {context = try_context.get();}try_context->__try_block = std::move(__try_block);try_context->__try_catch = std::move(__try_catch);__try_contexts__.emplace_back(try_context);}#ifdef _MSC_VERtry_seh_windows(context);
#elsetry_seh_linux(context);
#endif
}bool try_eeh() {jmp_buf __try_jmp_buf;for (;;) {{std::shared_ptr<__try_context__> context = try_seh_pop_context();if (NULL == context) {break;}if (!context->__try_jmp_flg) {continue;}else {__try_eeh__ = context;}memcpy(__try_jmp_buf, context->__try_jmp_buf, sizeof(__try_jmp_buf));}longjmp(__try_jmp_buf, 1);return true;}return false;
}void try_ctor() {auto __try_eeh__ = [](int signo) noexcept -> void {bool ok = try_eeh();if (!ok) {signal(signo, SIG_DFL);raise(signo);}};#ifdef __GNUC__signal(SIGTRAP, __try_eeh__);   // 调试陷阱signal(SIGBUS, __try_eeh__);    // 总线错误(常见于结构对齐问题)signal(SIGQUIT, __try_eeh__);   // CTRL+\退出终端signal(SIGSTKFLT, __try_eeh__); // 进程堆栈崩坏
#endifsignal(SIGSEGV, __try_eeh__);   // 段错误(试图访问无效地址)signal(SIGFPE, __try_eeh__);    // 致命的算术运算问题(常见于试图除以零或者FPU/IEEE-754浮点数问题)signal(SIGABRT, __try_eeh__);   // 程式被中止执行(常见于三方库或固有程式遭遇一般性错误执行abort()强行关闭主板程式)signal(SIGILL, __try_eeh__);    // 非法硬件指令(CPU/RING 0 ABORT)
}

相关文章:

C++ SEH结构化异常捕获处理(双平台支持 Linux、Windows)。

测试&#xff1a; try_ctor();try_call([](){printf("1111111111111111111111\r\n");int* p NULL;*p 100;throw 1;// try_eeh();}, [](){printf("2222222222222222222222\r\n");}); 设置NULL指针P的值引发程式崩溃&#xff0c;可以被正确捕获&#xff0…...

jvm-sandbox-repeater 精简版部署之standalone模式

jvm-sandbox-repeater 仅仅提供了录制回放的能力&#xff0c;如果需要完成业务回归、实时监控、压测等平台&#xff0c;后面须要有一个数据中心负责采集数据的加工、存储、搜索&#xff0c;repeater-console提供了简单的demo示例&#xff1b;一个模块管理平台负责管理JVM-Sandb…...

【JavaWeb笔记】单选框,结合Servlet

各个部分的作用 jsp部分 form action"..."&#xff1a;表单标签&#xff0c;供用户提交数据。内部的submit点击之后相当于是点action的URL input type"radio"&#xff1a;输入类型为单选框。把name设置为一样的&#xff0c;这样效果上就是单选&#xff…...

Docker 与 Podman:揭示容器编排的最佳 25 大常见问题解答

让我们告诉你一件事。 这不仅仅是这两个强大平台之间的普通比较。 相反&#xff0c;我们分析并列出了有关 Docker 与 Podman 的最紧迫问题。 但这里有一件事——这些问题不仅被技术角度所包围。 我们还深入研究了业务环境&#xff0c;因为我们知道这不仅仅是关于代码。这是…...

Spark分布式内存计算框架

目录 一、Spark简介 &#xff08;一&#xff09;定义 &#xff08;二&#xff09;Spark和MapReduce区别 &#xff08;三&#xff09;Spark历史 &#xff08;四&#xff09;Spark特点 二、Spark生态系统 三、Spark运行架构 &#xff08;一&#xff09;基本概念 &#x…...

安装python第三方库后,在pycharm中不能正常导入

python小白学习opencv&#xff0c;使用pip安装完opencv库后import cv2报错&#xff0c;按照如下设置解决&#xff1a; 需要正确设置python解释器路径...

从“食”到“用”,燕之屋的未来增长价值几何?

12月12日&#xff0c;燕窝行业头部企业燕之屋在港交所上市。 作为新消费的热门赛道&#xff0c;近年滋补品的关注度一直比较高。“领头燕”登陆资本市场&#xff0c;是消费者健康养生意识不断提高&#xff0c;滋补品成为营养补充主流的一个积极信号。 长期以来&#xff0c;中…...

C++使用策略模式,减少使用switch...case...

目录 原理函数类模板函数使用switch...case...不使用switch...case... 知识点decltypestd::remove_reference 原理 函数 #include <iostream> #include <functional> #include <map>void fun1(int a, int b) {std::cout << "fun1 : a "<…...

.NET 8 编写 LiteDB vs SQLite 数据库 CRUD 接口性能测试(准备篇)

WebAppDbTest 项目准备 项目准备1、.net cli 创建项目2、nuget 包引用和项目结构2.1、项目添加相关 nuget 包2.2、WebAppDbTest 项目结构 3、项目代码说明3.1、CSharp/C# 类文件说明3.2、json 配置文件说明 4、项目运行预览 数据库 .db 文件准备1、创建 SQLite 数据库1.1、在 W…...

2024 年,新程序员如何与AI共赢!!

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

Debian 系统镜像下载

最近在看一些网络相关的文章需要用到 debian 11.x 的系统网上找了好多都发下载&#xff0c;在官网看一下 有个 11.8 的版本我无法下载&#xff0c;提示被最新的 debian-12.4.0 所代替&#xff0c;于是找到了这个链接 Index of /cdimage/unofficial/non-free/cd-including-fi…...

数据结构和算法(全)

1.了解数据结构和算法 1.1 二分查找 二分查找&#xff08;Binary Search&#xff09;是一种在有序数组中查找特定元素的搜索算法。它的基本思想是将数组分成两半&#xff0c;然后比较目标值与中间元素的大小关系&#xff0c;从而确定应该在左半部分还是右半部分继续查找。这个…...

Vue项目中WebSocket封装

WEBSOCKET 封装引入初始化使用 封装 utils下建立WebSocketManager.js class WebSocketManager {constructor() {this.url null;this.websocket null;this.isConnected false;this.listeners {onopen: [],onmessage: [],onclose: [],onerror: [],};this.reconnectionOptio…...

018 OpenCV 人脸检测

目录 一、环境 二、分类器原理 2.1、概述 2.2、工作原理 三、人脸检测代码 一、环境 本文使用环境为&#xff1a; Windows10Python 3.9.17opencv-python 4.8.0.74 二、分类器原理 CascadeClassifier是OpenCV&#xff08;开源计算机视觉库&#xff09;中的一个强大的类…...

Etcd实战(一)-部署etcd集群

1 概述 etcd是一个高可用的分布式键值存储系统&#xff0c;是CoreOS&#xff08;现在隶属于Red Hat&#xff09;公司开发的一个开源项目。它提供了一个简单的接口来存储和检索键值对数据&#xff0c;并使用Raft协议实现了分布式一致性。etcd广泛应用于Docker、Kubernetes等分布…...

Python绘制一个简单的圣诞树

在Python中,你可以使用基本的打印语句和循环来绘制一个简单的圣诞树。以下是一个例子: def draw_christmas_tree(height):for i in range(height):print( * (height - i - 1) +...

【CANoe】CANoe中使用RS232

文章目录 1、CANoe中自带示例2、示例讲解2.1CANoe自带Port A和Port B通讯2.2CANoe自带Port A和串口助手通讯 1、CANoe中自带示例 我使用的事CANoe12&#xff0c;RS232路径如下&#xff1a; C:\Users\Public\Documents\Vector\CANoe\Sample Configurations 12.0.75\IO_HIL\RS23…...

Springboot内置Tomcat线程数优化

Springboot内置Tomcat线程数优化 # 等待队列长度&#xff0c;默认100。队列也做缓冲池用&#xff0c;但也不能无限长&#xff0c;不但消耗内存&#xff0c;而且出队入队也消耗CPU server.tomcat.accept-count1000 # 最大工作线程数&#xff0c;默认200。&#xff08;4核8g内存…...

vue+django 开发环境跨域前后端联调配置

vue环境是127.0.0.1:8080&#xff0c;django环境是127.0.0.1:8000 要解决url相对路径和Axios跨域权限问题。 注意&#xff1a;程序发起了一个 POST 请求&#xff0c;但请求的 URL 没有以斜杠结尾。Django 默认设置是无法执行重定向到带斜杠 URL的。例如&#xff1a;url http:/…...

Apache+mod_jk模块代理Tomcat容器

一、背景介绍 最近在看Tomcat运行架构原理, 正好遇到了AJP协议(Apache JServ Protocol). 顺道来研究下这个AJP协议和具体使用方法. 百度百科是这么描述AJP协议的: AJP&#xff08;Apache JServ Protocol&#xff09;是定向包协议。因为性能原因&#xff0c;使用二进制格式来传输…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...