We are happy to announce the first release of ThreadSanitizer support for OCaml 5.
Motivation in a nutshell
With OCaml 5 comes parallel programming, and, with it, the possibility of introducing data races. A data race is when two or more threads access the same memory location concurrently, and at least one of the accesses is a write. Data races can lead to particularly hard-to-debug problems.
ThreadSanitizer (TSan for short) is an approach developed by Google to locate data races in code bases. It consists in instrumenting your executables to keep a history of previous memory accesses (at a certain performance cost), in order to detect a potential data race, even when this race has no visible effect on the execution. ThreadSanitizer has proved very effective in detecting hundreds of concurrency bugs in large projects.
There is now a new opam switch, 5.0.0+tsan
, on which all your libraries and executables will be compiled with ThreadSanitizer instrumentation. On that switch, the ThreadSanitizer runtime will run as part of your executables and emit reports when it detects a potential data race:
==================
WARNING: ThreadSanitizer: data race (pid=4170290)
Read of size 8 at 0x7f072bbfe498 by thread T4 (mutexes: write M0):
#0 camlSimpleRace__fun_524 /tmp/simpleRace.ml:7 (simpleRace.exe+0x43dc9d)
#1 camlStdlib__Domain__body_696 /home/olivier/.opam/5.0.0+tsan/.opam-switch/build/ocaml-variants.5.0.0+tsan/stdlib/domain.ml:202 (simpleRace.exe+0x47b5dc)
#2 caml_start_program ??:? (simpleRace.exe+0x4f51c3)
#3 caml_callback_exn /home/olivier/.opam/5.0.0+tsan/.opam-switch/build/ocaml-variants.5.0.0+tsan/runtime/callback.c:168 (simpleRace.exe+0x4c2b93)
#4 caml_callback /home/olivier/.opam/5.0.0+tsan/.opam-switch/build/ocaml-variants.5.0.0+tsan/runtime/callback.c:256 (simpleRace.exe+0x4c36e3)
#5 domain_thread_func /home/olivier/.opam/5.0.0+tsan/.opam-switch/build/ocaml-variants.5.0.0+tsan/runtime/domain.c:1093 (simpleRace.exe+0x4c6ad1)
Previous write of size 8 at 0x7f072bbfe498 by thread T1 (mutexes: write M1):
#0 camlSimpleRace__fun_520 /tmp/simpleRace.ml:6 (simpleRace.exe+0x43dc45)
#1 camlStdlib__Domain__body_696 /home/olivier/.opam/5.0.0+tsan/.opam-switch/build/ocaml-variants.5.0.0+tsan/stdlib/domain.ml:202 (simpleRace.exe+0x47b5dc)
#2 caml_start_program ??:? (simpleRace.exe+0x4f51c3)
#3 caml_callback_exn /home/olivier/.opam/5.0.0+tsan/.opam-switch/build/ocaml-variants.5.0.0+tsan/runtime/callback.c:168 (simpleRace.exe+0x4c2b93)
#4 caml_callback /home/olivier/.opam/5.0.0+tsan/.opam-switch/build/ocaml-variants.5.0.0+tsan/runtime/callback.c:256 (simpleRace.exe+0x4c36e3)
#5 domain_thread_func /home/olivier/.opam/5.0.0+tsan/.opam-switch/build/ocaml-variants.5.0.0+tsan/runtime/domain.c:1093 (simpleRace.exe+0x4c6ad1)
Mutex M0 (0x000000567ad8) created at:
#0 pthread_mutex_init /home/olivier/other_projects/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp:1316 (libtsan.so.0+0x3cafb)
[...]
SUMMARY: ThreadSanitizer: data race /tmp/simpleRace.ml:7 in camlSimpleRace__fun_524
==================
ThreadSanitizer: reported 1 warnings
OCaml executables are instrumented so that ThreadSanitizer will show precise backtraces, including when using exceptions, effect handlers, or C stubs.
ThreadSanitizer support for OCaml is a joint work with Fabrice Buoro, based on the work of Anmol Sahoo.
Usage instructions
At this stage, ThreadSanitizer for OCaml is supported only on the x86_64 architecture, and is not available on Windows.
Internally, the OCaml instrumentation uses the libunwind library, so if you’re on Linux you will need to install it using your system’s package manager. If you’re a macOS user, you have nothing to do: libunwind is installed by default.
Then you simply need to build and run your programs in the 5.0.0+tsan
switch:
opam update
opam switch create 5.0.0+tsan
Usage examples and further information can be found in the README of the project.
We are eager to get your feedback! We believe that running your Multicore programs or test suites with TSan can be a huge time-saver in debugging.