[PATCH] D39619: Correct atexit(3) support in TSan/NetBSD

Dmitry Vyukov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 8 08:01:45 PST 2017


dvyukov added inline comments.


================
Comment at: lib/tsan/rtl/tsan_interceptors.cc:413
+  // Pop AtExitCtx from the top of the stack of callback functions
+  uptr element = interceptor_ctx()->AtExitStack.Size() - 1;
+  AtExitCtx *ctx = interceptor_ctx()->AtExitStack[element];
----------------
dvyukov wrote:
> krytarowski wrote:
> > dvyukov wrote:
> > > This also needs the mutex for 2 reasons:
> > > 1. It can race with setup_at_exit_wrapper in other threads.
> > > 2. You push onto the stack _after_ calling __cxa_atexit, so if another thread calls exit in between, at_exit_wrapper can see an empty stack.
> > atexit(3) are global, not per-thread.
> > 
> > I'm not convinced that races for 1 can impact execution of `at_exit_wrapper()`.
> > 
> > I agree that someone might try to keep registering new atexit(3) callbacks inside atexit(3) callback functions. I don't know whether this behavior is even defined or real-world.  I think that function-scoped mutex can cause deadlock with callback registration mutex, so I will protect only the access to `AtExitStack`.
> > I'm not convinced that races for 1 can impact execution of at_exit_wrapper().
> 
> Why? One thread executes callbacks, another registers new callbacks. AtExitStack is corrupted as the result. Everything explodes.
> 
> > I agree that someone might try to keep registering new atexit(3) callbacks inside atexit(3) callback functions. 
> 
> That's less of an issue. The problem are other threads that know nothing about process existing yet and continue registering callbacks.
And the second problem is: thread registers callback with __cxa_atexit but don't push onto AtExitStack yes; another thread calls exit and at_exit_wrapper() discovers empty AtExitStack.


Repository:
  rL LLVM

https://reviews.llvm.org/D39619





More information about the llvm-commits mailing list