[PATCH] PrettyStackTrace should use ManagedStatic for its ThreadLocal
Reid Kleckner
rnk at google.com
Thu Sep 12 16:38:45 PDT 2013
On Thu, Sep 12, 2013 at 2:13 PM, Filip Pizlo <fpizlo at apple.com> wrote:
>
> How about adding a variant of ManagedStatic that registers the destructor
> with atexit(), just like C++ dynamic initializers do, instead of the LLVM
> shutdown machinery?
>
>
> That wouldn't fix the problem that I'm trying to fix. A library that
> wishes to be used in a larger system shouldn't register atexit() or
> anything like it. That's why I like that ManagedStatic's are only
> destroyed via an explicit call to llvm_shutdown().
>
> Registering atexit() means that you end up with the following situation:
>
> Program A links against library B, which then links against library C.
> Lets say C = llvm.
>
> Library B provides a create/destroy API for its own objects. It does not
> require programs that use it to call destroy, if the object is used as a
> global. This is common. The code base I work with (JavaScriptCore, part
> of WebKit, see webkit.org) has provided just such an API for a long time
> and we intend to continue supporting it.
>
> Library B decides to spawn LLVM compilations concurrently.
>
> Now you get the following exit-time race:
>
> 1) B tells LLVM to compile something on a thread.
> 2) LLVM starts working.
> 3) A calls exit(0).
>
> exit() then calls atexit() handlers and you start destroying
> ManagedStatic's while LLVM is working in a thread.
>
> One of the things that my patches are trying to ensure is that if the
> client of LLVM (in this case library B) isn't itself shut down explicitly
> (something that is common and that we allow with our APIs) then you don't
> get exit-time races, because then the client won't call llvm_shutdown().
> In fact, we're going further in JavaScriptCore: we never call
> llvm_shutdown(), though we do destroy the Context/ExecutionEngine/etc if
> our notion of context (we call it "VM") is destroyed or if we haven't used
> LLVM for a while. Of course, we won't destroy the
> Context/ExecutionEngine/etc if our client calls exit() while we're using
> them on a thread - and we'd like this to Just Work.
>
> I know that you could argue that clients of LLVM should always call
> llvm_shutdown(). This will probably work for a lot of clients where the
> relationship between the outer application and LLVM isn't transitive
> through multiple intervening libraries. We certainly can't change our API
> to require our client to destroy the global VM, and it would be silly if
> that blocked us from ever using LLVM to compile any code due to exit-time
> crashes.
>
You know, clang might not even call llvm_shutdown() if -disable_free is
set, and that should be fine. :)
>
> Then we could convert llvm::outs() to use it, thereby potential
> initialization races on Windows.
>
> Er, "thereby *fixing* potential races"
Interesting. Can you elaborate what the problem is there?
>
llvm::outs() has a static local that closes stdout in its destructor.
Obviously, this *really* has to run atexit, and probably can't run at
llvm_shutdown() time. Alternatively, it shouldn't close stdout.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130912/5ca521f5/attachment.html>
More information about the llvm-commits
mailing list