bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ld/ld.so: wrapping C++ in C?


From: David Hemming
Subject: ld/ld.so: wrapping C++ in C?
Date: Mon, 7 Oct 2002 06:16:21 -0700 (PDT)

I've been unsuccessfully attempting to build a library
with a C interface to be freestanding, hiding the fact
that the internal implementation makes use of C++. The
symbol table and dependencies look entirely clean.

What exactly are ld and ld.so doing that makes this
implementation visible? If such static binding and
symbol-stripping are impossible using ld, I'd
definitely consider it a bug.

Here's the original posting that nobody (apparently
including Sun) has been able to answer:

I'm interested in finding a robust solution to a
number of bugs relating to incompatible C++ library
ABI versions affecting Sun's Java implementation. Some
relevent bug reports are here:

http://developer.java.sun.com/developer/bugParade/bugs/4389172.html
http://developer.java.sun.com/developer/bugParade/bugs/4694590.html

(I'm only addressing the first of these here, with the
second really being Sun's problem, although the same
solution might apply to both...)

The basic issue is that an application (in this case
the Java VM itself) is built to require the
compatibility version of the C++ support library
libstdc++-libc6.1-1.so.2. I am building a shared
library with a pure C interface, but the functions
make internal use of full C++ functionality. (They may
throw exceptions internally, but of course they are
all caught and do not propagate through the C
interface, which has other error reporting channels.)
This shared library is built with some version of gcc
(RedHat gcc 2.96 by default, but stock 3.1 or 3.2
would be nice) and linked against the appropriate
version of the C++ support library
(libstdc++-libc6.2-2.so.3 for 2.96). As a result, when
the application loads the shared library and the
shared library throws an exception internally, a C++
support function (__rethrow) is called and the whole
process dies with a SEGV. I expect that this is a
result of a symbol conflict or ABI incompatibility
between the two versions of the support library (which
is understandable).

There are a couple of workarounds suggested by Sun in
the above bug report, both of which involve tricking
the executable into loading the new version of the
support library and not the compatibility version.
This seems very nasty to me, and will not be an
acceptable solution in all situations. (As a sidenote,
where precisely are the differences between these two
versions noted? Can I assure that this change is
safe?)

My expectation was that I could simply statically link
the C++ libraries within my shared library, producing
what looked to the application and the dynamic loader
to be a pure C library. Specifying -static to the
linker resulted in a shared library which didn't
*appear* to depend on any other libraries, but the
problems remained. I've also tried running the library
through a version script to tag all the symbols that
don't need to be exported as local. I'm left with a
library whose dynamic symbol table contains my own
entry points (just one, in the simple test), a few
local weak references to pthread functions (what is
the impact of these?), and absolutely nothing else--
no undefined symbols and no global symbols hanging
around to cause conflicts.
With these options in place, I *am* able to avoid
symbol conflicts for my own custom symbols (I've
managed to build an app which dlopens a shared library
where both the app and the shared library
independently depend on yet another library; I am able
to get the main app to call a function in one version
of this extra library and the shared library to call
the same function in a different version.), but this
only makes the JNI loading worse-- the statically
linked shared library causes the VM to abort on the
first call the library instead of when the first
exception is thrown (presumably because it's no longer
doing lazy symbol resolution).

I'm stumped.

What exactly *are* ld and ld.so doing to cause these
problems? My understanding of the load and relocation
process was that a clean "nm -D" assured protection
from these kinds of dynamic linking issues, and that
exporting a pure C interface would free you from
worries about C++ ABI changes...

Is there magic in these tools to help with language
support functions?

What is the correct procedure to build a fully
self-sufficient shared library with a pure C
interface, completely hiding away the fact that the
implementation involves C++?



__________________________________________________
Do you Yahoo!?
Faith Hill - Exclusive Performances, Videos & More
http://faith.yahoo.com




reply via email to

[Prev in Thread] Current Thread [Next in Thread]