The following code :
- Runs fine when compiled with gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5/32bits)
- Runs fine when compiled with MSVC10 (Win7/32bits)
- Crashes when running with gcc version 4.5.2 (MinGW on Win7/32bits)
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 :
- If I replace the
do_work
function call by its content, the program runs fine. - If I remove the
try{ ... } catch(...){ }
block insidedo_work
, the program runs fine. - Optimization flags have no effect (always crashing).
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 :
- Is this a faulty/buggy/erroneous code ? Or is MinGW 4.5 mishandling the code ? (It is harsh and presumptuous to blame the tool, but I suspect some settings in it).
Thanks for any advice.
Please retag if necessary.
longjmp
andsetjmp
are c functions, invoking them with C++ exception handling semantics and object destruction semantics is undefined behavior, which means its up to the implementation whether it works or not (your testing shows this, the SEH stack unwind semantics break things, depending on the type used, iirc your working ones are using dwarf2)