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

为什么不能使用signalfd捕获SIGSEGV?

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

为什么不能使用signalfd捕获SIGSEGV?

请参阅此答案以及该答案以获取详细说明。仔细阅读signal(7)和signal-safety(7)。也请记住,虚拟地址空间的的过程中是常见的,和之间,所有的共享线程是进程。另请参见proc(5)(并使用pmap(1)),并尝试

/proc/self/maps
从您的进程内部进行读取以了解其实际的虚拟地址空间。

概括地说,如果您

SIGSEGV
使用signalfd(2)处理(异步)(在发生异常错误后由内核生成),则好像您安装了“内核”信号处理程序,该信号处理程序神奇地“写入”了某些文件中的某些字节描述符(
signalfd
通过在某个管道上安装信号处理程序,您几乎可以模仿一下;但是可以
signalfd
保证您不会有其他的“原子性”)。

当您从该处理中返回时,机器处于相同状态,因此SIGSEGV再次发生。

如果要处理

SIGSEGV
,则需要使用sigaction(2)或过时的方法
signal(2)
来安装处理例程(因此不能
signalfd
用于SIGSEGV),然后应该

  • (或多或少可移植)避免从您的信号处理程序返回(例如,从安装了sigaction(2)的信号处理程序中调用siglongjmp(3 ))
  • 非便携(在处理器和操作系统的特定方式)改变机器上下文(由第三个参数(一个指向一些处理器具体给出
    ucontext_t
    通过安装)到处理程序
    sigaction
    SA_SIGINFO
    ),例如通过改变一些寄存器,或改变它的地址空间(例如,从处理程序内部调用mmap(2))。

洞察力是输入了SIGSEGV处理程序,并将程序计数器设置为故障机器指令。当您从SIGSEGV处理程序返回时,寄存器处于给定的状态(指针

ucontext_t
作为
sa_sigaction
传递给的函数的第三个参数
sigaction
)。如果不更改该状态,则将重新执行相同的机器指令,并且由于未更改任何内容,因此会发生相同的错误,并且内核会再次发送相同的SIGSEGV信号。

顺便说一句,Ravenbrook
MPS
垃圾收集库是一个巧妙且非便携地处理SIGSEGV的软件的很好示例。它们的写屏障(按照GC的说法)是通过处理SIGSEGV来实现的。这是非常聪明的(非便携式)代码。

注意:实际上,如果您只想显示回溯信息,则可以从

SIGSEGV
处理程序中进行处理(例如,通过使用GCC
libbacktrace
或backtrace(3)然后_exit(2)
-ing而不是从
SIGSEGV
信号处理程序中返回);它不是完美的,并且将永远无法工作(例如,如果您破坏了内存堆),因为您将调用非异步信号安全函数,但实际上效果很好。最近的GCC正在这样做(在编译器(例如
cc1plus
,及其插件)内部),并且对您有很大帮助。



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

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

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