Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert NULL pointer access to C++ exception under Linux/GCC

Is there any way to convert a NULL pointer access into a C++ exception under Linux ? Something similar to the NullPointerException in Java. I hope the following program would return successfully, instead of crash (assume the compiler cannot figure out this NULL pointer access during compile time):

class NullPointerException {};

void accessNullPointer(char* ptr) {
    *ptr = 0;
}

int main() {
    try {
        accessNullPointer(0);
    } catch (NullPointerException&) {
        return 1;
    }
    return 0;
}

I'm not expecting any standard way of doing it, since NULL pointer access under C++ is undefined-behavior, just want to know how to get it done under x86_64 Linux/GCC.

I did some very primitive research in this, it might be possible:

  1. When a NULL pointer is access under Linux, a SIGSEGV will be generated.
  2. Inside the SIGSEGV handler, the program's memory and register information will be available (if sigaction() is used to register the signal handler). The instruction which caused the SIGSEGV is also available if the program is disassembled.
  3. Modify the program's memory and/or register, and create/fake an exception instance (maybe by invoking the low level unwind library functions, like _Unwind_RaiseException, etc.)
  4. Finally return from the signal handler, hope the program would start a C++ stack unwinding process like a normal exception was thrown.

Here's a quote from GCC's man page (-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".

It seems this "platform-specific runtime" is exactly what I want. Anyone knows such a runtime for Linux/x86_64 ? Or give me some information on how to implement such a runtime if no such runtime already exists ?

I want the solution to work in multi-threaded program as well.

like image 717
user416983 Avatar asked Oct 30 '22 02:10

user416983


1 Answers

No, there's no good way to do that, and there shouldn't be. Exceptions are thrown by a throw statement in source code. That's important for reasoning about exception safety: you can look at the code and see the places where exceptions can be thrown and, perhaps more important, you can look a the code and see the places where exceptions will not be thrown. If pretty much anything you do can throw an exception it becomes very difficult to write exception-safe code without cluttering it with catch clauses. Microsoft tried this in their early C++ compilers: they piggybacked C++ exception handling on top of their OS's structured exceptions, and the result was a disaster.

like image 143
Pete Becker Avatar answered Nov 02 '22 10:11

Pete Becker