-
Notifications
You must be signed in to change notification settings - Fork 26
Description
Source
Stack unwinding is simulated in exception.{h,c} by utilizing the setjmp and longjmp functions from the C standard library. These functions dynamically create for non-local gotos, allowing control flow to be transferred from one function to an arbitrary location in another.
There functions, while useful, carry a subtle "gotcha". When control flow is transferred, whether or not registers are restored is unspecified (it is undefined in GCC, not sure about clang), meaning the values of non-volatile variables with automatic storage duration that have changed between the setjmp and longjmp calls are unspecified.
Example of the UB:
int foo(int);
void bar(int, int);
int main(void)
{
int x = 10, y = 5;
// Do stuff with x and y
try { // setjmp is called in the expansion of `try`
x = foo(y); // x is modified
bar(x,y); // Throws an exception, which calls longjmp
} catch (ANY) {
// x might have been in a register but it's value has (maybe) been clobbered
fprintf(stderr, "The value of x is %d", x);
}
}
Recommendation
I don't think that leaving potentially UB-causing constructs in a library designed for students. I would propose removing this feature and refactoring the library to function without it.