473,500 Members | 1,943 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.learn.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 throwExceptionType1();
typedef void (* throwExceptionType1_Fn)();

#ifdef FIX_VAGUE_LINKAGE

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

char const * ExceptionType1__TypeId =
typeid(DynamicLink::ExceptionType1).name();

#endif

}

#endif

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

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

#include "DynamicLink.h"

#include <stdio.h>

namespace DynamicLink
{

extern "C" void throwExceptionType1()
{
throw a;

}

#ifdef FIX_VAGUE_LINKAGE

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_LINKAGE -g -fpic -o DynamicLinkDriver -ldl
Driver.cpp

#include "DynamicLink.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_LINKAGE

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
{
throwExceptionType1_Fn throwExceptionType1_fn =
(throwExceptionType1_Fn) dlsym(lib, "throwExceptionType1");
throwExceptionType1_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_LINKAGE 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 throwExceptionType1();
typedef void (* throwExceptionType1_Fn)();

#ifdef FIX_VAGUE_LINKAGE

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

char const * ExceptionType1__TypeId =
typeid(DynamicLink::ExceptionType1).name();

#endif

}

#endif

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

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

#include "DynamicLink.h"

#include <stdio.h>

namespace DynamicLink
{

extern "C" void throwExceptionType1()
{
throw a;

}

#ifdef FIX_VAGUE_LINKAGE

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_LINKAGE -g -fpic -o DynamicLinkDriver -ldl
Driver.cpp

#include "DynamicLink.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_LINKAGE

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
{
throwExceptionType1_Fn throwExceptionType1_fn =
(throwExceptionType1_Fn) dlsym(lib, "throwExceptionType1");
throwExceptionType1_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_LINKAGE 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 3366
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 throwExceptionType1();
typedef void (* throwExceptionType1_Fn)();

#ifdef FIX_VAGUE_LINKAGE

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

char const * ExceptionType1__TypeId =
typeid(DynamicLink::ExceptionType1).name();

#endif

}

#endif

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

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

#include "DynamicLink.h"

#include <stdio.h>

namespace DynamicLink
{

extern "C" void throwExceptionType1()
{
throw a;

}

#ifdef FIX_VAGUE_LINKAGE

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_LINKAGE -g -fpic -o DynamicLinkDriver -ldl
Driver.cpp

#include "DynamicLink.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_LINKAGE

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
{
throwExceptionType1_Fn throwExceptionType1_fn =
(throwExceptionType1_Fn) dlsym(lib, "throwExceptionType1");
throwExceptionType1_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_LINKAGE 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.learn.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.linux.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.learn.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.learn.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_LINKAGE 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
{
throwExceptionType1_Fn throwExceptionType1_fn =
(throwExceptionType1_Fn) dlsym(lib, "throwExceptionType1");
throwExceptionType1_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
3242
by: usr2003 | last post by:
I wrote the following test program to test the linkage directives extern "C": #include <stdio.h> extern "C" {
5
10500
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...
20
3194
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...
19
2477
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...
0
1365
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...
3
2225
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...
3
2209
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...
3
3256
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...
3
1820
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...
0
7136
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7018
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...
0
7182
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,...
0
7232
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...
0
5490
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
3110
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1430
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 ...
1
672
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
316
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.