[LLVMbugs] [Bug 23176] New: atomic compare-and-swap under thread sanitizer after multithreaded fork is incorrect

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Thu Apr 9 12:24:08 PDT 2015


https://llvm.org/bugs/show_bug.cgi?id=23176

            Bug ID: 23176
           Summary: atomic compare-and-swap under thread sanitizer after
                    multithreaded fork is incorrect
           Product: compiler-rt
           Version: 3.5
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: compiler-rt
          Assignee: unassignedbugs at nondot.org
          Reporter: bsilver16384+llvm at gmail.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

Many of the atomic compare-and-swap primitives work incorrectly under thread
sanitizer after a multithreaded fork. Some of the ones which do not work:
__sync_bool_compare_and_swap, __sync_val_compare_and_swap,
__tsan_atomic32_compare_exchange_val. They all return a value indicating that
the variable did not contain the correct value at the start, even when it does.
However, they do change the value of the variable correctly. The variants which
return the previous value always return 1.

__tsan_atomic32_compare_exchange_strong does work correctly under the same
circumstances.

Here's a simple test program which shows the problem:
#include <stdio.h>
#include <unistd.h>
#include <sanitizer/tsan_interface_atomic.h>

#include <thread>

void succeed() {
  int test = 4;
  int result = 4;
  __tsan_atomic32_compare_exchange_strong(&test, &result, 5,
                                          __tsan_memory_order_seq_cst,
                                          __tsan_memory_order_seq_cst);
  printf("got %d value is %d\n", result, test);
}

void fail2() {
  int test = 4;
  int result = __tsan_atomic32_compare_exchange_val(
      &test, 4, 5, __tsan_memory_order_seq_cst, __tsan_memory_order_seq_cst);
  printf("got %d value is %d\n", result, test);
}

void fail1() {
  int test = 4;
  int result = __sync_val_compare_and_swap(&test, 4, 5);
  printf("got %d value is %d\n", result, test);
}

void nop() {}

int main() {
  ::std::thread thread1(nop);
  if (fork() == 0) {
    fail1();
    fail2();
    succeed();
    exit(0);
  } else {
    thread1.join();
  }
}

Here's what it prints for me:
got 1 value is 5
got 1 value is 5
got 4 value is 5

Those 1s should be 4s.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20150409/68ecbbb8/attachment.html>


More information about the llvm-bugs mailing list