The following code :
main.cpp :
# include <iostream>
# include <csetjmp>
# include <stdexcept>
using namespace std ;
void do_work(jmp_buf context)
{
try
{
throw runtime_error("Ouch !") ;
}
catch(exception & e)
{
}
longjmp(context, -1) ; //BP1
}
int main(int, char *[])
{
jmp_buf context ;
try
{
if( setjmp(context) != 0 )
{
throw runtime_error("Oops !") ; //BP2
}
do_work(context) ;
}
catch(exception & e)
{
cout << "Caught an exception saying : " << e.what() << endl ;
}
}
I tried debugging it but the program behaves strangely. Sometimes I could get past the first breakpoint (BP1), then crash at BP2, and sometimes control never reachs BP1, like if the program is stuck in an infinite loop. I cannot say more with my debugging skills.
This code is the minimal I could get that exhibits the strange behavior with MinGW 4.5. I also noticed that :
do_work
function call by its content, the program runs fine.try{ ... } catch(...){ }
block inside do_work
, the program runs fine.I'm aware of the setjmp/longjmp
issues in C++ code, but I'm forced to use it to interface with some legacy C code.
My question :
Thanks for any advice.
Please retag if necessary.
The longjmp(3) man page on Unix says:
The longjmp() routines may not be called after the routine which called the setjmp() routines returns
I think it explains explains your concern that "sometimes control never reachs BP1". I don't think "runs fine" is reliable judgement. I'd rather expect it randomly runs fine and generally is messing up with stack.
There are a few clear recommendations that should be taken into account while working mixing longjmp/setjmp with C++ exceptions in order to avoid crashes and undefined behaviour:
The question mentions dealing with legacy C code in programs written in C++. There has been an interesting discussion on sjlj issues in jpeg library during review of one of Boost libraries. The discussion was long but here is essence with recommended options.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With