Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String initialization is instrumented, leading to false positives #30

Open
OlivierNicole opened this issue May 26, 2023 · 0 comments
Open

Comments

@OlivierNicole
Copy link
Collaborator

How to reproduce

let table = Hashtbl.create 64

let read_table () =
  for _ = 0 to 99 do
    let key = QCheck.Gen.(generate1 small_string) in
    try ignore (Hashtbl.find table key) with Not_found -> ()
  done

let record_new_clients () =
  for _ = 0 to 99 do
    let key = QCheck.Gen.(generate1 small_string) in
    let v = QCheck.Gen.(generate1 small_nat) in
    Hashtbl.add table key v
  done

let () =
  let d = Domain.spawn read_table in
  record_new_clients ();
  Domain.join d

Build with

$ cat dune
(executable
 (name race)
 (libraries qcheck-core))
$ dune exec ./race.exe

You get reports like:

==================
WARNING: ThreadSanitizer: data race (pid=4184815)
  Read of size 1 at 0x7f0879dee8cf by thread T1 (mutexes: write M90):
    #0 caml_string_length runtime/str.c:36 (race.exe+0x596e71)
    #1 do_compare_val runtime/compare.c:221 (race.exe+0x56aafb)
    #2 compare_val runtime/compare.c:98 (race.exe+0x56aafb)
    #3 caml_compare runtime/compare.c:345 (race.exe+0x56ae75)
    #4 caml_c_call <null> (race.exe+0x5a09fb)
    #5 camlStdlib__Hashtbl.find_1339 /home/olivier/compiler/tsan/stdlib/hashtbl.ml:552 (race.exe+0x53af11)
    #6 camlDune__exe__Race.read_table_352 /workspace_root/race.ml:6 (race.exe+0x464ec0)
    #7 camlStdlib__Domain.body_703 /home/olivier/compiler/tsan/stdlib/domain.ml:202 (race.exe+0x50bf80)
    #8 caml_start_program <null> (race.exe+0x5a0af7)
    #9 caml_callback_exn runtime/callback.c:197 (race.exe+0x56919b)
    #10 caml_callback runtime/callback.c:293 (race.exe+0x569cd0)
    #11 domain_thread_func runtime/domain.c:1100 (race.exe+0x56d39f)

  Previous write of size 8 at 0x7f0879dee8c8 by main thread (mutexes: write M86):
    #0 __tsan_volatile_write8 runtime/tsan.c:239 (race.exe+0x59af35)
    #1 caml_alloc_string runtime/alloc.c:179 (race.exe+0x560fc5)
    #2 caml_create_bytes runtime/str.c:78 (race.exe+0x596fc7)
    #3 caml_c_call <null> (race.exe+0x5a09fb)
    #4 camlQCheck.bytes_size_inner_5638 src/core/QCheck.ml:369 (race.exe+0x48ffe5)
    #5 camlQCheck.string_size_inner_5644 src/core/QCheck.ml:376 (race.exe+0x4901dc)
    #6 camlDune__exe__Race.record_new_clients_579 /workspace_root/race.ml:11 (race.exe+0x464f9d)
    #7 camlDune__exe__Race.entry /workspace_root/race.ml:18 (race.exe+0x465118)
    #8 caml_program <null> (race.exe+0x45fefe)
    #9 caml_start_program <null> (race.exe+0x5a0af7)
    #10 caml_startup_common runtime/startup_nat.c:132 (race.exe+0x5a0332)
    #11 caml_startup_common runtime/startup_nat.c:88 (race.exe+0x5a0332)
    #12 caml_startup_exn runtime/startup_nat.c:139 (race.exe+0x5a0367)
    #13 caml_startup runtime/startup_nat.c:144 (race.exe+0x5a0395)
    #14 caml_main runtime/startup_nat.c:151 (race.exe+0x5a03d5)
    #15 main runtime/main.c:37 (race.exe+0x45f915)

  Mutex M90 (0x000000672960) created at:
    #0 pthread_mutex_init <null> (libtsan.so.2+0x54bc8)
    [...]

SUMMARY: ThreadSanitizer: data race runtime/str.c:36 in caml_string_length
==================

Reads in the string conflict with a write made during the initialization. These operations should in reality be ordered due to data dependencies (note for future me: can you explain this more precisely?). But data dependencies are not part of C11 and TSan will report a race here.

To avoid this specific instance of false positive, as with other publication safety issues, the initializing writes should be un-instrumented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant