Skip to content
This repository was archived by the owner on Feb 6, 2025. It is now read-only.
This repository was archived by the owner on Feb 6, 2025. It is now read-only.

String initialization is instrumented, leading to false positives #30

@OlivierNicole

Description

@OlivierNicole

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions