Exceptions are not caught although they should be

J

Johannes Bauer

Hello group,

yes, I know, this is no language question - but I feel here are the
experts who can help me.

This is the situation: I have a Exception hierarchy, GenericException
has many children. I'm under Linux and load classes dynamically at
runtime using dlopen(). Now the Exception classes are used by both the
..so-files (during linkage) and by the main application.

Now when an exception is thrown by a dynamically loaded shared object,
my main application does not catch it. catch (...) does, but catch
(GenericException &e) doesn't.

It seems to have something to do with linkage or the order of how files
are compiled or linked - because it worked at some point in time. Now it
doesn't anymore and I'm pretty puzzled.

This is how I compile my main application:

g++ -O0 -Wall -g -D_REENTRANT -DTHREADS -DTRACE -DHAVE_BOOST -ICommon
-ldl -lboost_regex -lboost_thread -lboost_program_options -lcfitsio
-lfftw3 -lm -lusb -o ccdsrv ccdsrv.cpp Authentification.o Base64.o
ConnectionHandlerThread.o ListenSocket.o md5.o PictureTest.o
SignalHandler.o TCPConnection.o Testsuite.o Common/Block.o
Common/GenericException.o Common/ModuleHandler.o Common/ModuleInstance.o

This is how I compile the exception class:

g++ -O0 -Wall -g -D_REENTRANT -DTHREADS -DTRACE -DHAVE_BOOST -fPIC
-I../../Common -Weffc++ -c -o ../../Common/GenericException.o
.../../Common/GenericException.cpp

and this is how I link my module:

g++ -O0 -Wall -g -D_REENTRANT -DTHREADS -DTRACE -DHAVE_BOOST -fPIC
-I../../Common -Weffc++ -shared -o ModuleSBIG.so ModuleSBIG.cpp
.../../Common/GenericException.o ../../Common/ModuleInstance.o
.../../Common/Block.o Static.o USB.o SBIGUtils.o

Does anyone see an obvious error that I made?

Kind regards,
Johannes
 
J

Jonathan Lee

Does anyone see an obvious error that I made?

I don't. However, does it matter that your Exception object file is
compiled with fPIC and your main app isn't? It's just a stab in the
dark. But I've had fPIC cause side effects I didn't expect (read:
didn't understand).

--Jonathan
 
S

Space Cowboy

Hello group,

yes, I know, this is no language question - but I feel here are the
experts who can help me.

This is the situation: I have a Exception hierarchy, GenericException
has many children. I'm under Linux and load classes dynamically at
runtime using dlopen(). Now the Exception classes are used by both the
.so-files (during linkage) and by the main application.

Now when an exception is thrown by a dynamically loaded shared object,
my main application does not catch it. catch (...) does, but catch
(GenericException &e) doesn't.

It seems to have something to do with linkage or the order of how files
are compiled or linked - because it worked at some point in time. Now it
doesn't anymore and I'm pretty puzzled.

This is how I compile my main application:

g++ -O0 -Wall -g -D_REENTRANT -DTHREADS -DTRACE -DHAVE_BOOST -ICommon
-ldl -lboost_regex -lboost_thread -lboost_program_options -lcfitsio
-lfftw3 -lm -lusb -o ccdsrv ccdsrv.cpp Authentification.o Base64.o
ConnectionHandlerThread.o ListenSocket.o md5.o PictureTest.o
SignalHandler.o TCPConnection.o Testsuite.o Common/Block.o
Common/GenericException.o Common/ModuleHandler.o Common/ModuleInstance.o

This is how I compile the exception class:

g++ -O0 -Wall -g -D_REENTRANT -DTHREADS -DTRACE -DHAVE_BOOST -fPIC
-I../../Common -Weffc++ -c -o ../../Common/GenericException.o
../../Common/GenericException.cpp

and this is how I link my module:

g++ -O0 -Wall -g -D_REENTRANT -DTHREADS -DTRACE -DHAVE_BOOST -fPIC
-I../../Common -Weffc++  -shared -o ModuleSBIG.so ModuleSBIG.cpp
../../Common/GenericException.o ../../Common/ModuleInstance.o
../../Common/Block.o Static.o USB.o SBIGUtils.o

Does anyone see an obvious error that I made?

See:
http://gcc.gnu.org/faq.html#dso
My guess is that you're passing RTLD_LOCAL to dlopen, or using the
default which is RTLD_LOCAL on Linux IIRC.
 
J

Johannes Bauer

Space said:
See:
http://gcc.gnu.org/faq.html#dso
My guess is that you're passing RTLD_LOCAL to dlopen, or using the
default which is RTLD_LOCAL on Linux IIRC.

While that was not the case (I use RTLD_NOW), the link you posted lead
me to the correct answer: I now export the symbols in the main program
by passing -rdynamic to the linker and threw out all linkings of
GenericException etc. in the modules - now it works beautifully.

THanks for the hint!

Kind regards,
Johannes
 
S

Space Cowboy

While that was not the case (I use RTLD_NOW), the link you posted lead
me to the correct answer: I now export the symbols in the main program
by passing -rdynamic to the linker and threw out all linkings of
GenericException etc. in the modules - now it works beautifully.

Note that these are two separate concerns. There are two orthogonal
options to dlopen in the bitfield parameter. See:
http://www.opengroup.org/onlinepubs/009695399/functions/dlopen.html
NOW vs LAZY, and LOCAL vs GLOBAL. You definitely want GLOBAL.

(And hopefully I got rid of that name SPACE COWBOY. I swear I
accidentally put it. Didn't mean it.)
 
S

Space Cowboy

Note that these are two separate concerns. There are two orthogonal
options to dlopen in the bitfield parameter. See:http://www.opengroup.org/onlinepubs/009695399/functions/dlopen.html
NOW vs LAZY, and LOCAL vs GLOBAL. You definitely want GLOBAL.

(And hopefully I got rid of that name SPACE COWBOY. I swear I
accidentally put it. Didn't mean it.)

Trying one last time to get rid of this name.

Also, to clarify, you probably want RTLD_GLOBAL | RTLD_NOW or
RTLD_GLOBAL | RTLD_LAZY. If you try this in a larger program where 2
different shared libraries dlopen the same shared library, and objects
are passed around between them, you will see this problem again.
Without the GLOBAL flag, you may do a LOCAL load, and this means that
symbols will not be resolved with currently open libraries, which
means that the foo in "catch(foo x)" in one shared library and the foo
in "throw foo();" in another shared library may not match, and the
catch will not catch that exception.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top