【发布时间】:2023-03-06 04:08:01
【问题描述】:
我目前正在用 C/C++ 编写一个小型 VM。显然,如果用户取消对空指针的引用,我不能让整个 VM 崩溃,所以我必须检查每个访问,随着 VM 的增长和更多系统的实施,这些访问变得越来越麻烦。
所以我有一个想法:为 sigsegv 编写一个信号处理程序,让操作系统做它的事情,而不是关闭程序调用 VM 异常处理程序。
它似乎有效(使用我非常简单的测试用例),但我没有找到任何保证 Sigsegv 被抛出 null-derefs 或处理程序被调用用于 OS 生成的信号。
所以我的问题是: 我可以指望现代 destkop 操作系统上的 signal.h 吗(我真的不在乎它是否不是标准的在 linux/win 以外的其他东西上不起作用:这是一个宠物项目)。是否有任何重要的事情我应该注意(signal(...) 或 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 处理,不应该发生。
【问题讨论】:
-
除了取消引用空指针之外,代码还可以取消引用垃圾指针或任何其他类型的无效指针。这不一定会产生信号。因此,除了验证每个指针访问之外,您别无选择。
-
如果您将指针取消引用操作传递给主机操作系统,则它不是 VM。充其量它是一个仿真包装器(尽管不要告诉 WINE 那就是它!)。
-
@Sam Varshavchik:这就是最后一个注释存在的原因:垃圾不应该发生:永远。
-
@OP:不,但您的担心似乎是处理一般的分段错误,而不仅仅是 NULL 指针。例如:
*(int *)(-5) = 1可能会产生段错误,即使它不包含任何 NULL 指针。
标签: c++ c error-handling operating-system signals