有什么方法可以将 NULL 指针访问转换为 Linux 下的 C++ 异常?类似于 Java 中的 NullPointerException。我希望以下程序能够成功返回,而不是崩溃(假设编译器在编译期间无法计算出这个 NULL 指针访问):
class NullPointerException {};
void accessNullPointer(char* ptr) {
*ptr = 0;
}
int main() {
try {
accessNullPointer(0);
} catch (NullPointerException&) {
return 1;
}
return 0;
}
我不期待任何标准的方法,因为 C++ 下的 NULL 指针访问是未定义的行为,只是想知道如何在 x86_64 Linux/GCC 下完成它。
我对此做了一些非常原始的研究,有可能:
- 在 Linux 下访问 NULL 指针时,会产生一个 SIGSEGV。
- 在 SIGSEGV 处理程序内部,程序的内存和寄存器信息将可用(如果
sigaction()
用于注册信号处理程序)。如果程序被反汇编,导致 SIGSEGV 的指令也可用。 - 修改程序的内存和/或寄存器,并创建/伪造一个异常实例(可能通过调用低级展开库函数,如_Unwind_RaiseException等)
- 最后从信号处理程序返回,希望程序会像抛出正常异常一样启动 C++ 堆栈展开过程。
这是来自 GCC 手册页(-fnon-call-exceptions)的引用:
生成允许捕获指令抛出异常的代码。请注意,这需要并非随处都存在的特定于平台的运行时支持。此外,它只允许捕获指令抛出异常,即内存引用或浮点指令。它不允许从诸如“SIGALRM”之类的任意信号处理程序中抛出异常。
看来这个“特定于平台的运行时”正是我想要的。有人知道 Linux/x86_64 这样的运行时吗?或者如果不存在这样的运行时,请给我一些关于如何实现这样的运行时的信息?
我希望该解决方案也能在多线程程序中工作。