This is the mail archive of the
mailing list for the GCC project.
Re: Duplicate data objects in shared libraries
From: "Jason Merrill" <email@example.com>
> Let me try to summarize the discussion:
> The semantics of existing SVR4 dynamic linkers are such that:
> IF two shared objects A.so and B.so link against the same shared
> library C.so, AND
> both override the same symbol S, AND
> A.so and B.so are loaded in that order with RTLD_LOCAL, THEN
> all references to S from A.so and C.so will resolve to the copy from
> A.so, but references from B.so will resolve to the copy from B.so.
> This is true because:
> There is only one copy of C.so loaded, and its relocs are only
> once, AND
> the definitions from A.so and C.so are not visible when loading B.so.
> This breaks RTTI matching, which relies on all references within a
> program resolving to the same copy. Since references from B.so and C.so
> differ, this premise is violated.
> It is generally agreed that this is unfortunate. Yes?
I agree; I can't speak for others.
> Various solutions present themselves. Most basically, they break down
> 1) Change the dynamic linker so that B.so and C.so agree, AND/OR
> 2) Change the runtime so that it doesn't matter if they don't agree.
> Possible implementations of #1:
> 3) If a library needed by an RTLD_LOCAL object is already loaded, ignore
> and map a new copy. As an optimization, only do this if it refers to
> symbols defined by the RTLD_LOCAL object.
> 4) If a library needed by an RTLD_LOCAL object is already loaded, force
> library to RTLD_GLOBAL status so that references from B.so will use
> already-resolved definition.
> I think #3 is philosophically cleaner.
#3 would be much worse for me than the status quo is. The scenario is that
my clients are writing extension modules loaded with RTLD_LOCAL. In order
to function properly, these modules must share a copy of a common library:
each module "publishes" some data through calls to the common library and
also "subscribes" to all the data in the library. It sounds like ensuring
that the library is actually shared in #3 would be next-to-impossible, and
that even if it were possible my users could easily break sharing
unintentionally by using a some template, inline function or polymorphic
class which is also used by the library.
[I have managed, for the time being, to make my application immune to the
problem we're discussing at the top by arranging for certain exceptions
previously thrown by client code to to be thrown by a function call into
the common library... so they are thrown and caught in the same object. I
don't think such work-arounds will be available for some planned upcoming
#4, or a variation on it, makes much more sense to me.
> Have I missed any arguments?
None that I wouldn't take issue with ;-)
> I am in favor of doing #1 and neutral to positive on #2. As a possible
> point for further discussion, here is an unofficial patch I whipped up a
> week or so ago to do #2 iff -fpic. YMMV.