When using a TSan-enabled compiler, tests/parallel/test_c_thread_register.ml fails, but not on every run, with TSan reporting a use-after-free, which is probably a race.
==================
WARNING: ThreadSanitizer: heap-use-after-free (pid=1442508)
Read of size 8 at 0x7bb400000000 by thread T3 (mutexes: write M78):
#0 scan_stack_frames runtime/fiber.c:243 (test_c_thread_register.opt+0x10428d)
#1 caml_scan_stack runtime/fiber.c:284 (test_c_thread_register.opt+0x10428d)
#2 caml_do_local_roots runtime/roots.c:69 (test_c_thread_register.opt+0x123fcb)
#3 caml_thread_scan_roots /home/miod/git/ocaml.tsan/otherlibs/systhreads/st_stubs.c:174 (test_c_thread_register.opt+0xddb2a)
#4 caml_empty_minor_heap_promote runtime/minor_gc.c:611 (test_c_thread_register.opt+0x120b66)
#5 caml_stw_empty_minor_heap_no_major_slice runtime/minor_gc.c:742 (test_c_thread_register.opt+0x121008)
#6 caml_stw_empty_minor_heap runtime/minor_gc.c:773 (test_c_thread_register.opt+0x1212e9)
#7 stw_handler runtime/domain.c:1362 (test_c_thread_register.opt+0xfd411)
#8 handle_incoming runtime/domain.c:335 (test_c_thread_register.opt+0xfd411)
#9 caml_handle_incoming_interrupts runtime/domain.c:348 (test_c_thread_register.opt+0xfd64d)
#10 backup_thread_func runtime/domain.c:998 (test_c_thread_register.opt+0xfd64d)
Previous write of size 8 at 0x7bb400000000 by thread T4 (mutexes: write M78):
#0 free ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:711 (libtsan.so.0+0x37ab8)
#1 caml_stat_free runtime/memory.c:645 (test_c_thread_register.opt+0x11ef17)
#2 caml_free_stack runtime/fiber.c:582 (test_c_thread_register.opt+0x104be7)
#3 caml_thread_free_info /home/miod/git/ocaml.tsan/otherlibs/systhreads/st_stubs.c:320 (test_c_thread_register.opt+0xdeac3)
#4 caml_thread_remove_and_free /home/miod/git/ocaml.tsan/otherlibs/systhreads/st_stubs.c:359 (test_c_thread_register.opt+0xdf04b)
#5 caml_c_thread_unregister /home/miod/git/ocaml.tsan/otherlibs/systhreads/st_stubs.c:708 (test_c_thread_register.opt+0xdfa3a)
#6 thread_func <null> (test_c_thread_register.opt+0xececa)
Mutex M78 (0x5603ee6b2448) created at:
#0 pthread_mutex_init ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1227 (libtsan.so.0+0x4bee1)
#1 caml_plat_mutex_init runtime/platform.c:55 (test_c_thread_register.opt+0x1230fa)
#2 caml_init_domains runtime/domain.c:916 (test_c_thread_register.opt+0xfc50e)
#3 caml_init_gc runtime/gc_ctrl.c:348 (test_c_thread_register.opt+0x108e53)
#4 caml_startup_common runtime/startup_nat.c:111 (test_c_thread_register.opt+0x1357c7)
#5 caml_startup_common runtime/startup_nat.c:88 (test_c_thread_register.opt+0x1357c7)
#6 caml_startup_exn runtime/startup_nat.c:139 (test_c_thread_register.opt+0x13598b)
#7 caml_startup runtime/startup_nat.c:144 (test_c_thread_register.opt+0x13598b)
#8 caml_main runtime/startup_nat.c:151 (test_c_thread_register.opt+0x13598b)
#9 main runtime/main.c:37 (test_c_thread_register.opt+0x659c9)
Thread T3 (tid=1442513, running) created by main thread at:
#0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:969 (libtsan.so.0+0x605b8)
#1 install_backup_thread runtime/domain.c:1064 (test_c_thread_register.opt+0xfae6a)
#2 install_backup_thread runtime/domain.c:1273 (test_c_thread_register.opt+0xfe037)
#3 caml_domain_spawn runtime/domain.c:1270 (test_c_thread_register.opt+0xfe037)
#4 caml_c_call <null> (test_c_thread_register.opt+0x135fd3)
#5 camlStdlib__Domain.spawn_701 <null> (test_c_thread_register.opt+0xacf26)
#6 camlTest_c_thread_register.entry <null> (test_c_thread_register.opt+0x6845c)
#7 caml_program <null> (test_c_thread_register.opt+0x65f39)
#8 caml_start_program <null> (test_c_thread_register.opt+0x1360ef)
#9 caml_startup_common runtime/startup_nat.c:132 (test_c_thread_register.opt+0x1358e0)
#10 caml_startup_common runtime/startup_nat.c:88 (test_c_thread_register.opt+0x1358e0)
#11 caml_startup_exn runtime/startup_nat.c:139 (test_c_thread_register.opt+0x13598b)
#12 caml_startup runtime/startup_nat.c:144 (test_c_thread_register.opt+0x13598b)
#13 caml_main runtime/startup_nat.c:151 (test_c_thread_register.opt+0x13598b)
#14 main runtime/main.c:37 (test_c_thread_register.opt+0x659c9)
Thread T4 (tid=1442514, finished) created by thread T1 at:
#0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:969 (libtsan.so.0+0x605b8)
#1 spawn_thread <null> (test_c_thread_register.opt+0xecf43)
#2 caml_c_call <null> (test_c_thread_register.opt+0x135fd3)
#3 camlTest_c_thread_register.fun_358 <null> (test_c_thread_register.opt+0x68388)
#4 camlStdlib__Domain.body_706 <null> (test_c_thread_register.opt+0xad00f)
#5 caml_start_program <null> (test_c_thread_register.opt+0x1360ef)
#6 caml_callback_exn runtime/callback.c:200 (test_c_thread_register.opt+0xf8333)
#7 domain_thread_func runtime/domain.c:1187 (test_c_thread_register.opt+0xfc7ab)
SUMMARY: ThreadSanitizer: heap-use-after-free runtime/fiber.c:243 in scan_stack_frames
==================
==================
WARNING: ThreadSanitizer: heap-use-after-free (pid=1442508)
Read of size 8 at 0x7bb400000010 by thread T3 (mutexes: write M78):
#0 scan_stack_frames runtime/fiber.c:247 (test_c_thread_register.opt+0x1042a1)
#1 caml_scan_stack runtime/fiber.c:284 (test_c_thread_register.opt+0x1042a1)
#2 caml_do_local_roots runtime/roots.c:69 (test_c_thread_register.opt+0x123fcb)
#3 caml_thread_scan_roots /home/miod/git/ocaml.tsan/otherlibs/systhreads/st_stubs.c:174 (test_c_thread_register.opt+0xddb2a)
#4 caml_empty_minor_heap_promote runtime/minor_gc.c:611 (test_c_thread_register.opt+0x120b66)
#5 caml_stw_empty_minor_heap_no_major_slice runtime/minor_gc.c:742 (test_c_thread_register.opt+0x121008)
#6 caml_stw_empty_minor_heap runtime/minor_gc.c:773 (test_c_thread_register.opt+0x1212e9)
#7 stw_handler runtime/domain.c:1362 (test_c_thread_register.opt+0xfd411)
#8 handle_incoming runtime/domain.c:335 (test_c_thread_register.opt+0xfd411)
#9 caml_handle_incoming_interrupts runtime/domain.c:348 (test_c_thread_register.opt+0xfd64d)
#10 backup_thread_func runtime/domain.c:998 (test_c_thread_register.opt+0xfd64d)
Previous write of size 8 at 0x7bb400000010 by thread T4 (mutexes: write M78):
#0 free ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:711 (libtsan.so.0+0x37ab8)
#1 caml_stat_free runtime/memory.c:645 (test_c_thread_register.opt+0x11ef17)
#2 caml_free_stack runtime/fiber.c:582 (test_c_thread_register.opt+0x104be7)
#3 caml_thread_free_info /home/miod/git/ocaml.tsan/otherlibs/systhreads/st_stubs.c:320 (test_c_thread_register.opt+0xdeac3)
#4 caml_thread_remove_and_free /home/miod/git/ocaml.tsan/otherlibs/systhreads/st_stubs.c:359 (test_c_thread_register.opt+0xdf04b)
#5 caml_c_thread_unregister /home/miod/git/ocaml.tsan/otherlibs/systhreads/st_stubs.c:708 (test_c_thread_register.opt+0xdfa3a)
#6 thread_func <null> (test_c_thread_register.opt+0xececa)
Mutex M78 (0x5603ee6b2448) created at:
#0 pthread_mutex_init ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1227 (libtsan.so.0+0x4bee1)
#1 caml_plat_mutex_init runtime/platform.c:55 (test_c_thread_register.opt+0x1230fa)
#2 caml_init_domains runtime/domain.c:916 (test_c_thread_register.opt+0xfc50e)
#3 caml_init_gc runtime/gc_ctrl.c:348 (test_c_thread_register.opt+0x108e53)
#4 caml_startup_common runtime/startup_nat.c:111 (test_c_thread_register.opt+0x1357c7)
#5 caml_startup_common runtime/startup_nat.c:88 (test_c_thread_register.opt+0x1357c7)
#6 caml_startup_exn runtime/startup_nat.c:139 (test_c_thread_register.opt+0x13598b)
#7 caml_startup runtime/startup_nat.c:144 (test_c_thread_register.opt+0x13598b)
#8 caml_main runtime/startup_nat.c:151 (test_c_thread_register.opt+0x13598b)
#9 main runtime/main.c:37 (test_c_thread_register.opt+0x659c9)
Thread T3 (tid=1442513, running) created by main thread at:
#0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:969 (libtsan.so.0+0x605b8)
#1 install_backup_thread runtime/domain.c:1064 (test_c_thread_register.opt+0xfae6a)
#2 install_backup_thread runtime/domain.c:1273 (test_c_thread_register.opt+0xfe037)
#3 caml_domain_spawn runtime/domain.c:1270 (test_c_thread_register.opt+0xfe037)
#4 caml_c_call <null> (test_c_thread_register.opt+0x135fd3)
#5 camlStdlib__Domain.spawn_701 <null> (test_c_thread_register.opt+0xacf26)
#6 camlTest_c_thread_register.entry <null> (test_c_thread_register.opt+0x6845c)
#7 caml_program <null> (test_c_thread_register.opt+0x65f39)
#8 caml_start_program <null> (test_c_thread_register.opt+0x1360ef)
#9 caml_startup_common runtime/startup_nat.c:132 (test_c_thread_register.opt+0x1358e0)
#10 caml_startup_common runtime/startup_nat.c:88 (test_c_thread_register.opt+0x1358e0)
#11 caml_startup_exn runtime/startup_nat.c:139 (test_c_thread_register.opt+0x13598b)
#12 caml_startup runtime/startup_nat.c:144 (test_c_thread_register.opt+0x13598b)
#13 caml_main runtime/startup_nat.c:151 (test_c_thread_register.opt+0x13598b)
#14 main runtime/main.c:37 (test_c_thread_register.opt+0x659c9)
Thread T4 (tid=1442514, finished) created by thread T1 at:
#0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:969 (libtsan.so.0+0x605b8)
#1 spawn_thread <null> (test_c_thread_register.opt+0xecf43)
#2 caml_c_call <null> (test_c_thread_register.opt+0x135fd3)
#3 camlTest_c_thread_register.fun_358 <null> (test_c_thread_register.opt+0x68388)
#4 camlStdlib__Domain.body_706 <null> (test_c_thread_register.opt+0xad00f)
#5 caml_start_program <null> (test_c_thread_register.opt+0x1360ef)
#6 caml_callback_exn runtime/callback.c:200 (test_c_thread_register.opt+0xf8333)
#7 domain_thread_func runtime/domain.c:1187 (test_c_thread_register.opt+0xfc7ab)
SUMMARY: ThreadSanitizer: heap-use-after-free runtime/fiber.c:247 in scan_stack_frames
==================
Steps to reproduce:
git reset --hard <REVISION_TO_TEST>;
./configure --enable-tsan && make && cd testsuite && env KEEP_TEST_DIR_ON_SUCCESS=1 make one TEST=tests/parallel/test_c_thread_register.ml;
timeout 60 sh -c 'while ./_ocamltest/tests/parallel/test_c_thread_register/ocamlopt.byte/test_c_thread_register.opt ; do true; done'; test $? -eq 124
With a head of trunk at 9b059b1e7a66e9d2f04d892a4de34c418cd96f69, I have not been able to trigger the TSan report.
With a head of trunk at b4308a0c74070116a5fb27b07e1c15f099c2c0e3, I have been able to trigger it at least once in ten runs.
This hints to a subtle regression introduced by #12318. This does not mean that particular change is faulty, but it might make an existing race occur more easily than prior to that change.
When using a TSan-enabled compiler,
tests/parallel/test_c_thread_register.mlfails, but not on every run, with TSan reporting a use-after-free, which is probably a race.Steps to reproduce:
With a head of trunk at
9b059b1e7a66e9d2f04d892a4de34c418cd96f69, I have not been able to trigger the TSan report.With a head of trunk at
b4308a0c74070116a5fb27b07e1c15f099c2c0e3, I have been able to trigger it at least once in ten runs.This hints to a subtle regression introduced by #12318. This does not mean that particular change is faulty, but it might make an existing race occur more easily than prior to that change.