TSan runtime library

Hello all,
I am curently strugling to get the TSan runtime library to work. I have cloned the LLVM project, ran the following cmake command:

cmake -G “Unix Makefiles” -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=“clang;compiler-rt” …/llvm

After the build I tried to use the TSan library like:

LD_PRELOAD=/media/data/llvm-project/build/lib/clang/15.0.0/lib/linux/libclang_rt.tsan-x86_64.so /media/data/test1/src/thread_test

But this leads to Segmentation fault. GDB shows the following backtrace:
#0 0x0000000000000000 in ?? ()
#1 0x00007f0ffe7d3339 in __sanitizer::internal_start_thread (func=func@entry=0x7f0ffe7a64c0 <__tsan::BackgroundThread(void*)>, arg=arg@entry=0x0) at /media/data/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp:1778
#2 0x00007f0ffe7a89f5 in __tsan::StartBackgroundThread () at /media/data/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp:503
#3 __tsan::MaybeSpawnBackgroundThread () at /media/data/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp:716
#4 __tsan::MaybeSpawnBackgroundThread () at /media/data/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp:708
#5 0x00007f0ffe738e76 in __interceptor_pthread_create (th=th@entry=0x7fff63af2d20, attr=attr@entry=0x0, callback=0x55629e6c3160 , param=param@entry=0x0)
at /media/data/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp:1022
#6 0x000055629e6c31d7 in main (argc=, argv=) at /media/data/test1/src/thread_test.c:33

When I use the prebuilt TSan library from gcc the same way it works fine:
LD_PRELOAD=/lib/x86_64-linux-gnu/libtsan.so.0 ltrace -x @libtsan.so.0 /media/data/test1/src/thread_test 2>&1 | grep -E ‘pthread*’

pthread_create(0x7ffcd84b22a0, 0, 0x5561fc54b160, 0 <unfinished …>
pthread_create@libtsan.so.0(0x7ffcd84b22a0, 0, 0x5561fc54b160, 0 <unfinished …>
ZN11__sanitizer19real_pthread_createEPvS0_PFS0_S0_ES0@libtsan.so.0(0x7ffcd84b2008, 0, 0x7fa2ae21a150, 0 <unfinished …>
<… ZN11__sanitizer19real_pthread_createEPvS0_PFS0_S0_ES0 resumed> ) = 0
real_pthread_attr_getstack@libtsan.so.0(0x7ffcd84b21d0, 0x7ffcd84b2138, 0x7ffcd84b2140, 0x7fa2ae23b80c) = 0

I am using “Ubuntu 22.04 LTS - JAMMY”

Also, just to mention that ASan library seems to be working:
LD_PRELOAD=/media/data/llvm-project/build/lib/clang/15.0.0/lib/linux/libclang_rt.asan-x86_64.so LSAN_OPTIONS=verbosity=1:log_threads=1 /media/data/test1/src/thread_test

Any ideas what I am doing wrong?
Best Regards,

Just wanted to do a little follow up, maybe someone will someday find this helpful :slight_smile:

I did some more investigation and source code check and here is what I found.

In my build the “initialization” is not called, more precisely the function “void Initialize(ThreadState *thr)” (llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp).
On the other hand when using the prebuilt gcc library this call is made. The printed version of the ThreadSanitizer in our case is v3 while the gcc one is v2.

There are 2 options to call this function:

  1. From “__tsan_init()” which should be linked into the main executable when -fsanitize=thread is in the link flags. This relies on the use of “.preinit_array”, but since we are not building with sanitize flag this is not done.
  2. From “LazyInitialize” in case “.preinit_array” can not be used.
    In my case the function “LazyInitialize” is called but the call to “Initialize(ThreadState *thr)” is inside the compile switch “#if !SANITIZER_CAN_USE_PREINIT_ARRAY”.
    And since in my case SANITIZER_CAN_USE_PREINIT_ARRAY is true the call to “Initialize(ThreadState *thr)” will not exist in the binary.
    To verify this I commented out the compile switch and call to “Initialize(ThreadState *thr)” was made which resulted in no Segfault crash.

If anyone has something to add to this feel free :slight_smile:
Anyway, just wanted to share my findings, might help someone :slight_smile: