在Linux信号处理中longjmp和siglongjmp

Linux 编程之非局部跳转:longjmp siglongjmp 在同一个函数中,我们可以使用 goto 修改程序的执行逻辑。如果在多个函数中,想要修改函数的执行顺序(从一个函数,返回到之前函数的某个预定义逻辑),怎么办呢? 答案是使用 longjmp 或 siglongjmp。 本文主要内容: longjmp 的作用及使用 siglongjmp 的作用及使用 两者的区别 longjmp 的作用及使用 https://man7.org/linux/man-pages/man3/setjmp.3.html longjmp 需要和 setjmp 成对使用。 #includ 阅读详情

以下有一些是我网上搜索到的,觉得写的还行,记录下来以供以后查阅。

void longjmp(jmp_buf env, int val);

void siglongjmp(sigjmp_buf env, int val);

有一点我发现没有人说到,就是这个val,其实它是一个返回值给跳转后的setjmp指令。 但是默认返回值0 是用作第一次做记号,所以如果设置为0,页会返回1作为代替。 


相关函数:longjmp, siglongjmp, setjmp 
表头文件:#include <setjmp.h> 
函数定义:int sigsetjmp(sigjmp_buf env, int savesigs) 
函数说明:sigsetjmp()会保存目前堆栈环境,然后将目前的地址作一个记号,而在程序其他地方调用siglongjmp()时便会直接跳到这个记号位置,然后还原堆栈,继续程序好执行。 
参数env为用来保存目前堆栈环境,一般声明为全局变量 
参数savesigs若为非0则代表搁置的信号集合也会一块保存 
当sigsetjmp()返回0时代表已经做好记号上,若返回非0则代表由siglongjmp()跳转回来。 
返回值  :返回0代表局促存好目前的堆栈环境,随时可供siglongjmp()调用, 若返回非0值则代表由siglongjmp()返回


附加说明:setjmp()和sigsetjmp()会令程序不易令人理解,请尽量不要使用



Linux的异常处理

    基于setjmp和longjmp的运行控制方式是Linux平台上C语言处理异常的标准方案,已被广泛运用到由C语言开发的软件系统和链接库中,例如jpg解析库,加密解密库等等。setjmp和longjmp是以C语言标准库函数的形式提供的,setjmp函数能够保存程序当前的执行环境,即程序的状态,该被保存的程序状态可以在随后程序执行的某一点被longjmp函数恢复,程序的控制流也将跳转到调用setjmp时的执行点,实现非本地局部跳转("non-local goto")的机制。
问题描述:
    在编写基于异常的代码混淆程序时,signal注册的异常信号处理程序只能执行一次,第二次发生异常时异常处理函数没有被调用。
分析:
1. 搞清楚Linux的信号处理流程:
  [1] 收到信号,例如SIGFPE
  [2] 进入signal注册的信号处理函数,此时,SIGFPE自动被加入到进程信号屏蔽字
  [3] 执行信号处理函数
  [4] 信号处理结束,恢复信号屏蔽字,SIGFPE被取消阻塞
  [5] 返回到产生信号地方继续执行
2. 分析异常处理函数没有被调用的原因:
    异常信号处理函数在结束前没有取消对SIGFPE信号的阻塞,直接调用longjmp()进行控制流转移。所以在后面的执行过程中再次遇到SIGFPE信号,系统会自动根据 信号屏蔽字进行屏蔽,异常处理函数也就无法被调用。
3. 该问题的解决办法:
    使用sigsetjmp和siglongjmp函数替换setjmp和longjmp函数。siglongjmp功能与longjmp类似,不同的是siglongjmp会自动恢复进程的信号屏蔽字,因此相同的异常信号再次发生时就不会被系统屏蔽了。

操作系统中的信号与异常:sigsetjmp和siglongjmp【2】 在信号处理程序中经常调用longjmp函数以返回到程序的主流程中,而不是从该处理程序返回。如果用longjmp跳出信号处理程序,那么,对此进程的信号屏蔽字会发生什么呢?(setjmp和longjmp保存和恢复信号屏蔽字,还是不保存和恢复,不同的实现各有不同)这也就是调用longjmp的一个问题 阅读详情

相关推荐

STM32CubeMX 6.4.0 + STM32F407ZGT6 实战:基于YT8512C PHY的lwIP以太网配置与调试

本文详细介绍了使用STM32CubeMX 6.4.0为STM32F407ZGT6微控制器配置YT8512C PHY芯片,并成功移植lwIP以太网协议栈的实战过程。文章从硬件差异分析入手,逐步讲解时钟配置、ETH外设设置、PHY寄存器适配以及lwIP协议栈剪裁等关键步骤,旨在帮助开发者解决非标准PHY芯片的联网难题,最终实现网络连通与Ping测试。

n8m7b6v5c4的博客 592

Linux 信号 longjmp,Linux编程---信号处理

三.阻塞信号阻塞信号意味着告诉操作系统保持该信号并推迟它的发送.被阻塞的信号不会丢失,他们只是暂时被悬挂,直到阻塞解除.1.sigset_t类型的信号操作int sigemptyset(sigset_t *set);int sigfillset(sigset_t *set);int sigaddset(sigset_t *set,int signo);int sigdelset(sigset_t ...

weixin_29430691的博客 213

模型剪枝实战 | Torch-Pruning 库在YOLOv8上的应用指南

本文详细介绍了如何使用Torch-Pruning库对YOLOv8模型进行结构化剪枝,以实现模型“瘦身”。通过DepGraph(依赖图)技术自动处理层间依赖,确保剪枝安全。文章提供了从环境搭建、核心原理理解到完整剪枝流程的实战指南,并强调了剪枝后的微调与性能评估,帮助开发者在保持精度的同时显著提升模型推理速度。

weixin_29046035的博客 502

Linux学习笔记21——sigsetjmp和siglongjmp 信号里的非局部跳转

1,原型 前面提到过,setjmp和longjmp函数可以实现非局部跳转,实现goto语句都不易实现的功能。 上一节又提到过,在进入信号处理程序的时候,我们总是先屏蔽当前的信号,以避免在执行这个信号处理程序的时候又收到了一模一样的信号。当信号处理程序返回时,要先回复信号屏蔽字,解除屏蔽。 现在问题来了,如果在信号处理程序中调用setjmp和longjmp,实现非局部跳转,那信号屏蔽字会恢复吗...

孤独的根号3的博客 876

RC正弦波振荡电路实验全解析:如何通过调节电容电阻改变输出频率

本文深入解析RC正弦波振荡电路,重点阐述如何通过调节电容和电阻来精确改变输出频率。文章从文氏桥振荡电路的核心原理出发,详细介绍了电容粗调频段与电阻微调频率的实操策略,并分析了元件误差、寄生参数等对实测频率的影响,为电路设计与调试提供了从理论到实践的完整指南。

yhn456789的博客 1113

TCS34725颜色识别模块实战调校:从“一坨”例程到精准RGB

本文针对TCS34725颜色识别模块初始数据不准的问题,提供了从基础例程到精准调校的实战指南。核心在于通过白光校正与黑白光校正两种方法,补偿传感器偏差与环境光影响,将原始数据准确映射为标准RGB值。文章详细阐述了校准原理、操作步骤与代码实现,并分享了进阶调试技巧与避坑指南,帮助开发者显著提升颜色识别的准确性与项目可靠性。

weixin_29188043的博客 287

Linux系统调用--signal、setjmp、longjmp、alarm和sleep

这涉及到信号捕获函数的有效性。信号捕获函数一旦被执行,如果不再重新设置信号捕获函数,那下次信号再发生了,触发的是默认的信号捕获函数------也就是会忽略这个信号,什么也不处理。因为在开始的时候设置SIGALRM的信号捕获函数。之后的地方继续执行。之后的地方继续执行?,在这个捕获函数里,使用。后程序为什么不继续回到。超时,但是不处理,再过。

qq_36346625的博客 370

中科蓝讯蓝牙开发:从源码到固件的自动化构建链路解析

本文详细解析了中科蓝讯AB530X蓝牙芯片从源码到最终固件的完整自动化构建链路。通过剖析prebuild.bat、GCC编译、postbuild.bat等关键环节,阐述了资源打包、配置生成、代码编译与固件合成的全过程,并重点介绍了如何实现一键编译与自动下载,为开发者高效进行嵌入式蓝牙开发提供清晰指南。

weixin_29193259的博客 121

【C/C++ 跳转函数】setjmp 和 longjmp 函数的巧妙运用: C 语言错误处理实践

C标准库提供两个特殊的函数:setjmp() 及 longjmp(),这两个函数是结构化异常的基础,正是利用这两个函数的特性来实现异常。 所以,异常的处理过程可以描述为这样: 首先设置一个跳转点(setjmp() 函数可以实现这一功能), 然后在其后的代码中任意地方调用 longjmp() 跳转回这个跳转点上, 以此来实现当发生异常时,转到处理异常的程序上,在其后的介绍中将介绍如何实现。 setjmp() 为跳转返回保存现场并为异常提供处理程序,longjmp() 则进行跳转(抛出异常),setjmp()

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 4377

PS射击游戏射线检测优化:原理、工程与全链路高性能实现

射线池:减少GC,提升批量检测效率。分层检测:先粗后细,远距离射击高效判定。批量检测:并行处理,适合大量射线场景。空间结构:进一步加速大场景检测。下面继续深入射线检测优化,补充更多实用细节和进阶技巧,包括空间分区加速、射线检测多线程/异步化、射线合并与分帧、射线池通用模板、常见性能陷阱与调优建议等。对于极端性能需求,可自定义轻量级物理系统,仅检测关键对象(如玩家、子弹),跳过复杂物理引擎。结合AABB、OBB、球体等简单碰撞体,射线-包围体检测极快。空间分区+分层检测是大场景射线优化核心。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 434

ofd转pdf报错:org.ofdrw.reader.ZipUtil.unZipFileByApacheCommonCompress【已解决】

ofd转pdf报错:java.lang.NoClassDefFoundError:org/apache/commons/io/function/IOIterator at org.ofdrw.reader.ZipUtil.unZipFileByApacheCommonCompress,java.lang.NoSuchMethodError:org.apache.commons.compress.archivers.zip.ZipArchiveInputStream.getNextEntry()

黄团团的个人博客 1283

Linux_C编程—信号处理函数的返回

文章目录信号处理函数执行完怎么办setjmp()/longjmp()sigsetjmp()/siglongjmp() 信号处理函数执行完怎么办 一般来讲,信号处理函数执行完毕都会正常返回,也可以调用其他函数返回到程序的主函数中。这里总结一下信号处理函数执行完毕后跳转到主函数中指定的位置的操作(有点类似goto语句,但goto不支持函数间的跳转,只能在一个函数中跳转),主要是通过俩对函数来实现的: ...

肥宅快乐博客 1398

智能化教育改革中的教师角色转变:AI应用架构师如何设计“人机协同”系统?

个性化与规模化的矛盾:如何用AI实现规模化的个性化学习,同时保留教师的“人文温度”?自动化与自主性的矛盾:如何用AI自动化流程(如批改),同时避免教师沦为“AI操作工人”?数据驱动与经验驱动的矛盾:如何平衡AI的“数据决策”与教师的“经验决策”,避免“算法偏见”或“经验固化”?在智能化教育改革中,教师始终是教育的核心——AI系统是“辅助工具”,而非“替代者”。

小白菜的博客 1269

信号之sigsetjmp和siglongjmp函数

在信号处理程序中经常调用longjmp函数以返回到程序的主循环中,而不是从该处理程序返回。 但是,调用longjmp有一个问题。当捕捉到一个信号时,进入信号捕捉函数,此时当前信号被自动地加到进程的信号屏蔽字中。这阻止了后来产生的这种信号中断该信号处理程序。(仅当从信号捕捉函数返回时再将进程的信号屏蔽字复位为原先值:http://www.cnblogs.com/nufangrensheng/p/3...

weixin_34151004的博客 249

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

linux SIGSEGV 信号捕捉,保证发生段错误后程序不崩溃

在linux中编程的时候 有时候 try catch 可能满足不了我们的需求。因为碰到类似数组越界 ,非法内存访问之类的 ,这样的错误无法捕获。下面我们介绍一种使用捕获信号实现的异常 用来保证诸如段错误之类的错误发生时程序不会崩溃,而是跳过代码继续执行。首先我们来看看发生段错误之后系统的处理。发生段错误后系统会抛出 SIGSEGV 信号 ,之后 调用默认的信号处理函数 ,产生core文件 ,然后关

work_msh的专栏 3万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

context linux,Unix_Linux

Unix_Linux 的 getcontextgetcontext, setcontext -获取或设置用户环境内容简介#include int getcontext(ucontext_t *ucp); int setcontext(const ucontext_t *ucp);where:标签描述ucppoints to a structure defined in containing t...

weixin_30166291的博客 146

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

从信号处理到检查点:计算机系统崩溃恢复原理与实现

计算机系统崩溃恢复是操作系统中异常控制流与上下文切换的典型应用。当程序遭遇段错误或非法指令时,内核通过信号机制通知进程,默认动作往往是终止。用户态程序可以借助sigsetjmp/siglongjmp保存并恢复CPU上下文,配合检查点记录逻辑进度,实现崩溃后从最近一致性点继续执行。这一机制类似于数据库的预写日志和虚拟机快照回滚,体现了检测、保存、恢复三层核心思想。本文从信号处理原理出发,分析非本地跳转的底层行为,结合C语言实现一个自动跳过故障数据并恢复运行的最小示例,并探讨检查点粒度对性能的影响。通过这一实践

weixin_30225755的博客 178

Linux Signal (8): sigsetjmp和siglongjmp

进程部分介绍过了setjmp和longjmp函数, 这两个函数在跳转时会带信号屏蔽字跳转, 在信号处理程序(hanlder)中使用longjmp会导致后来产生的这种信号被屏蔽.POSIX.1 也没有具体说明setjmp和longjmp对信号屏蔽字的作用, 而是定义了两个新函数: sigsetjmp和siglongjmp.1. 原型:#include setjmp.h>int sig

代威涛的主页 1万+

linux信号【5】sigsetjmp和siglongjmp函数

文章目录简述 简述 这两个函数与 s e t j m p和l o n g j m p函数非常相似,都是用于程序的非局部转移。而在信号处理程序中,对应使用的就是sigsetjmp和siglongjmp函数。在信号处理程序中,有时需要返回到序的主循环中,而不是从该处理程序返回。为什么不直接使用 s e t j m p和l o n g j m p呢? 因为用l o n g j m p时有一个问题。当捕捉到一个信号时,进入信号捕捉函数,此时当前信号被 自动地加到进程的信号屏蔽字中。这阻止了后来产生的这种信号中断此信

D&T的博客 643

10.15 sigstjmp以及siglongjmp函数

在7.10节中,我们讲述了setjmp以及longjmp函数,这两个函数用于远程跳转。其中longjmp函数进场在信号处理函数中被调用,用于返回到进程的主循环中去,而不是从信号处理函数中返回。 但是使用函数longjmp有一个问题,当一个信号被捕获的时候,信号处理函数被执行,当前信号将被自动增加到进程的信号掩码中去。这样做的目的是为了防止后续的信号中断当前信号处理函数的执行,如...

Alice816102的博客 256

《Linux C编程实战》笔记:信号处理函数的返回

信号处理函数可以正常返回,也可以调用其他函数返回到程序的主函数中,而不是从处理程序返回。

ouliten的博客 1237

函数setjmp,longjmp和sigsetjmp,siglongjmp

int sigsetjmp(sigjmp_buf env,int savemask); 返回值:若直接调用则返回0,若从siglongjmp调用返回则返回非0值; int siglongjmp(sigjmp_buf env,int val); setjmp和longjmp的使用如下: ...

weixin_30747253的博客 99

非本地跳转函数setjmp,longjmp, sigsetjmp, siglongjmp

非本地跳转 一种用户级的异常控制流形式。将控制直接从一个函数转移到另一个当前正在执行的函数。不需要正常的调用-返回序列(入栈--出栈)  (ps: 系统调用 为异常中陷阱的主要表现形式,参数都是通过通用寄存器而不是栈来传递的)   重要应用:从一个深层嵌套的函数调用中 立即返回。   相关函数:setjmp, longjmp 表头文件:#include 函数定义:int

Just To Be 1881

在信号处理函数中调用longjmp

错误情况及原因分析   前两天看APUE的时候,有个程序要自己制作一个sleep程序,结果在这个程序中就出现了在信号处理函数中调用longjmp函数的情况,结果就出现了错误,具体错误是啥呢,请参见下面这段程序: 1 /* 2 * 在信号处理函数中调用longjmp的错误情况 3 */ 4 #include <errno.h> ...

weixin_30666943的博客 202
上一篇: C语言的STL 库
下一篇: GDB watch if var !=value
Bigengine
博客等级 码龄11年 2粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值