栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何编写信号处理程序以捕捉SIGSEGV?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何编写信号处理程序以捕捉SIGSEGV?

当您的信号处理程序返回时(假设它不调用exit或longjmp或阻止其实际返回的操作),代码将在发生信号时继续执行,重新执行同一指令。由于此时,内存保护尚未更改,它只会再次抛出信号,并且您将陷入无限循环中的信号处理程序中。

因此,要使其工作,您必须在信号处理程序中调用mprotect。不幸的是,正如Steven
Schansker指出的那样,mprotect不是异步安全的,因此您不能从信号处理程序中安全地调用它。因此,就POSIX而言,您很困惑。

幸运的是,对于大多数实现(据我所知,它是所有现代UNIX和Linux变体),mprotect是系统调用,因此可以从信号处理程序中安全地调用,因此您可以执行大部分所需的操作。问题是,如果您想在读取后重新更改保护,则必须在读取后在主程序中执行此操作。

另一种可能性是对信号处理程序的第三个参数进行操作,该参数指向一个操作系统和特定结构,该结构包含有关信号发生位置的信息。在Linux上,这是_ucontext_结构,其中包含有关$PC地址和发生信号的其他寄存器内容的机器特定信息。如果对此进行了修改,则可以更改信号处理程序将返回的位置,因此可以将$PC更改为仅在错误指令之后,以便它在处理程序返回后不会重新执行。要做到这一点非常棘手(也是不可携带的)。

编辑

所述

ucontext
结构定义
<ucontext.h>
。内的
ucontext
所述字段
uc_mcontext
包含了机器上下文,并在
中,阵列
gregs
包含通用寄存器上下文。因此,在您的信号处理程序中:

ucontext *u = (ucontext *)unused;unsigned char *pc = (unsigned char *)u->uc_mcontext.gregs[REG_RIP];

将为您提供发生异常的电脑。您可以阅读它以找出错误的指令,然后执行其他操作。

就在信号处理程序中调用mprotect的可移植性而言,遵循SVID规范或BSD4规范的任何系统都应该是安全的-
它们允许在信号中调用任何系统调用(手册第2节中的任何内容)处理程序。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/369280.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号