[llvm-dev] call_once and TSan

Dmitry Vyukov via llvm-dev llvm-dev at lists.llvm.org
Fri Sep 2 02:18:22 PDT 2016


On Thu, Sep 1, 2016 at 2:30 PM, Kuba Brecka <kuba.brecka at gmail.com> wrote:
> Hi,
>
> I'm trying to write a TSan interceptor for the C++11 call_once function.  There are currently false positive reports, because the inner __call_once function is located in the (non-instrumented) libcxx library, and on macOS we can't expect the users to build their own instrumented libcxx.
>
> TSan already supports pthread_once and dispatch_once by having interceptors that re-implement the logic.  However, doing the same for call_once/__call_once doesn't work, because call_once is explicitly supposed to be exception-safe, but the sanitizer runtime libraries disallow exception handling.
>
> Any ideas how to handle call_once in TSan?



Does anybody remember exact reasons we disable exceptions in sanitizer
runtimes? One is that it won't link with C programs. Are there any
other?
If C is the only reason: there is already a part of tsan runtime is
linked only to C++ programs (it contains operator new/delete
interceptors). We could add additional files to the cxx part of
runtime and build them with exceptions.

Alternatively, the interceptor can handle only synchronization but
forward actual logic to the real function. Along the lines of:

INTERCEPTOR(call_once, o) {
  __tsan_acquire_release(o);
  REAL(call_once)(o);
}

That will have some performance impact. If we hardcode the "fully
initialized" value, then we can eliminate the additional overhead:

INTERCEPTOR(call_once, o) {
  if (__atomic_load(o, acquire) == FULLY_INITIALIZED) {
     __tsan_acquire(o);
     return;
  }
  __tsan_acquire_release(o);
  REAL(call_once)(o);
}


More information about the llvm-dev mailing list