[PATCH] Fix initialization problems with PassRegistry

David Blaikie dblaikie at gmail.com
Wed Jun 11 13:22:53 PDT 2014


On Wed, Jun 11, 2014 at 1:00 PM, Zachary Turner <zturner at google.com> wrote:
> Another alternative is writing to immutable static (not ManagedStatic) data
> structures during static initialization, and then copying them over to the
> ManagedStatics after main begins.
>
> The fundamental problem, at least in my mind, is this scenario:
>
> 1) During static construction, you access a ManagedStatic, causing it to be
> allocated.
> 2) Before main exits, you call llvm_shutdown to destroy ManagedStatics,
> including the one allocated in #1
> 3) During static destruction, you do the inverse operation of what you did
> in #1.  This also accesses a ManagedStatic, after llvm_shutdown has been
> called, and allocates another one.

Yeah, the interaction with llvm_shutdown is painful. So then the
constraint you need is "static dtors don't access ManagedStatics",
that doesn't constrain what their ctors do.

> Plus, it only resolves ordering insofar as the ordering of the static
> constructors is resolved.  Which is to say, not very much.

It resolves it in the sense that, unless they're circular, they do
what you want - anything you depend on is constructed before/when you
need it.

> You get
> deterministic destruction order, but you still get non-deterministic
> construction order, because you dont' know in which order the static
> constructors which use the ManagedStatics will be called in.

Yep, though that's the nature of any lazy thing. This is true of
ManagedStatics even when they aren't used from global ctors.

> On Wed, Jun 11, 2014 at 12:41 PM, David Blaikie <dblaikie at gmail.com> wrote:
>>
>> On Wed, Jun 11, 2014 at 11:54 AM, Zachary Turner <zturner at google.com>
>> wrote:
>> > I might be able to solve the lock problem by just deleting the lock
>> > access from the destructor, as you mention, or making the lock an instance
>> > variable of the PassRegistry class.  But I still think the way I've done is
>> > the only real way to solve the problem with the PassRegistrationListener.
>>
>> It seems like the problem with PassRegistrationListener would be
>> solved by having a static device (other than
>> PassRegistrationListener's ctor itself) that simply doesn't remove the
>> listener in its dtor. The problem being then you change the behavior
>> of non-static PassRegistrationListeners (since you have to remove the
>> registration machinery from PassRegistrationListener's ctor/dtor).
>> Global registration devices are pretty common.
>>
>> All that being said, removing global ctors is a soft goal of the
>> project, so I'm OK doing it for those reasons - I'm just trying not to
>> conflate different goals/problems & understand which things we're
>> doing for what reasons.
>>
>> > Ultimately, the root of the problem is that ManagedStatics are being
>> > accessed during static initialization and shutdown.
>>
>> I don't actually see those things as inherently wrong. Something like
>> a ManagedStatic is the only way to resolve ordering in global init
>> (yes, the alternative is to restrict the project to never have globals
>> that access other globals - but that's not the only correct answer).
>> During destruction is more subtle, certainly.
>>
>> > This needs to be prevented, and I think we need to try to get to a point
>> > where we can actually enforce, by way of asserts, that you cannot touch a
>> > ManagedStatic before main is entered or after it returns.
>> >
>> > http://reviews.llvm.org/D3996
>> >
>> >
>
>



More information about the llvm-commits mailing list