[llvm-dev] [TSAN] LLVM statistics and pass initialization trigger race detection

Mehdi Amini via llvm-dev llvm-dev at lists.llvm.org
Fri Apr 15 22:24:42 PDT 2016


Hello,

I trying TSAN on Darwin on LLVM itself (sanitizing multi-threaded ThinLTO link).
However I see two main issues on my debug build: 

1) Statistics: the pre/post increment is not safe, it seems to be acknowledge in the code itself:

    // FIXME: This function and all those that follow carefully use an
    // atomic operation to update the value safely in the presence of
    // concurrent accesses, but not to read the return value, so the
    // return value is not thread safe.

Can we tell TSAN to ignore the statistics somehow? Alternatively, is there a fix someone can suggest?

2) Pass initialization. This macro does not please TSAN (even though it seems written with TSAN in mind):

#define CALL_ONCE_INITIALIZATION(function) \
  static volatile sys::cas_flag initialized = 0; \
  sys::cas_flag old_val = sys::CompareAndSwap(&initialized, 1, 0); \
  if (old_val == 0) { \
    function(Registry); \
    sys::MemoryFence(); \
    TsanIgnoreWritesBegin(); \
    TsanHappensBefore(&initialized); \
    initialized = 2; \
    TsanIgnoreWritesEnd(); \
  } else { \
    sys::cas_flag tmp = initialized; \
    sys::MemoryFence(); \
    while (tmp != 2) { \
      tmp = initialized; \
      sys::MemoryFence(); \
    } \
  } \
  TsanHappensAfter(&initialized);

The failure looks like:

==================
WARNING: ThreadSanitizer: data race (pid=17192)
  Atomic write of size 4 at 0x0001113619e8 by thread T13:
    #0 __tsan_atomic32_compare_exchange_val <null>:568340296 (libclang_rt.tsan_osx_dynamic.dylib+0x00000003e7aa)
    #1 llvm::sys::CompareAndSwap(unsigned int volatile*, unsigned int, unsigned int) Atomic.cpp:52 (libLTO.dylib+0x000000511914)
    #2 llvm::initializeSimpleInlinerPass(llvm::PassRegistry&) InlineSimple.cpp:82 (libLTO.dylib+0x000000ab2b55)
    #3 (anonymous namespace)::SimpleInliner::SimpleInliner() InlineSimple.cpp:50 (libLTO.dylib+0x000000ab2e8e)
    #4 (anonymous namespace)::SimpleInliner::SimpleInliner() InlineSimple.cpp:49 (libLTO.dylib+0x000000ab2d19)
    #5 llvm::createFunctionInliningPass() InlineSimple.cpp:85 (libLTO.dylib+0x000000ab2ce3)
...

  Previous read of size 4 at 0x0001113619e8 by thread T14:
    #0 llvm::initializeSimpleInlinerPass(llvm::PassRegistry&) InlineSimple.cpp:82 (libLTO.dylib+0x000000ab2b65)
    #1 (anonymous namespace)::SimpleInliner::SimpleInliner() InlineSimple.cpp:50 (libLTO.dylib+0x000000ab2e8e)
    #2 (anonymous namespace)::SimpleInliner::SimpleInliner() InlineSimple.cpp:49 (libLTO.dylib+0x000000ab2d19)
    #3 llvm::createFunctionInliningPass() InlineSimple.cpp:85 (libLTO.dylib+0x000000ab2ce3)
...
  Location is global 'llvm::initializeSimpleInlinerPass(llvm::PassRegistry&)::initialized' at 0x0001113619e8 (libLTO.dylib+0x0000016389e8)


Thanks!

Mehdi


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160415/b34ec2a8/attachment.html>


More information about the llvm-dev mailing list