c++ - 将 NULL 指针访问转换为 Linux/GCC 下的 C++ 异常

标签 c++ linux exception gcc stack-unwinding

有什么方法可以将 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 下完成它。

我在这方面做了一些非常原始的研究,这可能是可能的:

  1. Linux下访问NULL指针时,会产生SIGSEGV。
  2. 在 SIGSEGV 处理程序中,程序的内存和寄存器信息将可用(如果 sigaction() 用于注册信号处理程序)。如果程序被反汇编,导致 SIGSEGV 的指令也可用。
  3. 修改程序的内存和/或寄存器,并创建/伪造一个异常实例(可能通过调用低级展开库函数,如 _Unwind_RaiseException 等)
  4. 最后从信号处理程序返回,希望程序像抛出正常异常一样启动 C++ 堆栈展开过程。

这里引用 GCC 的手册页 (-fnon-call-exceptions):

Generate code that allows trapping instructions to throw exceptions. Note that this requires platform-specific runtime support that does not exist everywhere. Moreover, it only allows trapping instructions to throw exceptions, i.e. memory references or floating point instructions. It does not allow exceptions to be thrown from arbitrary signal handlers such as "SIGALRM".

看来这个“特定于平台的运行时”正是我想要的。有人知道 Linux/x86_64 这样的运行时吗?或者,如果不存在这样的运行时,请给我一些关于如何实现这样的运行时的信息?

我希望该解决方案也适用于多线程程序。

最佳答案

不,没有好的方法,也不应该有。异常由源代码中的 throw 语句抛出。这对于异常安全性推理很重要:您可以查看代码并查看可以抛出异常的位置,也许更重要的是,您可以查看代码并查看异常不会的位置被抛出。如果您所做的几乎任何事情都可能引发异常,那么编写异常安全的代码而不用 catch 子句将其弄得一团糟就变得非常困难。微软在其早期的 C++ 编译器中尝试了这一点:他们在操作系统的结构化异常之上搭载了 C++ 异常处理,结果是一场灾难。

关于c++ - 将 NULL 指针访问转换为 Linux/GCC 下的 C++ 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37672893/

相关文章:

java - ConcurrentModificationException - 无法启动 Activity

java - NullPointerException 和 NoSuchElementException

exception - 为什么 Perl 6 会为我的子集类型抛出 X::AdHoc 异常?

c++ - gcc 3.3.3 支持预编译头文件吗?

c++ - 按 Enter 时 cin 的返回值不为 0

c++ - 如何使 QtCreator 使用 gsl 库进行编译?

linux - 如何要求身份验证和加密访问 Ubuntu 服务器上的文件和数据流端口?

c++ - STL Sort静态函数的使用

c++ - 使用从 mkstemp 生成的文件名

c++ - Armadillo ,如何增长 vector 并获得他的大小?