SIGSEGV 由“kill”生成时是否特殊?

2023-12-06

我知道SIGSEGV当内核使用它来报告内存访问冲突时,不能忽略它。但是如果我安装一个信号处理程序SIGSEGV什么都不做,然后另一个进程使用kill向我发送该信号,其行为是否与我使用“正常”信号相同(例如SIGUSR1) 反而?


Grijesh Chauhan's answer is technically correct but difficult to understand, so I am going to write out my own exposition of basically the same points. With footnotes.0

Dima asks what happens when one thread installs a do-nothing handler for SIGSEGV and then another thread uses kill1 to generate SIGSEGV on that thread. The one-sentence answer is that the handler runs, does nothing, and then control returns to normal flow within the interrupted thread. Unlike when the kernel generates SIGSEGV as a response to an actual memory access violation, this scenario does not trigger undefined behavior2. However, the intended purpose of SIGSEGV and its friends (SIGBUS, SIGFPE, and SIGILL) is for the kernel to tell your program that it has done something so heinous that there must be a bug, normal execution cannot continue, would you like to clean up a little before you get killed? It is therefore unwise to use them for anything else. There are several signals (SIGUSR1, SIGUSR2, and SIGRTMIN through SIGRTMAX) reserved for each application to use however it likes; you should use one of those instead.


For the longer answer, I am going to crib from the POSIX standard,3 subsection Signal Actions. First, the four signals SIGFPE, SIGILL, SIGSEGV, and SIGBUS, like any other signal, can be delivered "asynchronously"—at no particular time—because some piece of code used a system call (such as kill) to generate them. When this happens, they are treated exactly the same as any other signal whose default "action" happens to be "terminate the program abnormally"; note that many other signals have this property, including those reserved for application use. If your program only ever has to worry about receiving SIGFPE, SIGILL, SIGSEGV, and SIGBUS when they are generated by kill and friends, it can do all of the normal things with them: block them, ignore them, establish signal handlers that do anything that is valid for an asynchronous signal handler,4 receive them via sigwait or signalfd rather than the normal asynchronous system trap-like delivery mechanism.

然而。SIGFPE, SIGILL, SIGSEGV, and SIGBUS也由内核“同步”生成,以响应触发硬件异常的不同类型的错误程序行为,例如尝试访问未映射的内存。同步意味着信号传递立即地在执行有问题的 CPU 指令时,并且在同一线程上,而不是在进程中碰巧使其解锁的任何线程上。我们真的不是在开玩笑“立即”部分:如果有一个信号处理程序,当它执行时,保存的程序计数器将指向导致任何类型的硬件异常的确切指令。内核不允许执行导致 CPU 发出硬件异常的指令,因此 POSIX 表示尝试丢弃这些信号,而不是终止进程或采取一些激烈的恢复操作:

进程在忽略某个事件后的行为是未定义的SIGFPE, SIGILL, SIGSEGV, or SIGBUS信号不是由产生的kill(), sigqueue(), or raise().

(上下文中的“忽略之后”意味着“如果在操作设置为时内核尝试同步生成这些信号之一”SIG_IGN.)

对于不是由kill()、sigqueue()或raise()生成的SIGBUS、SIGFPE、SIGILL或SIGSEGV信号,进程从信号捕获函数正常返回后,进程的行为是未定义的。

(“正常返回”的意思是“不通过调用(sig)longjmp". It is至少就内核而言,展开堆栈并在其他地方恢复执行是有效的;不过,如果您没有充分修复最初导致故障的损坏数据结构,您可能会遇到麻烦。正如 Basile 提到的,扰乱已保存的处理器状态也是有效的,这样“正常”返回就不仅仅是尝试再次运行相同的错误指令;而是返回“正常”状态。但正在做that往往涉及手动解释机器指令和其他此类黑魔法。)

如果任何 SIGFPE、SIGILL、SIGSEGV 或 SIGBUS 信号在被阻塞时生成,则结果是未定义的,除非该信号是由另一个进程的操作或由 Kill()、pthread_kill() 函数之一生成的、raise() 或 sigqueue()。

(我不确定为什么这个措辞与其他两个有点不同;可能只是因为写这个的人具体文档sigprocmask没有与撰写该内容的人协调信号操作的一般文档.)


0 Dima tagged their question "Linux", but I am going to put in this caveat anyway, for the benefit of future readers: Everything I write here should be assumed to apply only to POSIX-conformant operating systems; to first order, that means "all OSes you are likely to encounter, except Windows." The exception is important. Windows has a rather different notion of the relationship between threads and processes than POSIX does, and a completely different (superior!) fundamental mechanism for reporting CPU-generated erroneous-program exceptions. Signals on Windows are emulated by the C library and probably do not behave as I describe.
1 presumably actually pthread_kill.
2 please read this entire series of blog posts
3 specifically, the online copy of The Open Group Base Specifications Issue 7, 2013 edition, which is also "simultaneously" the 2013 edition of IEEE Standard 1003.1, POSIX.
4 not a lot, but more than nothing; there's a list in the "Signal Actions" document, but no fragment ID allowing me to point you right at it.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SIGSEGV 由“kill”生成时是否特殊? 的相关文章

  • 使用 gcc 在 Linux 上运行线程构建块 (Intel TBB)

    我正在尝试为线程构建块构建一些测试 不幸的是 我无法配置 tbb 库 链接器找不到库 tbb 我尝试在 bin 目录中运行脚本 但这没有帮助 我什至尝试将库文件移动到 usr local lib 但这又失败了 任何的意见都将会有帮助 确定您
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • 没有特殊字符的密码验证器

    我是 RegEx 的新手 已经进行了大量搜索 但没有找到任何具体内容 我正在编写一个验证密码字符串的正则表达式 可接受的字符串必须至少具有 4 种字符类型中的 3 种 数字 小写字母 大写字母 特殊字符 我对包含有一个想法 也就是说 如果这
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么

随机推荐

  • 如何使用具有 Java 配置的 CommandLineJobRunner 启动 Spring Batch Job

    我的批处理作业定义在基于 Java 的配置文件中 我已经看到了CommandLineJobRunner可用于启动作业 但作业定义应在 xml 中定义 我想用CommandLineJobRunner运行在基于java的配置中定义的作业 根据这
  • PHP Xpath 提取属性 name="author" 的节点的值

    我正在尝试解析一些 XML 数据以获取某个属性的值 具体来说 我想找到作者 下面是一个非常精简但有效的示例 这R节点重复多次
  • 如何在 pandas DataFrame 中存储行名称和列索引?

    我有一个DataFrame with named行和列索引 import numpy as np import pandas as pd I pd Index a b c d name rows C pd Index col0 col1 c
  • PerformSelectorInBackground 和 NSOperation 子类之间的区别

    我创建了一个用于运行深度计数器循环的测试应用程序 我分别使用performSelector In Background 和 NSOperation 子类在后台线程中运行循环函数 我还使用performSelectorOnMainThread
  • 局部变量还是直接语句?

    我目前正在学习C 我真的很想从一开始就获得良好的编码风格 所以我想听听你们专业人士对这个问题的意见 您是否应该始终 或大部分 使用局部变量进行条件 计算 示例 2 还是直接使用语句同样好 更好 示例 1 示例 1 if double Try
  • 响应中的“Access-Control-Allow-Credentials”标头为“”,必须为“true”

    我在后端使用 Node Express 在客户端使用 Angular4 这给了我以下错误 XMLHttpRequest 无法加载http localhost 4876 登录 检查 对预检请求的响应未通过访问控制检查 响应中 Access C
  • 组合框中的两个项目相同,但第一个总是被选中 C#

    我的 Windows 窗体应用程序上的组合框遇到了非常奇怪的问题 因此 我的组合框是使用数据源填充的 它显示人员姓名 并将其 ID 保存为 cmbRequestor ValueMember public BindingSource requ
  • 搜索文件时 Google Drive API 调用出现问题

    如果您在云端硬盘中创建一个名为 HelloWorld 的文件 然后进行以下 API 调用 https www googleapis com drive v2 files q title contains 世界 该文件不会出现在结果中 它在
  • 安全擦除文件内容

    如何安全删除文件内容 我的意思是数据应该被不可恢复地擦除 因此即使有人 入侵者 取消删除已删除的文件 人们也可能会发现垃圾而不是真正的数据 实际上 您确实不能 因为您不知道使用哪种介质进行存储以及其块是否可以可靠地覆盖 对于包含闪存的移动设
  • 并发连接后 SQL Azure 连接问题

    SQL Azure 数据库上可以建立的并发连接数是否有限制 这就是我面临的情况 我有一个网站 托管在 Windows Server 2008 R2 虚拟机上 许多用户将连接到该虚拟机 并且数据库是在 SQL azure 中创建的 我们观察到
  • 如何通过 iso_c_binding 从 Fortran 调用的 C 函数接收字符串?

    我想从 Fortran 调用 C 函数并接收 C 函数中定义的字符串 我进行了搜索 但到目前为止我找不到有效的 直接的答案 实际上我找到了一个解决方法 接收字符数组 然后使用内部函数transfer将结果放入 Fortran 字符串中 这是
  • Julia 错误:LoadError:ArgumentError:Package xxxx 的依赖项中没有 ExcelReaders:

    所以我从 v0 6 升级到了 Julia v0 7 我正在尝试转换我的代码 我收到以下错误 ERROR LoadError LoadError ArgumentError Package xxx does not have ExcelRea
  • 嵌套函数在 gcc 中是坏事吗? [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 我知道嵌套函数不是标准 C 的一部分 但由于它们存在于 gcc 中 并且 gcc 是我唯一关心的编译器这一事实 所以我倾向于经常使用它们 这是坏事吗 如果是这样 你能给我看一些令人讨厌的例
  • 我可以同时选择和更新吗?

    这是对我正在做的事情的过于简单的解释 我有一个带有状态列的表 应用程序的多个实例将提取第一行的内容 状态为NEW 将状态更新为WORKING然后继续处理内容 通过两次数据库调用即可轻松完成此操作 首先是SELECT那么UPDATE 但我想在
  • 有没有一种方法可以使用 Apache Beam FileIO 为每条记录写入一个文件?

    我正在学习 Apache Beam 并尝试实现类似于 distcp 的东西 我使用 FileIO read filepattern 来获取输入文件 但是在使用 FileIO write 写入时 文件有时会合并 在作业执行之前知道分区计数是不
  • 溢出:隐藏在 Google Chrome 中未按预期工作

    我遇到了 overflow hidden CSS 属性的问题 在 Firefox IE8 和 Safari 5 中 当我将此属性应用于内容顶部用于包含广告横幅 如 adsense 排行榜或 flash 的 div 时 当窗口大小调整为足够小
  • 检测 jQuery 中的输入变化?

    使用jquery时 change on an input仅当输入失去焦点时才会触发该事件 就我而言 一旦输入值发生更改 我需要立即调用服务 检查值是否有效 我怎样才能做到这一点 更新了澄清和示例 例子 http jsfiddle net p
  • Selenium IDE 浏览器插件 3.1.0

    我已经安装了新的 Selenium IDE 3 1 0 Firefox 插件 但我找不到任何工具来导出测试 以便从 Python 驱动程序运行它们 我缺少什么 搜索 SO 仅返回旧版 IDE 的建议 但不返回新 Web 浏览器插件的建议 N
  • java中的位运算符仅适用于整数和长整型?

    我在Eclipse中编写了以下代码 byte b 10 some other operations b b Eclipse 希望在按位补码行中将其强制转换为字节 它说 类型不匹配 无法从 int 转换为 byte 我还尝试了其他按位运算和其
  • SIGSEGV 由“kill”生成时是否特殊?

    我知道SIGSEGV当内核使用它来报告内存访问冲突时 不能忽略它 但是如果我安装一个信号处理程序SIGSEGV什么都不做 然后另一个进程使用kill向我发送该信号 其行为是否与我使用 正常 信号相同 例如SIGUSR1 反而 Grijesh