Hi, I have a real serious problem with g++ version 4.2.1 and lower. When I compile the attached code, the exception from the last loaded shared library will not be caught correctly. So basically if I have a shared library that has a function throwing a custom exception and two more shared libraries are linked against it and loaded in an application with dlopen, only the exception thrown in the first loaded library will be caught correctly. The exception from the library loaded second will not be caught with correct type. I attached a simple testcase that shows this behaviour. The output is: Wrapper: caught exception ERROR: caught unknown exception, expected type Exception The expected output is: Wrapper: caught exception Wrapper: caught exception Is it a bug in g++ or do I miss something really important? I searched the web but only found a problem related to a similar problem when throwing an exception from one shared library. This has been resolved by adding the "-Wl,-E" option to the compiler and does not fix my problem. Thanks, Jan --- attachement ------ [classes.h] #ifndef _classes_h_ #define _classes_h_ class ClassA { public: ClassA() {} virtual ~ClassA() {} virtual const char* className() { return "ClassA"; } }; class ClassB : public ClassA { public: ClassB() {} virtual ~ClassB() {} virtual const char* className() { return "ClassB"; } }; ClassA* testClass(); ClassA* testAnotherClass(); #endif [exception.h] #ifndef _exception_h_ #define _exception_h_ #include <exception> class MyException { }; typedef MyException Exception; //typedef std::exception Exception; typedef void* (*Func)(); void testException() throw(Exception); void testAnotherException() throw(Exception); #endif [libtest_a.cpp] #include <stdio.h> #include "exception.h" #include "classes.h" extern "C" { void* wrapTestException() { try { testException(); } catch(Exception &_e) { printf("Wrapper: caught exception\n"); } catch(...) { printf("ERROR: caught unknown exception, expected type Exception\n"); } return NULL; } void* wrapTestClass() { return testClass(); } } [libtest_b.cpp] #include <stdio.h> #include "exception.h" #include "classes.h" extern "C" { void* wrapTestAnotherException() { try { testAnotherException(); } catch(Exception &_e) { printf("Wrapper: caught another exception\n"); } catch(...) { printf("ERROR: caught unknown exception, expected type Exception\n"); } return NULL; } void* wrapTestAnotherClass() { return testAnotherClass(); } } [libutils.cpp] #include "exception.h" #include "classes.h" void testException() throw(Exception) { throw Exception(); } void testAnotherException() throw(Exception) { throw Exception(); } ClassA* testClass() { return new ClassB(); } ClassA* testAnotherClass() { return new ClassB(); } [main.cpp] #include <iostream> #include <dlfcn.h> #include "exception.h" #include "classes.h" using namespace std; Func initFunc(const char *path, const char *funcName) { void *handle; Func proc = NULL; if (!(handle=dlopen(path ,RTLD_LAZY))) { cerr << "Can't open " << path << endl; return NULL; } if (!(proc=(Func)dlsym(handle,funcName))) { cerr << "Can't bind '" << funcName << "'" << endl; return NULL; } return proc; } void testFunc(const char *path, const char *funcName) { Func func = initFunc(path, funcName); if ( func ) { ClassA* c = (ClassA*)func(); if ( c ) { cout << c->className() << endl; if ( dynamic_cast<ClassB*>(c) ) cout << "dynamic_cast<ClassB*> passed" << endl; else cout << "dynamic_cast<ClassB*> failed" << endl; } } } int main(int, char **) { testFunc("libtest_a.so", "wrapTestException"); //testFunc("libtest_a.so", "wrapTestClass"); testFunc("libtest_b.so", "wrapTestAnotherException"); //testFunc("libtest_b.so", "wrapTestAnotherClass"); } [Makefile] GPP=g++ GXX_OPTS=-Wall -v -save-temps all: libutils.so libtest_a.so libtest_b.so testcase testcase: main.cpp libutils.so libtest_a.so libtest_b.so $(GPP) $(GXX_OPTS) -ldl -Wl,-E -o testcase main.cpp libutils.so: libutils.cpp exception.h classes.h $(GPP) $(GXX_OPTS) -fPIC -shared -Wl,-soname,libutils.so -o libutils.so libutils.cpp libtest_a.so: libtest_a.cpp libutils.so $(GPP) $(GXX_OPTS) -fPIC -shared -Wl,-soname,libtest_a.so -L. -o libtest_a.so libtest_a.cpp -lutils libtest_b.so: libtest_b.cpp libutils.so $(GPP) $(GXX_OPTS) -fPIC -shared -Wl,-soname,libtest_b.so -L. -o libtest_b.so libtest_b.cpp -lutils clean: rm -f *.o lib*.so core* a.out testcase -- GMX FreeMail: 1 GB Postfach, 5 E-Mail-Adressen, 10 Free SMS. Alle Infos und kostenlose Anmeldung: http://www.gmx.net/de/go/freemail