c++multithreadinginterrupt-handlingstack-unwinding

What is the machinery behind stack unwinding?


I'm trying to understand the machinery behind stack unwinding in C++. In other words I'm interested in how this feature is implemented (and whether that is a part of the standard).

So, the thread executes some code until an exception is thrown. When the exception is thrown, what are the threads/interrupt handlers used to record the state and unwind the stack? What is guaranteed by the standard and what is implementation specific?


Solution

  • The thread executes some code until the exception is thrown, and it continues to do so. Exception handling still is C++ code.

    The throw expression creates a C++ object, running in the context of the throwing function. While the constructor of the exception object is running, all objects in the scope of the throwing function are still alive.

    Directly after, however, the stack unwind happens. The C++ compiler will have arranged for a return path that does not require a return object, but which does allow passing of the exception object. Just like a normal return, objects that are local to a function are being destroyed when the function returns. At binary level, this is pretty straightforward: it's just a bunch of destructor calls, and typically a stack pointer is also adjusted.

    What the standard also does not specify, is the mechanism used to determine how many scopes need to be exited. The standard describes in terms of catch, but a typical CPU has no direct equivalent. Hence, this is commonly part of the C++ ABI for a given platform so that compilers sharing a ABI agree. ABI compatibility requires that a caller must catch the exceptions from a callee, even if they've been compiled with different compilers. And obviously, destructors have to be called, so the ABI also needs to arrange that mechanism. The intermediate functions could even have been compiled by a third compiler - as long as they share an ABI, it's all supposed to work.

    As noted in the comments, C++ has no notion of interrupts. If the OS needs something to happen with interrupts, the compiler needs to take care of that. It matters little what exactly the C++ code is doing at that time.