This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Minimal GCC/Linux shared lib + EH bug example


on 5/14/02 8:10 PM, David Abrahams at david.abrahams@rcn.com wrote:

> This is weird. You snipped out the very thing I was asking about above,
> leaving it looking as though I was asking about your use of terminology...

Sorry for the misunderstanding.

>> David's proposal, I believe amounts to requiring that dynamic linking is
>> handled much more like static linking with a resolution mechanism for
>> duplicate symbols. This proposal would require significantly more
>> sophisticated loaders (than current loaders which usually
>> do a very simple name binding).
> 
> And I was asking you to be more specific about the significant increase in
> sophistication you think would be demanded of loaders.
> 
> I also went on to claim that Linux dynamic linking already provides
> *precisely* the semantics of static linking in the simple case where there
> is no use of RTLD_LOCAL. In other words I challenge your assertions above.

Ahh - I don't have experience with Linux (as I had stated above) I had
assumed that RTLD_LOCAL vs. RTLD_GLOBAL simply referred to whether or not
the data section was reinstantiated. I assume that RTLD_LOCAL is only
available for dlopen and not a mode for a dynamic link. I believe my
assertion holds for many loaders in common use.

> No, we don't care (from a standards point-of-view) whether any code is
> actually shared. However, "identity sharing" is absolutely relevant to this
> thread: the observable behavior differences that can arise in the context
> of shared libraries (if we ignore unloading for the moment) are ALL cases
> of duplication of things which are "supposed" to arise as a single copy:
> two different addresses (and thus values) for the same static member of an
> inline function or function template, two different addresses for the same
> function, two different run-time type identities for the same type, etc.

Problems also arise from two items that are supposed to be joined into a
single item - such as exception handling tables - this may not be an issue
with Linux - it is with CodeWarrior on the Mac however. Also replacements
for operator new and delete lead to two different items of the same name of
which one is supposed to be correct. You also have issues with
initialization order - the runtime environment may not be fully initialized
prior to statics being initialized.
 
> I'm not sure I agree. I think the CFM model where the library is shared
> across processes is strikingly similar to the case we're discussing on
> Linux if you take Martin's view that each library loaded with RTLD_LOCAL
> should be viewed as a separate "program".

It's a little bit reversed - it's a property of the library being linked
against rather than an option on the library being loaded - but it is
similar.

> If you ignore dlopen and dlclose I don't think there's anything mysterious
> about what it means on Unix: from as standards POV, there's nothing to
> discuss because it works like static linking.

That may be what it means on Linux - I think it's a stretch to generalize
that to UNIX. It certainly isn't what it means on Mac or Windows - and I'm
not convinced it is a desirable definition.

> I don't think Windows can be discussed in the same breath, since it is a
> different model and we're not going to be able to force them both into the
> same box, if the box is going to be concrete enough to be useful.

Oh boy - if you can't include Windows in the standard you really don't have
a standard. I hate that (like I hate VPC) but it is reality.

> Please be specific about the language features you feel you can't use on
> Linux in shared libs, and why you think you can't use them... or why
> special considerations about the runtime, etc., are required.

I can't use any of the features portably. I'm not a Linux developer - I
develop primarily on the Mac but everything I do also will have to run on
Windows. It would be nice if it could run on Unix for a couple of our
products - and Palm and PocketPC (really another Windows). Linux isn't
currently on the list. I'll probably move my primary development off CFM to
Mach-O at some point, basically I'm waiting for better tool and library
support for Metrowerks before I do that.

>> I'm perfectly fine with there being restrictions about what
>> can be linked together - in fact I think restrictions are probably
> desirable
>> if they contribute to the encapsulation provided by the library.
> 
> Why is it better for the language designer, rather than the designer of
> library X, to say "You can't link Y to X"?

If the language gives me the control to specify it in my library design -
great. If the language requires that all my static symbols and runtime
symbols be exported than I can't use it. I can't afford to build an economy
where all of the add-ons to my product are revision locked to my product, my
compiler, my runtime. Those become handcuffs to the adoption of my next
release. Solid encapsulation is a good thing.

> The way you avoid that kind of visibility on Unix is with dlopen and
> RTLD_LOCAL. Otherwise, you're discussing a windows-model concept. As a
> cross-platform developer, I think it's important to be able to have this
> kind of hiding, and that's one reason I don't think brushing aside dlopen
> is appropriate.

I think we should come back to dlopen - I agree it is very important. But I
think in order to make it work we first need to settle what it means to
dynamically link a C++ application. The issues of dlopen only add complexity
with regards to scoping and lifespan.

> No, you've misinterpreted it. Furthermore, as I say above, if you don't use
> dlopen it's already equivalent to static linking.

Really? You have all these issue with duplicate symbols that don't get
merged with static linking? I guess I'm running with a very different model
- all my static linking "just works" - and dynamic linking isn't even close
to an equivalent.
 
>> That doesn't get you any of the benefits of dynamic linking other
>> than saving bytes on disk.
> 
> Not true; it gets you component-based development.

What does that buy you if everything is revision locked? You can't afford to
allow separate companies to develop components and you would have to give
them your sources to make it work. Might as static linking it and ship an
updater.
 
>> I'm not sure what you mean about "current
>> semantics if the library load order were changed."
> 
> Let me review, then: In the case I'm talking about, the executable A opens
> two libs B and C with dlopen. B and C each link dynamically to D in the
> usual way. B, C, and D all contain calls to the same inline function which
> has a static counter:
> 
> inline int count()
> {
>   static int n = 0;
>   return n++;
> }
> 
> D also contains the definition of:
> int count2() { return count(); }
> 
> B and C each contain this definition:
> 
> namespace {
> void check_count()
> {
>   int x = count2()
>   assert(x + 1 == count());
> }
> }
> 
> Calling check_count() in B always works, but in C it always asserts. That
> behavior depends on the order in which B and C were loaded. The change I'm
> proposing makes check_count() work in both B and C.

And it would also work that way with a static library? With CFM B, C, and D
would all have unique copies of count and the static so it would always
assert. Unless you exported that symbol (which you would have to look at the
link map to find the name) - in which case you couldn't load because you
would always have a conflict. "Weak" linking wouldn't help - that would only
allow you to load of no copies of the static were present.

To make this work you would have to make count() not be an inlined function,
put it into D, and export.

>> Today, in every loader
>> I'm using, conflicting symbols are an error - not a load order issue.
> 
> Are you sure? The ones we want to be shared without errorare usually hidden
> from you: template instantiations, static variables in inline functions and
> static data members of class templates, type_info, EH info, etc... Most
> implementations use some sort of notion of "weak" symbols to ensure that
> these things always get a single identity in the usual cases.

Quite certain with regards to CFM and the Metrowerks runtime - as I had
noted I had to repackage the runtime to get any kind of dll support to work
at all - I'm quite familiar with what it does and does not support. I also
had to build the export list necessary to get things wired together by
finding mangled names in link maps. Given that CFM was based on (and I
believe is a superset of) XCOFF I'd be surprised if XCOFF worked any
differently (my knowledge of XCOFF and AIX though is about a decade out of
date). I work with Alan Lillich who created CFM though so I'll ask him when
I get a moment.

> Not new/delete; those can be replaced. My proposal is explicitly concerned
> with those runtime-support symbols, though.

Okay - except they aren't always just "symbols" to be aliased (maybe they
are in Linux). It seems rather implementation dependent on the loader
though.

> I guess I just disagree with you there. I don't think the problem on Linux
> is really in the compilers. We can make the compiler do something which
> works around a few of the problems (i.e. by comparing typeinfo::name() for
> EH) but we can't really solve the problems in any meaningful way without
> changing the loader.

I can see that - it sounds like with Linux a lot already just works - great.
But what does work isn't defined to work in the standard, and I'm not sure
it's a reasonable extension to say "because it works on Linux it could be
made to work anywhere." I'm also still not convinced that the Linux
direction is the direction the standard should be going in.

> Okay, now we're in Windows land. That's a completely different domain and
> may require different solutions... but I'm out of time for tonight.

Windows and Mac land - and most of what you are taking for granted just
doesn't work that way on these platforms. Before we jump in to solve the
last bits for Linux I think we need to step back and define what the first
bits are for the standard.

-- 
Sean Parent
Sr. Computer Scientist II
Advanced Technology Group
Adobe Systems Incorporated
sparent@adobe.com



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]