In the small reproducer the symbol lookup of the typeinfo/vtable of the exception class with vtable fails. Why is it going wrong? Is it possible to make RTTI work correctly for classes with vtable loaded with dlopen? The purpose of the indirect load is runtime binding based on cpu.
lib.h:
#include <exception>
class myexception : public std::exception {
virtual void info();
};
void f();
lib.cc:
#include "lib.h"
void myexception::info() {};
void f() { throw myexception(); }
main.cc:
#include "lib.h"
int main() {
try { f(); }
catch(myexception) {}
}
stub.cc:
#include <dlfcn.h>
#include <stdlib.h>
__attribute__((constructor)) void init() {
dlopen("libreal.so", RTLD_NOW | RTLD_GLOBAL);
}
build.sh:
g++ lib.cc -Wall -Wextra -shared -o libf.so -fPIC -g
g++ main.cc -Wall -Wextra libf.so -fPIE -g
mv libf.so libreal.so
g++ stub.cc -Wall -Wextra -shared -o libf.so -fPIC -ldl -g
With GCC or clang+libstdc++:
./a.out |& c++filt
./a.out: symbol lookup error: ./a.out: undefined symbol: typeinfo for myexception
, and with clang+libc (or GCC with -fPIC rather than -fPIE):
./a.out |& c++filt
./a.out: symbol lookup error: ./a.out: undefined symbol: vtable for myexception
EDIT: Originally the question stated that the binary compiled with GCC segfaults. This is only the case if the binary is compiled without fPIC/fpic/fPIE/fpie. (Clang doesn't require the flag and the question wasn't updated in respect to the clang behavior). To simplify the question I edited the question to only ask about the runtime linker issue rather than the segfault.