Thursday, November 11, 2010

C++ exceptions and dynamic loading

[Note: non-geeks can click away right now...]

I just spent a chunk of my afternoon trying to figure out why my C++ exception handlers were not being invoked on Linux, using g++. I could see the exception being thrown in the debugger, but the catch block that caught the exception was the "catch(...)" block, rather than my type-specific block.

It looks like it's a problem with the g++ exception mechanism. What appears to be happening is that the selection of the catch block uses the addresses of type_info blocks, rather than string comparisons on the exception names (which, I've been led to believe, is what Visual Studio C++ does - where my code works fine). If you are using a dynamically loaded module, and there are multiple copies of the RTTI information (easy to do if you are statically linking some libraries, which I am...), and you throw across the loaded module boundary, SPLAT!

This mailing list thread helped me figure this out. I learned a few other useful factoids in the process:

  • gdb's catch command makes it easy to break on exceptions being thrown and caught:
    • catch throw
    • catch catch
  • It's possible to dig around in the g++ runtime system within the body of a catch(...) block and get to the type_info for the exception, which will give you a (platform-dependent) type name - handy for a debug message.
Thank you, web denizens...

No comments:

Post a Comment