473,554 Members | 4,465 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Shared Library Exceptions & Vague Linkage

First of all, sorry for duplicating this post. I put it up in the
alt.comp.lang.l earn.c-c++ mistakenly.

I'm investigating a problem whereby exceptions thrown from functions in
a Shared Library which was dynamically loaded (dlopen) are not properly
caught by the caller. Specifically, when compiling with G++ version
4.0, the RTTI data associated with the exception types is not being
properly aligned between the Shared Library and its caller.

The online manual for GCC describes this as a problem due to its
implementation of Vague Linkage, but does not fully explain how the
problem can be resolved.

I've been able to resolve the problem by taking the typeid of the
exception type before entering the try/catch block in the driver. This
is illustrated in the following code:

// DynamicLink.h
// **************

#ifndef dynamiclink_h
#define dynamiclink_h

#include <typeinfo>

namespace DynamicLink
{
I'm investigating a problem whereby exceptions thrown from functions in
a Shared Library which was dynamically loaded (dlopen) are not properly
caught by the caller. Specifically, when compiling with G++ version
4.0, the RTTI data associated with the exception types is not being
properly aligned between the Shared Library and its caller.

The online manual for GCC describes this as a problem due to its
implementation of Vague Linkage, but does not fully explain how the
problem can be resolved.

I've been able to resolve the problem by taking the typeid of the
exception type before entering the try/catch block in the driver. This
is illustrated in the following code:

// DynamicLink.h
// **************

#ifndef dynamiclink_h
#define dynamiclink_h

#include <typeinfo>

namespace DynamicLink
{

enum ExceptionType1
{
a = 0,
b = 1

};

extern "C" void throwExceptionT ype1();
typedef void (* throwExceptionT ype1_Fn)();

#ifdef FIX_VAGUE_LINKA GE

extern "C" void dumpRTTI();
typedef void (* dumpRTTI_Fn)();

char const * ExceptionType1_ _TypeId =
typeid(DynamicL ink::ExceptionT ype1).name();

#endif

}

#endif

// DynamicLink.cpp
// ***************

// build: g++ -DFIX_VAGUE_LINK AGE -g -shared -o libDynamicLink. so
DynamicLink.cpp

#include "DynamicLin k.h"

#include <stdio.h>

namespace DynamicLink
{

extern "C" void throwExceptionT ype1()
{
throw a;

}

#ifdef FIX_VAGUE_LINKA GE

extern "C" void dumpRTTI()
{
printf("Shared Library side RTTI:\n");
printf("typeid( ExceptionType1) : %s %p\n", ExceptionType1_ _TypeId,
ExceptionType1_ _TypeId);

}

#endif

}

// Driver.cpp
// *********

// build: g++ -DFIX_VAGUE_LINK AGE -g -fpic -o DynamicLinkDriv er -ldl
Driver.cpp

#include "DynamicLin k.h"
using namespace DynamicLink;

#include <stdio.h>
#include <dlfcn.h>

int main(int argv, char const * * arc)
{
void * lib = dlopen("./libDynamicLink. so", RTLD_NOW | RTLD_GLOBAL);

#ifdef FIX_VAGUE_LINKA GE

dumpRTTI_Fn dumpRTTI_fn = (dumpRTTI_Fn) dlsym(lib, "dumpRTTI") ;
dumpRTTI_fn();
printf("Driver side RTTI:\n");
printf("typeid( ExceptionType1) : %s %p\n", ExceptionType1_ _TypeId,
ExceptionType1_ _TypeId);

#endif

try
{
throwExceptionT ype1_Fn throwExceptionT ype1_fn =
(throwException Type1_Fn) dlsym(lib, "throwException Type1");
throwExceptionT ype1_fn();
}
catch (ExceptionType1 & e)
{
printf("caught ExceptionType1: %s %u - %u\n", __FILE__, __LINE__,
(int) e);
}
catch (...)
{
printf("caught unknown exception: %s %u\n", __FILE__, __LINE__);
}

dlclose(lib);

return 0;

}

// END CODE

If you compile the Shared Library and its associated executable driver
using the g++ commands given, then the proper exception handlers will
be executed. If you remove the -DFIX_VAGUE_LINK AGE directive from the
compile commands, then the catch (...) handler is erroniously executed.

The trick is putting the typeid(...) calls in the common header file.
Somehow this seems to resolve the typeid misalignment.

I would like to understand why this method is solving the problem, and
also if there is a better way to go about doing this. I suspect that
there is some combination of compiler / linker commands which can be
used, but I've yet to figure out which ones.

Thank you,

Albert Kennis
enum ExceptionType1
{
a = 0,
b = 1

};

extern "C" void throwExceptionT ype1();
typedef void (* throwExceptionT ype1_Fn)();

#ifdef FIX_VAGUE_LINKA GE

extern "C" void dumpRTTI();
typedef void (* dumpRTTI_Fn)();

char const * ExceptionType1_ _TypeId =
typeid(DynamicL ink::ExceptionT ype1).name();

#endif

}

#endif

// DynamicLink.cpp
// ***************

// build: g++ -DFIX_VAGUE_LINK AGE -g -shared -o libDynamicLink. so
DynamicLink.cpp

#include "DynamicLin k.h"

#include <stdio.h>

namespace DynamicLink
{

extern "C" void throwExceptionT ype1()
{
throw a;

}

#ifdef FIX_VAGUE_LINKA GE

extern "C" void dumpRTTI()
{
printf("Shared Library side RTTI:\n");
printf("typeid( ExceptionType1) : %s %p\n", ExceptionType1_ _TypeId,
ExceptionType1_ _TypeId);

}

#endif

}

// Driver.cpp
// *********

// build: g++ -DFIX_VAGUE_LINK AGE -g -fpic -o DynamicLinkDriv er -ldl
Driver.cpp

#include "DynamicLin k.h"
using namespace DynamicLink;

#include <stdio.h>
#include <dlfcn.h>

int main(int argv, char const * * arc)
{
void * lib = dlopen("./libDynamicLink. so", RTLD_NOW | RTLD_GLOBAL);

#ifdef FIX_VAGUE_LINKA GE

dumpRTTI_Fn dumpRTTI_fn = (dumpRTTI_Fn) dlsym(lib, "dumpRTTI") ;
dumpRTTI_fn();
printf("Driver side RTTI:\n");
printf("typeid( ExceptionType1) : %s %p\n", ExceptionType1_ _TypeId,
ExceptionType1_ _TypeId);

#endif

try
{
throwExceptionT ype1_Fn throwExceptionT ype1_fn =
(throwException Type1_Fn) dlsym(lib, "throwException Type1");
throwExceptionT ype1_fn();
}
catch (ExceptionType1 & e)
{
printf("caught ExceptionType1: %s %u - %u\n", __FILE__, __LINE__,
(int) e);
}
catch (...)
{
printf("caught unknown exception: %s %u\n", __FILE__, __LINE__);
}

dlclose(lib);

return 0;

}

// END CODE

If you compile the Shared Library and its associated executable driver
using the g++ commands given, then the proper exception handlers will
be executed. If you remove the -DFIX_VAGUE_LINK AGE directive from the
compile commands, then the catch (...) handler is erroniously executed.

The trick is putting the typeid(...) calls in the common header file.
Somehow this seems to resolve the typeid misalignment.

I would like to understand why this method is solving the problem, and
also if there is a better way to go about doing this. I suspect that
there is some combination of compiler / linker commands which can be
used, but I've yet to figure out which ones.

Thank you,

Albert Kennis

Jul 25 '06 #1
7 3378
I mixed up the message text - sorry again:

I'm investigating a problem whereby exceptions thrown from functions in
a Shared Library which was dynamically loaded (dlopen) are not properly
caught by the caller. Specifically, when compiling with G++ version
4.0, the RTTI data associated with the exception types is not being
properly aligned between the Shared Library and its caller.

The online manual for GCC describes this as a problem due to its
implementation of Vague Linkage, but does not fully explain how the
problem can be resolved.

I've been able to resolve the problem by taking the typeid of the
exception type before entering the try/catch block in the driver. This
is illustrated in the following code:

// DynamicLink.h
// **************

#ifndef dynamiclink_h
#define dynamiclink_h

#include <typeinfo>

namespace DynamicLink
{

enum ExceptionType1
{
a = 0,
b = 1

};

extern "C" void throwExceptionT ype1();
typedef void (* throwExceptionT ype1_Fn)();

#ifdef FIX_VAGUE_LINKA GE

extern "C" void dumpRTTI();
typedef void (* dumpRTTI_Fn)();

char const * ExceptionType1_ _TypeId =
typeid(DynamicL ink::ExceptionT ype1).name();

#endif

}

#endif

// DynamicLink.cpp
// ***************

// build: g++ -DFIX_VAGUE_LINK AGE -g -shared -o libDynamicLink. so
DynamicLink.cpp

#include "DynamicLin k.h"

#include <stdio.h>

namespace DynamicLink
{

extern "C" void throwExceptionT ype1()
{
throw a;

}

#ifdef FIX_VAGUE_LINKA GE

extern "C" void dumpRTTI()
{
printf("Shared Library side RTTI:\n");
printf("typeid( ExceptionType1) : %s %p\n", ExceptionType1_ _TypeId,
ExceptionType1_ _TypeId);

}

#endif

}

// Driver.cpp
// *********

// build: g++ -DFIX_VAGUE_LINK AGE -g -fpic -o DynamicLinkDriv er -ldl
Driver.cpp

#include "DynamicLin k.h"
using namespace DynamicLink;

#include <stdio.h>
#include <dlfcn.h>

int main(int argv, char const * * arc)
{
void * lib = dlopen("./libDynamicLink. so", RTLD_NOW | RTLD_GLOBAL);

#ifdef FIX_VAGUE_LINKA GE

dumpRTTI_Fn dumpRTTI_fn = (dumpRTTI_Fn) dlsym(lib, "dumpRTTI") ;
dumpRTTI_fn();
printf("Driver side RTTI:\n");
printf("typeid( ExceptionType1) : %s %p\n", ExceptionType1_ _TypeId,
ExceptionType1_ _TypeId);

#endif

try
{
throwExceptionT ype1_Fn throwExceptionT ype1_fn =
(throwException Type1_Fn) dlsym(lib, "throwException Type1");
throwExceptionT ype1_fn();
}
catch (ExceptionType1 & e)
{
printf("caught ExceptionType1: %s %u - %u\n", __FILE__, __LINE__,
(int) e);
}
catch (...)
{
printf("caught unknown exception: %s %u\n", __FILE__, __LINE__);
}

dlclose(lib);

return 0;

}

// END CODE

If you compile the Shared Library and its associated executable driver
using the g++ commands given, then the proper exception handlers will
be executed. If you remove the -DFIX_VAGUE_LINK AGE directive from the
compile commands, then the catch (...) handler is erroniously executed.

The trick is putting the typeid(...) calls in the common header file.
Somehow this seems to resolve the typeid misalignment.

I would like to understand why this method is solving the problem, and
also if there is a better way to go about doing this. I suspect that
there is some combination of compiler / linker commands which can be
used, but I've yet to figure out which ones.

Thank you,

Albert Kennis

Jul 25 '06 #2
On 24 Jul 2006 19:23:05 -0700, "akennis" <a_******@yahoo .comwrote in
comp.lang.c++:
First of all, sorry for duplicating this post. I put it up in the
alt.comp.lang.l earn.c-c++ mistakenly.

I'm investigating a problem whereby exceptions thrown from functions in
a Shared Library which was dynamically loaded (dlopen) are not properly
caught by the caller. Specifically, when compiling with G++ version
4.0, the RTTI data associated with the exception types is not being
properly aligned between the Shared Library and its caller.
[snip]

You're still in the wrong place. C++ does not have or define shared
libraries, dynamic loading, or dlopen().

news:comp.os.li nux.development .apps

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 25 '06 #3

akennis wrote:
First of all, sorry for duplicating this post. I put it up in the
alt.comp.lang.l earn.c-c++ mistakenly.

I'm investigating a problem whereby exceptions thrown from functions in
a Shared Library which was dynamically loaded (dlopen) are not properly
caught by the caller. Specifically, when compiling with G++ version
4.0, the RTTI data associated with the exception types is not being
properly aligned between the Shared Library and its caller.

make certain that you have only one definition of the matching symbols
in all of your exceutable and shared libraries.
I guess this is being caused by having multiple copies of the matching
code inside the excecutable and again inside the shared library

Jul 25 '06 #4

Peter wrote:
make certain that you have only one definition of the matching symbols
in all of your exceutable and shared libraries.
I guess this is being caused by having multiple copies of the matching
code inside the excecutable and again inside the shared library
If the -DFIX_VAGUE_LINK AGE command is removed, then the only code
common between the shared library and the executable are the type &
function declarations in the header file. These are required inorder
to establish the shared library API.

I think that the type_info objects are being compiled into the binaries
automatically, and so these ARE present in both. How can I prevent the
type_info stuff from being compiled into the executable?

Thanks.

Jul 25 '06 #5

akennis wrote:
void * lib = dlopen("./libDynamicLink. so", RTLD_NOW | RTLD_GLOBAL);
....
dlclose(lib);

dlopen belongs into a constructor and dlclose into the matching
destructor.
If dlopen fails throw an exception containing the error information.

Jul 26 '06 #6

akennis wrote:
try
{
throwExceptionT ype1_Fn throwExceptionT ype1_fn =
(throwException Type1_Fn) dlsym(lib, "throwException Type1");
throwExceptionT ype1_fn();
}
catch (ExceptionType1 & e)

it is unlikely that you want to modify the exception inside the catch
block.
Thus catch a const reference of this type.

Jul 26 '06 #7

akennis wrote:
I mixed up the message text - sorry again:

I did not know that it is possible to get the typeid for an
enumeration.
Try again with a class which has at least one virtual function
-- e.g. derived from the standard exception class.

And also -- the call to dlsym() belongs into a C++ wrapper which checks
for success and throws an exception otherwise.
The assumption being that you write such a wrapper only once and reuse
it.
And another assumption being that at the place where you call dlopen()
you don't want to deal with the possibility that it may fail,
but you want to delegate this task to some piece of code up the stack.

Jul 26 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
3248
by: usr2003 | last post by:
I wrote the following test program to test the linkage directives extern "C": #include <stdio.h> extern "C" {
5
10508
by: Oliver | last post by:
Hi, I have a problem with a shared library of mine. I compile the *.o files and then generate the .so lib with: cc -shared libjava_vrpn.so *.o When I then run my program I get an error for an unresolved symbol. The symbols it's looking for are in another library called libvrpn.a, but for some unknown reason the compiler does not uses...
20
3202
by: Steven T. Hatton | last post by:
I just read this in the description of how C++ is supposed to be implemented: "All external object and function references are resolved. Library components are linked to satisfy external references to functions and objects not defined in the current translation. All such translator output is collected into a program image which contains...
19
2488
by: Deniz Bahar | last post by:
Hi, I would like to call one of my functions the exact name as an existing C library function (for example K&R2 exercises asks me to make an atof function). If I don't include the header with the declaration for the C library function (stdlib.h in this case) then define/declare my own function with the same name, am I safe? It seems to...
0
1370
by: George P Boutwell | last post by:
I've got an 'third-party' library that had an library.sln for 2003.. I've opened that in VS 2005. I've modified the library and the test application that are part of that to enabled exceptions (the exceptions that where being used didn't work with /clr, so I changed them to the kind that did), and then I enabled /clr for both of them. The...
3
2240
by: tropos | last post by:
(Platform: Solaris with gmake and native Sun C++ compiler) Problem: If I create a shared object (.so file) and load it into a executable, the loader correctly runs constructors of static objects in the .so file. But if I link the same code statically, with no shared object, then the constructors don't run at all! Why?? Here's an...
3
2213
by: djbaker | last post by:
Greetings, I am trying to create a class library/dll with C++ and I am running into a lot of trouble. I know that this is a C++ forum and not one specific to windows or VS 2005 but I'm hoping someone call help me. I would like to create a class library so that I can put classes that I reuse a lot into their own modules. I played around...
3
3264
by: Bala | last post by:
Hello, I am trying to create a shared library on solaris. The inputs to this library is a source file and then 2 static libraries. I need to call code within the shared library in another application which in turn will use the static libraries for further processing. This is the command i am using to build the shared library
3
1822
by: HelloLinux | last post by:
The following is how I encouted my problems: 1) Compile print.cpp into libprint.so by Sun C++ 5.9.The command is: CC -G -KPIC -o libprint.so print.cpp It succeeds. 2)Compile debug.cpp into libdebug.so by g++ 3.4.6, debug.cpp calls a function defined in libprint.so. The command is: g++ -shared -fPIC -o libdebug.so debug.cpp -lprint -L....
0
7503
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7781
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8017
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
7869
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
1
5421
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5140
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3531
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2003
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1113
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.