Discussion:
C++ exception in shared library (Abort)
(too old to reply)
Serge Wenger
2005-02-28 15:13:36 UTC
Permalink
Hello,
I cannot catch (in a the main application) a C++ exception thown in a shared
libarary .I receive always an "Abort". If the C++ exception is thrown in the
main program, all is OK.

My gcc version is 3.2.3.

I create a "little" sample to reproduce.

Any idea?

Thanks

Serge

***************** DynLoad.cpp ********************
#include <stdexcept>

void Test ()
{
printf ("Before Throw\n") ;
const char* k_szText = "DynLoad Exception" ;
throw std::logic_error (k_szText) ;
}

***************** testapp.cpp ********************
#include <iostream>
#include <stdexcept>
#include <dlfcn.h>

int main(int argc, char* argv[]) {
std::cout << "C++ dlopen demo 1.0.0.02\n\n";
try {
std::cout << "Before throw inside main" << std::endl ;
throw std::logic_error ("Inside main") ;
}
catch (std::exception &e) {
std::cout << "CATCH "<< e.what() << std::endl ;
}

// open the library
std::cout << "Opening DynLoad.so...\n";
void* handle = dlopen("./libDynLoad.so", RTLD_NOW); // RTLD_NOW

if (!handle) {
std::cerr << "Cannot open library: " << dlerror() << '\n';
return 1;
}

// load the symbol
std::cout << "Loading symbol DynLoad...\n";
typedef void (*hello_t)();
hello_t hello = (hello_t) dlsym(handle, "_Z4Testv");
if (!hello) {
std::cerr << "Cannot load symbol 'DynLoad': " << dlerror() << '\n';
dlclose(handle);
return 1;
}

// use it to do the calculation
std::cout << "Calling hello...\n";
try {

hello();
}
catch (std::exception &e) {
std::cout << "CATCH "<< e.what() ;
}

// close the library
std::cout << "Closing library...\n";
dlclose(handle);
return 0 ;
}
******************Build commands (I cross complile for a ppc
60x)***********************
ppc_60x-g++ -O2 -fmessage-length=132 -I. -fPIC -c DynLoad.cpp
ppc_60x-ld -soname
libDynLoad.so -fmessage-length=132 -shared -L. -L../lib -lc -lstdc++ -olibDynLoad.so
DynLoad.o
ppc_60x-nm libDynLoad.so > DynLoad.txt
ppc_60x-g++ -I. -fmessage-length=132 -c testapp.cpp
ppc_60x-g++ -ot1 testapp.o -lc -ldl -lstdc++
chmod 755 libDynLoad.so
chmod 755 t1

*******************************g++ version
*******************************************
ppc_60x-g++ -v
Reading specs from
/opt/elinos/cdk/ppc/60x/glibc-2.3.2/lib/gcc-lib/powerpc-linux/3.2.3/specs
Configured with:
/home/elinos/ELinOS-Build/babs2/packages/BUILD/gcc-3.2.3/configure --prefix=/opt/elinos/cdk/ppc/60x/glibc-2.3.2
--host=i686-pc-linux-gnu --target=powerpc-linux --enable-c99 --enable-shared
--enable-threads --enable-languages=c,c++,f77,proto --program-transform-name=s,^,ppc_60x-,
--enable-long-long --with-cpu=603 --with-headers=/opt/elinos/cdk/ppc/60x/glibc-2.3.2/powerpc-linux/include
Thread model: posix
gcc version 3.2.3 (ELinOS V3.1 3.2.3-33 2004-12-05)


***************** Results **************************
#./t1
C++ dlopen demo 1.0.0.02

Before throw inside main
CATCH Inside main
Opening DynLoad.so...
Loading symbol DynLoad...
Calling hello...
Before Throw
Abort
Serge Wenger
2005-03-02 08:08:33 UTC
Permalink
Post by Serge Wenger
Post by Serge Wenger
Hello,
I cannot catch (in a the main application) a C++ exception thown in a
shared
Post by Serge Wenger
libarary .I receive always an "Abort". If the C++ exception is thrown
in the
Post by Serge Wenger
main program, all is OK.
My gcc version is 3.2.3.
I create a "little" sample to reproduce.
Any idea?
Thanks
Serge
***************** DynLoad.cpp ********************
#include <stdexcept>
void Test ()
{
printf ("Before Throw\n") ;
const char* k_szText = "DynLoad Exception" ;
throw std::logic_error (k_szText) ;
}
***************** testapp.cpp ********************
#include <iostream>
#include <stdexcept>
#include <dlfcn.h>
int main(int argc, char* argv[]) {
std::cout << "C++ dlopen demo 1.0.0.02\n\n";
try {
std::cout << "Before throw inside main" << std::endl ;
throw std::logic_error ("Inside main") ;
}
catch (std::exception &e) {
std::cout << "CATCH "<< e.what() << std::endl ;
}
// open the library
std::cout << "Opening DynLoad.so...\n";
void* handle = dlopen("./libDynLoad.so", RTLD_NOW); // RTLD_NOW
if (!handle) {
std::cerr << "Cannot open library: " << dlerror() << '\n';
return 1;
}
// load the symbol
std::cout << "Loading symbol DynLoad...\n";
typedef void (*hello_t)();
hello_t hello = (hello_t) dlsym(handle, "_Z4Testv");
if (!hello) {
std::cerr << "Cannot load symbol 'DynLoad': " << dlerror() << '\n';
dlclose(handle);
return 1;
}
// use it to do the calculation
std::cout << "Calling hello...\n";
try {
hello();
}
catch (std::exception &e) {
std::cout << "CATCH "<< e.what() ;
}
// close the library
std::cout << "Closing library...\n";
dlclose(handle);
return 0 ;
}
******************Build commands (I cross complile for a ppc
60x)***********************
ppc_60x-g++ -O2 -fmessage-length=132 -I. -fPIC -c DynLoad.cpp
ppc_60x-ld -soname
libDynLoad.so -fmessage-length=132 -shared -L. -L../lib -lc -lstdc++
-olibDynLoad.so
Post by Serge Wenger
DynLoad.o
ppc_60x-nm libDynLoad.so > DynLoad.txt
ppc_60x-g++ -I. -fmessage-length=132 -c testapp.cpp
ppc_60x-g++ -ot1 testapp.o -lc -ldl -lstdc++
chmod 755 libDynLoad.so
chmod 755 t1
*******************************g++ version
*******************************************
ppc_60x-g++ -v
Reading specs from
/opt/elinos/cdk/ppc/60x/glibc-2.3.2/lib/gcc-lib/powerpc-linux/3.2.3/specs
Post by Serge Wenger
/home/elinos/ELinOS-Build/babs2/packages/BUILD/gcc-3.2.3/configure
--prefix=/opt/elinos/cdk/ppc/60x/glibc-2.3.2
Post by Serge Wenger
--host=i686-pc-linux-gnu --target=powerpc-linux --enable-c99
--enable-shared
Post by Serge Wenger
--enable-threads --enable-languages=c,c++,f77,proto
--program-transform-name=s,^,ppc_60x-,
Post by Serge Wenger
--enable-long-long --with-cpu=603
--with-headers=/opt/elinos/cdk/ppc/60x/glibc-2.3.2/powerpc-linux/include
Post by Serge Wenger
Thread model: posix
gcc version 3.2.3 (ELinOS V3.1 3.2.3-33 2004-12-05)
***************** Results **************************
#./t1
C++ dlopen demo 1.0.0.02
Before throw inside main
CATCH Inside main
Opening DynLoad.so...
Loading symbol DynLoad...
Calling hello...
Before Throw
Abort
I've also ran into same problem. I've found that in some cases, using
the -static-libgcc flag helps. Following the debugger stack-trace,
results in a problem of the shared gcc library. This solution only
helps for some cases. I've no solution, however to the case in which
there is more than one shared object, since in such case the compiler
uses -shared-libgcc in order to allow exception flowing among
shred-objects.
Thanks for your answer, but I think I found another good solution (I follow
gcc bugs 17721, 3993 and found the solution in 4993):

1) Use RTLD_NOW | RTLD_GLOBAL with dlopen
2) Use the following line to buid the application
("-Xlinker -export-dynamic" is the news). You could also use short tags
"-Wl,-E", but I prefer long tags to understand what I do:
ppc_60x-g++ -ot1 testapp.o -lc -ldl -Xlinker -export-dynamic

Thanks for your help

Serge

Loading...