This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Minimal GCC/Linux shared lib + EH bug example
----- Original Message -----
From: "Martin v. Loewis" <martin@v.loewis.de>
> "David Abrahams" <david.abrahams@rcn.com> writes:
>
> > No, I'm saying that I'm relying on being *allowed* to use them, and I
don't
> > happen to care whether they're shared in this case.
>
> Well, the "restrictions" document would say "you can use these
> features, but we don't guarantee any specific semantics".
I could live with it if the standard told me that this was undefined
behavior, as long as implementors were inclined to "play nice" and give me
useful semantics I could count on.
The fact that some implementors are inclined to make this undefined
behavior is one reason I want the standard to say something stronger.
> This is the same for the exception handling: you can certainly throw
> any exceptions you want - but the compiler (or run-time system) won't
> guarantee that you can catch them everywhere.
I don't want it to guarantee that they can be caught everywhere. I /would/
like it to tell me precisely where they can and can't be caught, insofar as
it's possible. I'd also like to get you to change what you tell me about
it, but more on that below ;-)
> How could the authors of the compiler, or the authors of Python, know
> which deviations from accepted well-defined behaviour (in this case,
> the ISO C++ standard) are acceptable to you, and which aren't?
Any time you're in the domain of features (like shared libraries) which are
outside the standard, you need to make some judgements about what behaviors
would be most useful and predictable. That's what QOI is all about. I claim
to have a model which makes shared linking more useful and predictable than
what GCC/Linux currently implements. So, the short answer is "they can't
know for sure, but they can try to do the best job possible". I hope they
will.
> What good would be it be if you are happy, but the next user complains
> that all his counters are incorrect? (apart from the fact that I want
> you happy, of course :-)
Don't change anything just for me. A change should be made because it's the
right thing to do. As I've said, though I could get by with an
EH/RTTI-specific patch, what I really want, and what I have in mind, is a
behavior which works better for the next user's counters as well as
everything else.
> > > Also, how do you think you can initialize the static template member?
> > > Through function calls of the class template? Forget it, that might
> > > not work - you are relying here on functions being emitted together
> > > with the instantiation of the static member, and there is no
guarantee
> > > that this will work.
> >
> >
> > I have no idea what the above might mean. I do not happen to be calling
the
> > class template's own function members to initialize its data, but I
can't
> > imagine how it would be a problem unless I were relying on sharing or
> > not-sharing... But I'm not.
>
> Your get_x function above would fail to work if it was a member of the
> template, since you can multiple copies of the block-static variable.
Of course. That's why I put it in a source file in lib1.
> Likewise, if the get_x function is implemented in a static library, it
> will fail to work correctly - even if it is defined the way you wrote
> it.
Again, of course. You seem to be operating on the assumption that users of
shared libraries will expect them to be semantically equivalent to
good-ol'-static linking under all circumstances, and that if we can't make
them equivalent we shouldn't give any guarantees at all. Of course, nobody
but the most naive users have that expectation. Yes, we can make shared
libs act like static libs when they're linked in the usual way, but other
arrangements are quite common, and users have a mental model for those as
well. It's not clear that the model corresponds with reality, of course,
but it's worth supporting well-defined semantics when possible.
> > These /are/ susceptible to the same sort of workaround, using
references
> > (an extra level of indirection, the classic approach!) I wouldn't
expect to
> > see a unique copy unless all instantiating libraries share symbols
globally
> > with one-another.
>
> I think with RTLD_LAZY, you are up for even more surprises, e.g. when
> the local variable and its initialization guard resolve inconsistently.
Yes, I can see that. I think the current Linux/GCC symbol-binding semantics
lead to all sorts of trouble, and should be... dare-I-say-it... fixed.
Just to reiterate (and rephrase) what I think is the right behavior:
1. For each symbol, there is an undirected graph which determines how it is
shared.
2. Nodes of the graph correspond to shared libraries. There is also a node
for the sole executable.
3. At each boundary between nodes where there is global symbol sharing,
either via explicit linking, or via dlopen with RTLD_GLOBAL, an edge is
formed between nodes in a symbol's graph iff the symbol is used (defined or
unresolved) in BOTH nodes
4. A symbol's definition is shared between nodes A and B iff A is reachable
from B in that symbol's graph. Note that this is only true if there is a
continuous chain of global sharing between A and B, and all intermediate
nodes use the symbol as well.
5. Since neighbor nodes which share symbols are already required to have
the same definition of any symbols they have in common, there's no chance
of undesired name collision.
6. Since symbols used by both neighbors will always be shared between
neighbor nodes there's no chance of identity crises like we're seeing
today.
-Dave