Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C/C++ implementations where longjmp unwinds?

Are there major C/C++ implementations where the longjmp function "unwinds", i.e. where it interacts with destructors for automatic-storage objects, __attribute__((__cleanup__(...))), POSIX threads cancellation handlers, etc. rather than just restoring the register context saved by setjmp? I'm particularly interested in the existence (or non-existence) of POSIX implementations with this property, but C/C++ in general are also interesting.

For the bounty, I'm looking for a POSIX-conforming or at least POSIX-like system, as opposed to Windows which has already been mentioned.

like image 925
R.. GitHub STOP HELPING ICE Avatar asked Aug 28 '14 20:08

R.. GitHub STOP HELPING ICE


People also ask

Does Longjmp unwind the stack?

In Microsoft C++ code on Windows, longjmp uses the same stack-unwinding semantics as exception-handling code.

Which convention is used to stack unwind in caller?

JSC's Calling Convention This convention is used by the interpreter, the baseline JIT and its optimizing compilers DFG and FTL, such that JS-functions emitted by different compilers are able to interoperate with each other. All arguments are passed on the stack, there are also some additional values passed as argument.


1 Answers

I'm trying to understand the logical goals that are trying to be accomplished here.

The setjmp(3) manual page states:

setjmp() saves the stack context/environment in env for later use by longjmp(3). The stack context will be invalidated if the function which called setjmp() returns.

This says that if you return from the stack context where the setjmp() call was made, you can no longer longjmp back to it. Otherwise, undefined behavior.

Ok, So it seems to me that at the point that a valid longjmp call is made, setjmp must be somewhere in the current stack context. Therefore, a longjmp that unwinds the stack and calls all destructors of auto variables, etc, appears to be logically equivalent to throwing an exception, and catching it at the point the setjmp() call was originally made.

How does throwing and catching an exception is different from your desired setjmp/longjmp semantics? If, say, you had your wished-for setjmp/longjmp implementation, then how does replacing it with an ordinary try/throw, and catching the thrown exception, be different?

The only differences that I could see is the extra inner scope introduced by the try/catch block; while setjmp does not really open a new inner scope.

So, the answer here appears to be very easy: every compliant C++ implementation has a setjmp/longjmp equivalent that has the desired semantics. It's called try/throw/catch.

like image 89
Sam Varshavchik Avatar answered Oct 01 '22 17:10

Sam Varshavchik