ivmai / bdwgc

The Boehm-Demers-Weiser conservative C/C++ Garbage Collector (bdwgc, also known as bdw-gc, boehm-gc, libgc)
https://www.hboehm.info/gc/
Other
2.98k stars 407 forks source link

Race between GC_clear_block and GC_generic_malloc_aligned called by GC_memalign #537

Open ivmai opened 1 year ago

ivmai commented 1 year ago

Source: master (f21eefa) Build: https://app.travis-ci.com/github/ivmai/bdwgc/jobs/597794274 Host: Ubuntu x64 Compiler: clang How to reproduce: ./configure --disable-parallel-mark && make -j check CFLAGS_EXTRA="-fsanitize=thread -fno-omit-frame-pointer -D NTHREADS=10"

Output (gctest):

Switched to incremental mode
Reading dirty bits from /proc
==================
WARNING: ThreadSanitizer: data race (pid=8657)
  Write of size 8 at 0x7fecc9e240a0 by thread T5 (mutexes: write M4):
    #0 GC_reclaim_clear /home/travis/build/ivmai/bdwgc/extra/../reclaim.c:200:29 (libgc.so.1+0x19d47)
    #1 GC_reclaim_generic /home/travis/build/ivmai/bdwgc/extra/../reclaim.c:324 (libgc.so.1+0x19d47)
    #2 GC_reclaim_small_nonempty_block /home/travis/build/ivmai/bdwgc/extra/../reclaim.c:351:16 (libgc.so.1+0xb175)
    #3 GC_continue_reclaim /home/travis/build/ivmai/bdwgc/extra/../reclaim.c:706 (libgc.so.1+0xb175)
    #4 GC_allocobj /home/travis/build/ivmai/bdwgc/extra/../alloc.c:1745 (libgc.so.1+0xb175)
    #5 GC_generic_malloc_inner /home/travis/build/ivmai/bdwgc/extra/../malloc.c:188 (libgc.so.1+0xb175)
    #6 GC_generic_malloc_aligned /home/travis/build/ivmai/bdwgc/extra/../malloc.c:248:18 (libgc.so.1+0x17a8d)
    #7 GC_generic_malloc /home/travis/build/ivmai/bdwgc/extra/../malloc.c:292:12 (libgc.so.1+0x17edb)
    #8 GC_malloc_kind_global /home/travis/build/ivmai/bdwgc/extra/../malloc.c:329 (libgc.so.1+0x17edb)
    #9 GC_malloc_kind /home/travis/build/ivmai/bdwgc/extra/../thread_local_alloc.c:187:5 (libgc.so.1+0x17973)
    #10 GC_malloc /home/travis/build/ivmai/bdwgc/extra/../malloc.c:348:12 (libgc.so.1+0x1ab6d)
    #11 GC_memalign /home/travis/build/ivmai/bdwgc/extra/../mallocx.c:521 (libgc.so.1+0x1ab6d)
    #12 GC_posix_memalign /home/travis/build/ivmai/bdwgc/extra/../mallocx.c:551:18 (libgc.so.1+0x1acdc)
    #13 run_one_test /home/travis/build/ivmai/bdwgc/tests/gctest.c:1632:17 (lt-gctest+0x4b2d06)
    #14 thr_run_one_test /home/travis/build/ivmai/bdwgc/tests/gctest.c:2518:5 (lt-gctest+0x4b4463)
    #15 GC_pthread_start_inner /home/travis/build/ivmai/bdwgc/pthread_start.c:55:12 (libgc.so.1+0x3cb30)
    #16 GC_call_with_stack_base /home/travis/build/ivmai/bdwgc/extra/../misc.c:2169:14 (libgc.so.1+0x2a651)
    #17 GC_pthread_start /home/travis/build/ivmai/bdwgc/extra/../pthread_support.c:2375 (libgc.so.1+0x2a651)
  Previous write of size 8 at 0x7fecc9e240a0 by thread T4:
    #0 memset /tmp/final/llvm.src/projects/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:764:3 (lt-gctest+0x430789)
    #1 GC_generic_malloc_aligned /home/travis/build/ivmai/bdwgc/extra/../malloc.c:282:13 (libgc.so.1+0x17c9f)
    #2 GC_memalign /home/travis/build/ivmai/bdwgc/extra/../mallocx.c:515:29 (libgc.so.1+0x1aae3)
    #3 GC_valloc /home/travis/build/ivmai/bdwgc/extra/../mallocx.c:566:12 (libgc.so.1+0x1ad61)
    #4 run_one_test /home/travis/build/ivmai/bdwgc/tests/gctest.c:1637:21 (lt-gctest+0x4b2d21)
    #5 thr_run_one_test /home/travis/build/ivmai/bdwgc/tests/gctest.c:2518:5 (lt-gctest+0x4b4463)
    #6 GC_pthread_start_inner /home/travis/build/ivmai/bdwgc/pthread_start.c:55:12 (libgc.so.1+0x3cb30)
    #7 GC_call_with_stack_base /home/travis/build/ivmai/bdwgc/extra/../misc.c:2169:14 (libgc.so.1+0x2a651)
    #8 GC_pthread_start /home/travis/build/ivmai/bdwgc/extra/../pthread_support.c:2375 (libgc.so.1+0x2a651)
  Mutex M4 (0x7feccbc5f810) created at:
    #0 pthread_mutex_trylock /tmp/final/llvm.src/projects/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:1210:3 (lt-gctest+0x4284de)
    #1 GC_start_rtn_prepare_thread /home/travis/build/ivmai/bdwgc/extra/../pthread_support.c:2333:5 (libgc.so.1+0x29dc0)
    #2 GC_pthread_start_inner /home/travis/build/ivmai/bdwgc/pthread_start.c:50:17 (libgc.so.1+0x3cad3)
    #3 GC_call_with_stack_base /home/travis/build/ivmai/bdwgc/extra/../misc.c:2169:14 (libgc.so.1+0x2a651)
    #4 GC_pthread_start /home/travis/build/ivmai/bdwgc/extra/../pthread_support.c:2375 (libgc.so.1+0x2a651)
  Thread T5 (tid=9050, running) created by main thread at:
    #0 pthread_create /tmp/final/llvm.src/projects/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:965:3 (lt-gctest+0x427105)
    #1 GC_pthread_create /home/travis/build/ivmai/bdwgc/extra/../pthread_support.c:2449:14 (libgc.so.1+0x2a54f)
    #2 main /home/travis/build/ivmai/bdwgc/tests/gctest.c:2617:21 (lt-gctest+0x4b4702)
  Thread T4 (tid=9013, running) created by main thread at:
    #0 pthread_create /tmp/final/llvm.src/projects/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:965:3 (lt-gctest+0x427105)
    #1 GC_pthread_create /home/travis/build/ivmai/bdwgc/extra/../pthread_support.c:2449:14 (libgc.so.1+0x2a54f)
    #2 main /home/travis/build/ivmai/bdwgc/tests/gctest.c:2617:21 (lt-gctest+0x4b46dc)
SUMMARY: ThreadSanitizer: data race /home/travis/build/ivmai/bdwgc/extra/../reclaim.c:200:29 in GC_reclaim_clear
ivmai commented 1 year ago

Source: master (b41a290) Build: https://app.travis-ci.com/github/ivmai/bdwgc/jobs/598169329

 Write of size 8 at 0x7fc89e4b5050 by thread T10:
    #0 memset /tmp/final/llvm.src/projects/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:764:3 (lt-gctest+0x430789)
    #1 GC_generic_malloc_aligned /home/travis/build/ivmai/bdwgc/extra/../malloc.c:282:13 (libgc.so.1+0x17c9f)
    #2 GC_memalign /home/travis/build/ivmai/bdwgc/extra/../mallocx.c:515:29 (libgc.so.1+0x1aae3)
    #3 GC_valloc /home/travis/build/ivmai/bdwgc/extra/../mallocx.c:566:12 (libgc.so.1+0x1ad61)
    #4 run_one_test /home/travis/build/ivmai/bdwgc/tests/gctest.c:1637:21 (lt-gctest+0x4b2d21)
    #5 thr_run_one_test /home/travis/build/ivmai/bdwgc/tests/gctest.c:2518:5 (lt-gctest+0x4b4453)
    #6 GC_pthread_start_inner /home/travis/build/ivmai/bdwgc/pthread_start.c:55:12 (libgc.so.1+0x3cb30)
    #7 GC_call_with_stack_base /home/travis/build/ivmai/bdwgc/extra/../misc.c:2169:14 (libgc.so.1+0x2a651)
    #8 GC_pthread_start /home/travis/build/ivmai/bdwgc/extra/../pthread_support.c:2375 (libgc.so.1+0x2a651)
  Previous write of size 8 at 0x7fc89e4b5050 by main thread (mutexes: write M4):
    #0 GC_reclaim_clear /home/travis/build/ivmai/bdwgc/extra/../reclaim.c:200:29 (libgc.so.1+0x19d47)
    #1 GC_reclaim_generic /home/travis/build/ivmai/bdwgc/extra/../reclaim.c:324 (libgc.so.1+0x19d47)
    #2 GC_reclaim_small_nonempty_block /home/travis/build/ivmai/bdwgc/extra/../reclaim.c:351:16 (libgc.so.1+0xb175)
    #3 GC_continue_reclaim /home/travis/build/ivmai/bdwgc/extra/../reclaim.c:706 (libgc.so.1+0xb175)
    #4 GC_allocobj /home/travis/build/ivmai/bdwgc/extra/../alloc.c:1745 (libgc.so.1+0xb175)
    #5 GC_generic_malloc_inner /home/travis/build/ivmai/bdwgc/extra/../malloc.c:188 (libgc.so.1+0xb175)
    #6 GC_generic_malloc_aligned /home/travis/build/ivmai/bdwgc/extra/../malloc.c:248:18 (libgc.so.1+0x17a8d)
    #7 GC_generic_malloc /home/travis/build/ivmai/bdwgc/extra/../malloc.c:292:12 (libgc.so.1+0x17edb)
    #8 GC_malloc_kind_global /home/travis/build/ivmai/bdwgc/extra/../malloc.c:329 (libgc.so.1+0x17edb)
    #9 GC_malloc_kind /home/travis/build/ivmai/bdwgc/extra/../thread_local_alloc.c:187:5 (libgc.so.1+0x17973)
    #10 GC_malloc /home/travis/build/ivmai/bdwgc/extra/../malloc.c:348:12 (libgc.so.1+0x1ab6d)
    #11 GC_memalign /home/travis/build/ivmai/bdwgc/extra/../mallocx.c:521 (libgc.so.1+0x1ab6d)
    #12 GC_posix_memalign /home/travis/build/ivmai/bdwgc/extra/../mallocx.c:551:18 (libgc.so.1+0x1acdc)
    #13 run_one_test /home/travis/build/ivmai/bdwgc/tests/gctest.c:1632:17 (lt-gctest+0x4b2d06)
    #14 main /home/travis/build/ivmai/bdwgc/tests/gctest.c:2626:9 (lt-gctest+0x4b47f4)
ivmai commented 1 year ago

This looks like a false positive (because TSan does not properly identify thread suspend/resume by signals, I think). The scenario is: Thread 1:

The commit 55dbba223 reduces the chance of getting this issue.

We could probably minimize the chance even more if we change: GC_INLINE word GC_clear_block(word p, word sz, signed_word count) -> GC_ATTR_NO_SANITIZE_THREAD STATIC word GC_clear_block(word p, word sz, signed_word count)

Let's consider it if this issue is met once more.