信号.h 是捕获空指针的可靠方法吗?
Is signal.h a reliable way to catch null pointers?
我目前正在用C/C++编写一个小VM。显然,如果用户取消引用空指针,我不能让整个 VM 崩溃,所以我必须检查每个访问,随着 VM 的增长和更多系统的实施,这些访问变得越来越麻烦。
所以我有一个想法:为 sigsegv 编写一个信号处理程序,让操作系统做它的事情,而不是关闭程序,调用 VM 异常处理程序。
它似乎可以工作(使用我非常简单的测试用例),但我没有找到任何保证 Sigsegv 被抛出在 null-deref 上的东西,也没有为操作系统生成的信号调用处理程序。
所以我的问题是:我可以指望现代 destkop 操作系统上的 signal.h 吗(我真的不在乎它是否不是标准的,不适用于 linux/win 以外的其他东西:这是一个宠物项目)。我应该注意什么非平凡的事情吗(信号(...)或longjmp(...)的模糊限制?
谢谢!
这是伪实现:
/* ... */
jmp_buf env;
/* ... */
void handler(int) {
longjmp(env, VM_NULLPTR);
}
/* ... */
if(setjmp(env)) {
return vm_throw("NullPtrException");
}
switch(opcode) {
/* instructions */
case INVOKE:
*stack_top = vm_call(stack_top->obj); // don't check anything in the case where stack_top or stack_top->obj is null handler() will be called an a "NullPtrException" will be thrown
break;
/* more instructions */
}
/* ... */
注意:我只需要检查空值,垃圾(悬空)指针由GC处理,不应该发生。
仅当信号处理程序从未从异步信号不安全代码调用信号处理程序时,从信号处理程序调用longjmp()
才是安全的。 因此,例如,如果您可能通过将错误的指针传递给任何printf()
系列函数来接收 SIGSEGV,则无法从信号处理程序中longjmp()
。
我可以在现代 destkop 操作系统上依靠 signal.h 吗
从某种意义上说,您可以依靠它,因为标头及其中的功能将在所有符合标准的系统上可用。但是,究竟抛出什么信号以及何时抛出在操作系统中并不一致。
在Windows上,您可能需要使用cygwin或类似的环境编译程序,以使系统引发分段错误。使用 Visual Studio 编译的程序使用"结构化异常"来处理无效的存储访问。
signal.h 是捕获空指针的可靠方法吗?
在某些情况下,空指针取消引用不会导致引发分段错误信号,即使在 POSIX 系统上也是如此。
- 一种情况可能是编译器优化了操作,例如,在取消引用 null 指针以调用不访问任何数据成员的成员函数的情况下,这是典型的情况。当没有无效的内存访问时,也没有信号。当然,在这种情况下也不会发生崩溃。
- 另一种情况可能是地址 0 实际上是有效的。AIX 就是这种情况,您并不关心。在 Linux 上也是如此,您确实关心这种情况,但不是默认的,您可能会选择不关心它的情况。有关更多详细信息,请参阅此答案。
然后是信号处理程序的实现。 longjmp
不是异步信号安全的,因此如果在执行另一个非安全操作时发出信号,则中断的操作可能使程序处于不一致状态。有关详细信息,请参阅 John Zwinck 的答案和 libc 文档。
- 为什么会出现 gettnig 运行时错误:加载类型为"_Bit_type"(stl_bvector.h) 的空指针?
- 运行时错误:引用绑定到类型为"int"的空指针
- 这个失败的测试是将零添加到空指针未定义的行为、编译器错误还是其他什么?
- 为什么我在空指针错误(链表)中获取成员访问权限
- 从向量到空指针的 memcpy(反之亦然)不起作用
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 成员访问是否在空指针上定义C++?
- 尝试将对象插入空指针数组时出现分段错误
- 为什么我们需要在 C++ 中检查空指针,而在 Java 中不需要?
- 是否允许向空指针添加零?
- 为什么 C 样式字符串的工作空指针检查不?
- 在函数内初始化无符号字符指针将返回空指针
- C++ push() 和 pop() 方法使用指针的动态 LinkedList 的问题
- 为什么多维数组中的空字符串文本衰减为空指针?
- 如何在 Python 中的 SWIG Director 方法中处理空指针
- C 标准的哪一部分涵盖通过空指针调用方法
- 为什么通过空指针调用方法在C++中"有效"?
- 我可以在c++方法中返回空指针吗?
- 信号.h 是捕获空指针的可靠方法吗?
- 什么是返回非空指针的正确方法