Hey everyone, There are bits of information here and there, but I'm trying to get a complete picture of how gcc output interacts with dlopen to produce the results that I'm seeing in my test. I'm having a common exception class `E` and two modules `foo` and `bar` which need to be dlopened from one executable; functions from either module need to be able to catch `E` (if you're wondering, this is for Python extension modules), which for test's sake, they themselves can throw. E inherits from `std::exception`. [main] dlopen(..) <-- foo.so <--------| [e.h] dlopen(..) <-- bar.so <--------| For each module, [main] dlopens `catch_e` function that does a simple try { throw E(); } catch (const E & e) { printf("Caught e!\n" } For base case, * exception is defined entirely in the header. * I use RTLD_LOCAL for dlopen arguments. Now, according to `dlopen` manual, I have to load with RTLD_GLOBAL for RTTI to function properly. But, here are some steps that I want to understand how they work internally with RTLD_LOCAL enabled: * If I dlopen just one module (say foo), everything is dandy * If bar is loaded after that, bar::catch_e() catches general `std::exception` instead of E. * If I have a single `const std::type_info & t_ = typeid(E);` in my `main.cpp`, everything works fine. * Everything is solved if I implemented virtual destructor for my exception in a separate `libe.so` and link foo and bar against it. I think this is why modules catch std::exception instead of E; std::exception is implemented in libstdc++.so The last point seems to be the ultimate remedy, but I only found that resolution searching through a number of blog posts where folks seem to accidentally deduce that from trial and error. My best explanation is that the `typeinfo` from the first binary or DSO that has it becomes the main one; any subsequently loaded DSOs will get a mismatch between the main typeinfo and their internal one. But then why does implementing a virtual method of E in its own module solves the whole thing altogether? What makes [main] properly resolve the typeinfo from both loaded DSOs in that case? It would be great if someone explained how this whole thing works or pointed me to an official gcc/otherwise page that deals with this. I've attached the test case files. Platform info: gcc (Gentoo 4.3.4 p1.0, pie-10.1.5) 4.3.4 Thanks, Dimitri.
Attachment:
ex_test_5.tar.gz
Description: GNU Zip compressed data