dlopen() and placing exception body in .cpp file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux