Home | History | Annotate | Download | only in unittest
      1 /*
      2   This file is part of Valgrind, a dynamic binary instrumentation
      3   framework.
      4 
      5   Copyright (C) 2008-2008 Google Inc
      6      opensource (at) google.com
      7 
      8   This program is free software; you can redistribute it and/or
      9   modify it under the terms of the GNU General Public License as
     10   published by the Free Software Foundation; either version 2 of the
     11   License, or (at your option) any later version.
     12 
     13   This program is distributed in the hope that it will be useful, but
     14   WITHOUT ANY WARRANTY; without even the implied warranty of
     15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16   General Public License for more details.
     17 
     18   You should have received a copy of the GNU General Public License
     19   along with this program; if not, write to the Free Software
     20   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     21   02111-1307, USA.
     22 
     23   The GNU General Public License is contained in the file COPYING.
     24 */
     25 
     26 /* Author: Konstantin Serebryany <opensource (at) google.com>
     27 
     28  This file contains a set of unit tests for a data race detection tool.
     29 
     30  These tests can be compiled with pthreads (default) or
     31  with any other library that supports threads, locks, cond vars, etc.
     32 
     33 */
     34 #ifdef WIN32
     35 #error "Don't build this file on Windows!"
     36 #endif
     37 
     38 #include <fcntl.h>
     39 #include <fenv.h>
     40 #include <queue>
     41 #include <signal.h>
     42 #include <stdlib.h>
     43 #include <string>
     44 #include <vector>
     45 #include <unistd.h>
     46 
     47 #ifdef OS_linux
     48 # include <sys/epoll.h>
     49 #endif  // OS_linux
     50 
     51 #include "test_utils.h"
     52 #include <gtest/gtest.h>
     53 #include "gtest_fixture_injection.h"
     54 
     55 static CondVar CV;
     56 static int     COND = 0;
     57 
     58 // test11: FP. Synchronization via CondVar, 2 workers. {{{1
     59 // This test is properly synchronized, but currently (Dec 2007)
     60 // helgrind reports a false positive.
     61 //
     62 // Parent:                              Worker1, Worker2:
     63 // 1. Start(workers)                    a. read(GLOB)
     64 // 2. MU.Lock()                         b. MU.Lock()
     65 // 3. while(COND != 2)        /-------- c. CV.Signal()
     66 //      CV.Wait(&MU) <-------/          d. MU.Unlock()
     67 // 4. MU.Unlock()
     68 // 5. write(GLOB)
     69 //
     70 namespace test11 {
     71 int     GLOB = 0;
     72 Mutex   MU;
     73 void Worker() {
     74   usleep(200000);
     75   CHECK(GLOB != 777);
     76 
     77   MU.Lock();
     78   COND++;
     79   CV.Signal();
     80   MU.Unlock();
     81 }
     82 
     83 void Parent() {
     84   COND = 0;
     85 
     86   MyThreadArray t(Worker, Worker);
     87   t.Start();
     88 
     89   MU.Lock();
     90   while(COND != 2) {
     91     CV.Wait(&MU);
     92   }
     93   MU.Unlock();
     94 
     95   GLOB = 2;
     96 
     97   t.Join();
     98 }
     99 
    100 TEST(NegativeTests, test11) {
    101 //  ANNOTATE_EXPECT_RACE(&GLOB, "test11. FP. Fixed by MSMProp1.");
    102   printf("test11: negative\n");
    103   Parent();
    104   printf("\tGLOB=%d\n", GLOB);
    105 }
    106 }  // namespace test11
    107 
    108 
    109 // test75: TN. Test for sem_post, sem_wait, sem_trywait. {{{1
    110 namespace test75 {
    111 int     GLOB = 0;
    112 sem_t   sem[2];
    113 
    114 void Poster() {
    115   GLOB = 1;
    116   sem_post(&sem[0]);
    117   sem_post(&sem[1]);
    118 }
    119 
    120 void Waiter() {
    121   sem_wait(&sem[0]);
    122   CHECK(GLOB==1);
    123 }
    124 void TryWaiter() {
    125   usleep(500000);
    126   sem_trywait(&sem[1]);
    127   CHECK(GLOB==1);
    128 }
    129 
    130 TEST(NegativeTests, test75) {
    131 #ifndef NO_UNNAMED_SEM
    132   sem_init(&sem[0], 0, 0);
    133   sem_init(&sem[1], 0, 0);
    134 
    135   printf("test75: negative\n");
    136   {
    137     MyThreadArray t(Poster, Waiter);
    138     t.Start();
    139     t.Join();
    140   }
    141   GLOB = 2;
    142   {
    143     MyThreadArray t(Poster, TryWaiter);
    144     t.Start();
    145     t.Join();
    146   }
    147   printf("\tGLOB=%d\n", GLOB);
    148 
    149   sem_destroy(&sem[0]);
    150   sem_destroy(&sem[1]);
    151 #endif // NO_UNNAMED_SEM
    152 }
    153 }  // namespace test75
    154 
    155 
    156 // test98: Synchronization via read/write (or send/recv). {{{1
    157 namespace test98 {
    158 // The synchronization here is done by a pair of read/write calls
    159 // that create a happens-before arc. Same may be done with send/recv.
    160 // Such synchronization is quite unusual in real programs
    161 // (why would one synchronizae via a file or socket?), but
    162 // quite possible in unittests where one threads runs for producer
    163 // and one for consumer.
    164 //
    165 // A race detector has to create a happens-before arcs for
    166 // {read,send}->{write,recv} even if the file descriptors are different.
    167 //
    168 int     GLOB = 0;
    169 int fd_out = -1;
    170 int fd_in  = -1;
    171 
    172 void Writer() {
    173   usleep(1000);
    174   GLOB = 1;
    175   const char *str = "Hey there!\n";
    176   const int size = strlen(str) + 1;
    177   CHECK(size == write(fd_out, str, size));
    178 }
    179 
    180 void Reader() {
    181   char buff[100];
    182   while (read(fd_in, buff, 100) == 0)
    183     sleep(1);
    184   printf("read: %s\n", buff);
    185   GLOB = 2;
    186 }
    187 
    188 #ifndef __APPLE__
    189 // Tsan for Mac OS is missing the unlink() syscall handler.
    190 // TODO(glider): add the syscall handler to Valgrind.
    191 TEST(NegativeTests, test98) {
    192   printf("test98: negative, synchronization via I/O\n");
    193   char in_name[100];
    194   char out_name[100];
    195   // we open two files, on for reading and one for writing,
    196   // but the files are actually the same (symlinked).
    197   sprintf(in_name,  "/tmp/racecheck_unittest_in.%d", getpid());
    198   sprintf(out_name, "/tmp/racecheck_unittest_out.%d", getpid());
    199   fd_out = creat(out_name, O_WRONLY | S_IRWXU);
    200   CHECK(0 == symlink(out_name, in_name));
    201   fd_in  = open(in_name, 0, O_RDONLY);
    202   CHECK(fd_out >= 0);
    203   CHECK(fd_in  >= 0);
    204   MyThreadArray t(Writer, Reader);
    205   t.Start();
    206   t.Join();
    207   printf("\tGLOB=%d\n", GLOB);
    208   // cleanup
    209   close(fd_in);
    210   close(fd_out);
    211   unlink(in_name);
    212   unlink(out_name);
    213 }
    214 #endif  // __APPLE__
    215 }  // namespace test98
    216 
    217 
    218 namespace NegativeTests_PthreadOnce {  // {{{1
    219 int     *GLOB = NULL;
    220 static pthread_once_t once = PTHREAD_ONCE_INIT;
    221 void Init() {
    222   GLOB = new int;
    223   ANNOTATE_TRACE_MEMORY(GLOB);
    224   *GLOB = 777;
    225 }
    226 
    227 void Worker0() {
    228   pthread_once(&once, Init);
    229 }
    230 void Worker1() {
    231   usleep(100000);
    232   pthread_once(&once, Init);
    233   CHECK(*GLOB == 777);
    234 }
    235 
    236 
    237 TEST(NegativeTests, PthreadOnceTest) {
    238   MyThreadArray t(Worker0, Worker1, Worker1, Worker1);
    239   t.Start();
    240   t.Join();
    241   printf("\tGLOB=%d\n", *GLOB);
    242 }
    243 }  // namespace
    244 
    245 
    246 // test110: TP. Simple races with stack, global and heap objects. {{{1
    247 namespace test110 {
    248 int        GLOB = 0;
    249 static int STATIC;
    250 
    251 char       *STACK = 0;
    252 
    253 int       *MALLOC;
    254 int       *CALLOC;
    255 int       *REALLOC;
    256 int       *VALLOC;
    257 int       *PVALLOC;
    258 int       *MEMALIGN;
    259 int       *POSIX_MEMALIGN;
    260 int       *MMAP;
    261 
    262 int       *NEW;
    263 int       *NEW_ARR;
    264 
    265 void Worker() {
    266   GLOB++;
    267   STATIC++;
    268 
    269   (*STACK)++;
    270 
    271   (*MALLOC)++;
    272   (*CALLOC)++;
    273   (*REALLOC)++;
    274   (*VALLOC)++;
    275   (*PVALLOC)++;
    276   (*MEMALIGN)++;
    277   (*POSIX_MEMALIGN)++;
    278   (*MMAP)++;
    279 
    280   (*NEW)++;
    281   (*NEW_ARR)++;
    282 }
    283 TEST(PositiveTests, test110) {
    284   printf("test110: positive (race on a stack object)\n");
    285 
    286   char x = 0;
    287   STACK = &x;
    288 
    289   MALLOC = (int*)malloc(sizeof(int));
    290   CALLOC = (int*)calloc(1, sizeof(int));
    291   REALLOC = (int*)realloc(NULL, sizeof(int));
    292   VALLOC = (int*)valloc(sizeof(int));
    293   PVALLOC = (int*)valloc(sizeof(int));  // TODO: pvalloc breaks helgrind.
    294   MEMALIGN = (int*)memalign(64, sizeof(int));
    295   CHECK(0 == posix_memalign((void**)&POSIX_MEMALIGN, 64, sizeof(int)));
    296   MMAP = (int*)mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE,
    297                     MAP_PRIVATE | MAP_ANON, -1, 0);
    298 
    299   NEW     = new int;
    300   NEW_ARR = new int[10];
    301 
    302 
    303   ANNOTATE_EXPECT_RACE(STACK, "real race on stack object");
    304   ANNOTATE_EXPECT_RACE(&GLOB, "real race on global object");
    305   ANNOTATE_EXPECT_RACE(&STATIC, "real race on a static global object");
    306   ANNOTATE_EXPECT_RACE(MALLOC, "real race on a malloc-ed object");
    307   ANNOTATE_EXPECT_RACE(CALLOC, "real race on a calloc-ed object");
    308   ANNOTATE_EXPECT_RACE(REALLOC, "real race on a realloc-ed object");
    309   ANNOTATE_EXPECT_RACE(VALLOC, "real race on a valloc-ed object");
    310   ANNOTATE_EXPECT_RACE(PVALLOC, "real race on a pvalloc-ed object");
    311   ANNOTATE_EXPECT_RACE(MEMALIGN, "real race on a memalign-ed object");
    312   ANNOTATE_EXPECT_RACE(POSIX_MEMALIGN, "real race on a posix_memalign-ed object");
    313   ANNOTATE_EXPECT_RACE(MMAP, "real race on a mmap-ed object");
    314 
    315   ANNOTATE_EXPECT_RACE(NEW, "real race on a new-ed object");
    316   ANNOTATE_EXPECT_RACE(NEW_ARR, "real race on a new[]-ed object");
    317 
    318   MyThreadArray t(Worker, Worker, Worker);
    319   t.Start();
    320   t.Join();
    321   printf("\tSTACK=%d\n", *STACK);
    322   CHECK(GLOB <= 3);
    323   CHECK(STATIC <= 3);
    324 
    325   free(MALLOC);
    326   free(CALLOC);
    327   free(REALLOC);
    328   free(VALLOC);
    329   free(PVALLOC);
    330   free(MEMALIGN);
    331   free(POSIX_MEMALIGN);
    332   munmap(MMAP, sizeof(int));
    333   delete NEW;
    334   delete [] NEW_ARR;
    335 }
    336 }  // namespace test110
    337 
    338 
    339 // test115: TN. sem_open. {{{1
    340 namespace    test115 {
    341 int tid = 0;
    342 Mutex mu;
    343 const char *kSemName = "drt-test-sem";
    344 
    345 int GLOB = 0;
    346 
    347 sem_t *DoSemOpen() {
    348   // TODO: there is some race report inside sem_open
    349   // for which suppressions do not work... (???)
    350   ANNOTATE_IGNORE_WRITES_BEGIN();
    351   sem_t *sem = sem_open(kSemName, O_CREAT, 0600, 3);
    352   ANNOTATE_IGNORE_WRITES_END();
    353   return sem;
    354 }
    355 
    356 void Worker() {
    357   mu.Lock();
    358   int my_tid = tid++;
    359   mu.Unlock();
    360 
    361   if (my_tid == 0) {
    362     GLOB = 1;
    363   }
    364 
    365   // if the detector observes a happens-before arc between
    366   // sem_open and sem_wait, it will be silent.
    367   sem_t *sem = DoSemOpen();
    368   usleep(100000);
    369   CHECK(sem != SEM_FAILED);
    370   CHECK(sem_wait(sem) == 0);
    371 
    372   if (my_tid > 0) {
    373     CHECK(GLOB == 1);
    374   }
    375 }
    376 
    377 #ifndef __APPLE__
    378 /* This test is disabled for Darwin because of the tricky implementation of
    379  * sem_open on that platform: subsequent attempts to open an existing semafore
    380  * create new ones. */
    381 TEST(NegativeTests, test115) {
    382   printf("test115: stab (sem_open())\n");
    383 
    384   // just check that sem_open is not completely broken
    385   sem_unlink(kSemName);
    386   sem_t* sem = DoSemOpen();
    387   CHECK(sem != SEM_FAILED);
    388   CHECK(sem_wait(sem) == 0);
    389   sem_unlink(kSemName);
    390 
    391   // check that sem_open and sem_wait create a happens-before arc.
    392   MyThreadArray t(Worker, Worker, Worker);
    393   t.Start();
    394   t.Join();
    395   // clean up
    396   sem_unlink(kSemName);
    397 }
    398 #endif  // __APPLE__
    399 }  // namespace test115
    400 
    401 
    402 // test122 TP: Simple test with RWLock {{{1
    403 namespace  test122 {
    404 int     VAR1 = 0;
    405 int     VAR2 = 0;
    406 RWLock mu;
    407 
    408 void WriteWhileHoldingReaderLock(int *p) {
    409   usleep(100000);
    410   ReaderLockScoped lock(&mu);  // Reader lock for writing. -- bug.
    411   (*p)++;
    412 }
    413 
    414 void CorrectWrite(int *p) {
    415   WriterLockScoped lock(&mu);
    416   (*p)++;
    417 }
    418 
    419 void Thread1() { WriteWhileHoldingReaderLock(&VAR1); }
    420 void Thread2() { CorrectWrite(&VAR1); }
    421 void Thread3() { CorrectWrite(&VAR2); }
    422 void Thread4() { WriteWhileHoldingReaderLock(&VAR2); }
    423 
    424 
    425 TEST(PositiveTests, test122) {
    426   printf("test122: positive (rw-lock)\n");
    427   VAR1 = 0;
    428   VAR2 = 0;
    429   ANNOTATE_TRACE_MEMORY(&VAR1);
    430   ANNOTATE_TRACE_MEMORY(&VAR2);
    431   if (!Tsan_PureHappensBefore()) {
    432     ANNOTATE_EXPECT_RACE_FOR_TSAN(&VAR1, "test122. TP. ReaderLock-ed while writing");
    433     ANNOTATE_EXPECT_RACE_FOR_TSAN(&VAR2, "test122. TP. ReaderLock-ed while writing");
    434   }
    435   MyThreadArray t(Thread1, Thread2, Thread3, Thread4);
    436   t.Start();
    437   t.Join();
    438 }
    439 }  // namespace test122
    440 
    441 
    442 // test125 TN: Backwards lock (annotated). {{{1
    443 namespace test125 {
    444 // This test uses "Backwards mutex" locking protocol.
    445 // We take a *reader* lock when writing to a per-thread data
    446 // (GLOB[thread_num])  and we take a *writer* lock when we
    447 // are reading from the entire array at once.
    448 //
    449 // Such locking protocol is not understood by ThreadSanitizer's
    450 // hybrid state machine. So, you either have to use a pure-happens-before
    451 // detector ("tsan --pure-happens-before") or apply pure happens-before mode
    452 // to this particular lock by using ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&mu).
    453 
    454 const int n_threads = 3;
    455 RWLock   mu;
    456 int     GLOB[n_threads];
    457 
    458 int adder_num; // updated atomically.
    459 
    460 void Adder() {
    461   int my_num = AtomicIncrement(&adder_num, 1) - 1;
    462   CHECK(my_num >= 0);
    463   CHECK(my_num < n_threads);
    464 
    465   ReaderLockScoped lock(&mu);
    466   GLOB[my_num]++;
    467 }
    468 
    469 void Aggregator() {
    470   int sum = 0;
    471   {
    472     WriterLockScoped lock(&mu);
    473     for (int i = 0; i < n_threads; i++) {
    474       sum += GLOB[i];
    475     }
    476   }
    477   printf("sum=%d\n", sum);
    478 }
    479 
    480 TEST(NegativeTests, test125) {
    481   printf("test125: negative\n");
    482 
    483   ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&mu);
    484 
    485   // run Adders, then Aggregator
    486   adder_num = 0;
    487   {
    488     MyThreadArray t(Adder, Adder, Adder, Aggregator);
    489     t.Start();
    490     t.Join();
    491   }
    492 
    493   // Run Aggregator first.
    494   adder_num = 0;
    495   {
    496     MyThreadArray t(Aggregator, Adder, Adder, Adder);
    497     t.Start();
    498     t.Join();
    499   }
    500 
    501 }
    502 }  // namespace test125
    503 
    504 
    505 namespace MmapTest {  // {{{1
    506 
    507 const int kMmapSize =  65536;
    508 
    509 void SubWorker() {
    510   for (int i = 0; i < 500; i++) {
    511     int *ptr = (int*)mmap(NULL, kMmapSize, PROT_READ | PROT_WRITE,
    512                           MAP_PRIVATE | MAP_ANON, -1, 0);
    513     *ptr = 42;
    514     munmap(ptr, kMmapSize);
    515   }
    516 }
    517 
    518 void Worker1() {
    519   MyThreadArray t(SubWorker, SubWorker, SubWorker, SubWorker);
    520   t.Start();
    521   t.Join();
    522 }
    523 void Worker() {
    524   MyThreadArray t(Worker1, Worker1, Worker1, Worker1);
    525   t.Start();
    526   t.Join();
    527 }
    528 
    529 TEST(NegativeTests, MmapTest) {
    530   MyThreadArray t(Worker, Worker, Worker, Worker);
    531   t.Start();
    532   t.Join();
    533 }
    534 }  // namespace
    535 
    536 
    537 // A regression test for mmap/munmap handling in Pin.
    538 // If the tool misses munmap() calls it may report a false positive if two
    539 // threads map the same memory region.
    540 namespace MmapRegressionTest {  // {{{1
    541 
    542 const int kMmapSize =  65536;
    543 const uintptr_t kStartAddress = 0x10000;
    544 
    545 StealthNotification n1;
    546 
    547 void Worker() {
    548     int *ptr = (int*)mmap((void*)kStartAddress, kMmapSize,
    549                           PROT_READ | PROT_WRITE,
    550                           MAP_PRIVATE | MAP_ANON, -1, 0);
    551     *ptr = 42;
    552     munmap(ptr, kMmapSize);
    553 }
    554 
    555 TEST(NegativeTests, MmapRegressionTest) {
    556   MyThreadArray t(Worker, Worker);
    557   t.Start();
    558   t.Join();
    559 }
    560 
    561 }  // namespace
    562 
    563 // test136. Unlock twice. {{{1
    564 namespace test136 {
    565 TEST(LockTests, UnlockTwice) {
    566   pthread_mutexattr_t attr;
    567   CHECK(0 == pthread_mutexattr_init(&attr));
    568   CHECK(0 == pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK));
    569 
    570   pthread_mutex_t mu;
    571   CHECK(0 == pthread_mutex_init(&mu, &attr));
    572   CHECK(0 == pthread_mutex_lock(&mu));
    573   CHECK(0 == pthread_mutex_unlock(&mu));
    574   int ret_unlock = pthread_mutex_unlock(&mu);  // unlocking twice.
    575   int ret_destroy = pthread_mutex_destroy(&mu);
    576   printf("  pthread_mutex_unlock returned %d\n", ret_unlock);
    577   printf("  pthread_mutex_destroy returned %d\n", ret_destroy);
    578 }
    579 }  // namespace test136
    580 
    581 
    582 // test141 FP. unlink/fopen, rmdir/opendir. {{{1
    583 namespace test141 {
    584 int GLOB1 = 0,
    585     GLOB2 = 0;
    586 char *dir_name = NULL,
    587      *filename = NULL;
    588 
    589 void Waker1() {
    590   usleep(100000);
    591   GLOB1 = 1;  // Write
    592   // unlink deletes a file 'filename'
    593   // which exits spin-loop in Waiter1().
    594   printf("  Deleting file...\n");
    595   CHECK(unlink(filename) == 0);
    596 }
    597 
    598 void Waiter1() {
    599   FILE *tmp;
    600   while ((tmp = fopen(filename, "r")) != NULL) {
    601     fclose(tmp);
    602     usleep(10000);
    603   }
    604   printf("  ...file has been deleted\n");
    605   GLOB1 = 2;  // Write
    606 }
    607 
    608 void Waker2() {
    609   usleep(100000);
    610   GLOB2 = 1;  // Write
    611   // rmdir deletes a directory 'dir_name'
    612   // which exit spin-loop in Waker().
    613   printf("  Deleting directory...\n");
    614   CHECK(rmdir(dir_name) == 0);
    615 }
    616 
    617 void Waiter2() {
    618   DIR *tmp;
    619   while ((tmp = opendir(dir_name)) != NULL) {
    620     closedir(tmp);
    621     usleep(10000);
    622   }
    623   printf("  ...directory has been deleted\n");
    624   GLOB2 = 2;
    625 }
    626 
    627 TEST(NegativeTests, test141) {
    628   printf("test141: FP. unlink/fopen, rmdir/opendir.\n");
    629 
    630   dir_name = strdup("/tmp/tsan-XXXXXX");
    631   CHECK(mkdtemp(dir_name) != 0);
    632 
    633   filename = strdup((std::string() + dir_name + "/XXXXXX").c_str());
    634   const int fd = mkstemp(filename);
    635   CHECK(fd >= 0);
    636   close(fd);
    637 
    638   MyThreadArray mta1(Waker1, Waiter1);
    639   mta1.Start();
    640   mta1.Join();
    641 
    642   MyThreadArray mta2(Waker2, Waiter2);
    643   mta2.Start();
    644   mta2.Join();
    645 
    646   free(filename);
    647   filename = 0;
    648   free(dir_name);
    649   dir_name = 0;
    650 }
    651 }  // namespace test141
    652 
    653 
    654 // test146: TP. Unit test for RWLock::TryLock and RWLock::ReaderTryLock. {{{1
    655 namespace test146 {
    656 // Worker1 locks the globals for writing for a long time.
    657 // Worker2 tries to write to globals twice: without a writer lock and with it.
    658 // Worker3 tries to read from globals twice: without a reader lock and with it.
    659 int     GLOB1 = 0;
    660 char    padding1[64];
    661 int     GLOB2 = 0;
    662 char    padding2[64];
    663 int     GLOB3 = 0;
    664 char    padding3[64];
    665 int     GLOB4 = 0;
    666 RWLock  MU;
    667 StealthNotification n1, n2, n3, n4, n5;
    668 
    669 void Worker1() {
    670   MU.Lock();
    671   GLOB1 = 1;
    672   GLOB2 = 1;
    673   GLOB3 = 1;
    674   GLOB4 = 1;
    675   n1.signal();
    676   n2.wait();
    677   n3.wait();
    678   MU.Unlock();
    679   n4.signal();
    680 }
    681 
    682 void Worker2() {
    683   n1.wait();
    684   if (MU.TryLock()) CHECK(0);
    685   else
    686     GLOB1 = 2;
    687   n2.signal();
    688   n5.wait();
    689   if (MU.TryLock()) {
    690     GLOB2 = 2;
    691     MU.Unlock();
    692   } else {
    693     CHECK(0);
    694   }
    695 }
    696 
    697 void Worker3() {
    698   n1.wait();
    699   if (MU.ReaderTryLock()) CHECK(0);
    700   else
    701     printf("\treading GLOB3: %d\n", GLOB3);
    702   n3.signal();
    703   n4.wait();
    704   if (MU.ReaderTryLock()) {
    705     printf("\treading GLOB4: %d\n", GLOB4);
    706     MU.ReaderUnlock();
    707   } else {
    708     CHECK(0);
    709   }
    710   n5.signal();
    711 }
    712 
    713 TEST(PositiveTests, test146) {
    714   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB1, "test146. TP: a data race on GLOB1.");
    715   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB3, "test146. TP: a data race on GLOB3.");
    716   ANNOTATE_TRACE_MEMORY(&GLOB1);
    717   ANNOTATE_TRACE_MEMORY(&GLOB2);
    718   ANNOTATE_TRACE_MEMORY(&GLOB3);
    719   ANNOTATE_TRACE_MEMORY(&GLOB4);
    720   printf("test146: positive\n");
    721   MyThreadArray t(Worker1, Worker2, Worker3);
    722   t.Start();
    723   t.Join();
    724   printf("\tGLOB1=%d\n", GLOB1);
    725   printf("\tGLOB2=%d\n", GLOB2);
    726   printf("\tGLOB3=%d\n", GLOB3);
    727   printf("\tGLOB4=%d\n", GLOB4);
    728 }
    729 } // namespace test146
    730 
    731 namespace PositiveTests_CyclicBarrierTest {  // {{{1
    732 #ifndef NO_BARRIER
    733 // regression test for correct support of cyclic barrier.
    734 // This test was suggested by Julian Seward.
    735 // There is a race on L here between a1 and b1,
    736 // but a naive support of barrier makes us miss this race.
    737 pthread_barrier_t B;
    738 int L;
    739 
    740 // A1/A2: write L, then wait for barrier, then sleep
    741 void a1() {
    742   L = 1;
    743   pthread_barrier_wait(&B);
    744   sleep(1);
    745 }
    746 void a2() {
    747   pthread_barrier_wait(&B);
    748   sleep(1);
    749 }
    750 
    751 // B1/B2: sleep, wait for barrier, then write L
    752 void b1() {
    753   sleep(1);
    754   pthread_barrier_wait(&B);
    755   L = 1;
    756 }
    757 void b2() {
    758   sleep(1);
    759   pthread_barrier_wait(&B);
    760 }
    761 
    762 TEST(PositiveTests, CyclicBarrierTest) {
    763   ANNOTATE_EXPECT_RACE_FOR_TSAN(&L, "real race, may be hidden"
    764                                 " by incorrect implementation of barrier");
    765   pthread_barrier_init(&B, NULL, 3);
    766   MyThreadArray t1(a1, a2, a2),
    767                 t2(b1, b2, b2);
    768   t1.Start();
    769   t2.Start();
    770   t1.Join();
    771   t2.Join();
    772 }
    773 
    774 
    775 int *G = NULL;
    776 
    777 void Worker() {
    778   pthread_barrier_wait(&B);
    779   (*G) = 1;
    780   pthread_barrier_wait(&B);
    781 }
    782 
    783 TEST(PositiveTests, CyclicBarrierTwoCallsTest) {
    784   pthread_barrier_init(&B, NULL, 2);
    785   G = new int(0);
    786   ANNOTATE_TRACE_MEMORY(G);
    787   ANNOTATE_EXPECT_RACE_FOR_TSAN(G, "real race, may be hidden"
    788                                 " by incorrect implementation of barrier");
    789   MyThreadArray t1(Worker, Worker);
    790   t1.Start();
    791   t1.Join();
    792   CHECK(*G == 1);
    793   delete G;
    794 }
    795 
    796 
    797 
    798 #endif  // NO_BARRIER
    799 }  // namespace
    800 
    801 TEST(NegativeTests, Mmap84GTest) {  // {{{1
    802 #ifdef ARCH_amd64
    803 #ifdef OS_linux
    804   // test that we can mmap 84G and can do it fast.
    805   size_t size = (1ULL << 32) * 21;  // 21 * 4G
    806   void *mem_ptr = mmap((void *) 0,
    807                        size,
    808                        PROT_EXEC | PROT_READ | PROT_WRITE,
    809                        MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE,
    810                        -1,
    811                        (off_t) 0);
    812   printf("res=%p\n", mem_ptr);
    813 #endif
    814 #endif
    815 }
    816 
    817 namespace NegativeTests_PthreadCreateFailureTest {  // {{{1
    818 #ifdef OS_linux
    819 void* ThreadRoutine(void *) {
    820   return NULL;
    821 }
    822 
    823 TEST(NegativeTests, PthreadCreateFailureTest) {
    824   pthread_attr_t attributes;
    825   pthread_attr_init(&attributes);
    826   pthread_attr_setstacksize(&attributes, -1);
    827   pthread_t handle;
    828   CHECK(pthread_create(&handle, &attributes, ThreadRoutine, NULL) != 0);
    829   pthread_attr_destroy(&attributes);
    830 }
    831 #endif  // OS_linux
    832 }  // namespace NegativeTests_PthreadCreateFailureTest
    833 
    834 namespace Signals {  // {{{1
    835 
    836 typedef void (*Sigaction)(int, siginfo_t *, void *);
    837 
    838 int     GLOB = 0;
    839 
    840 static void EnableSigprof(Sigaction SignalHandler) {
    841   struct sigaction sa;
    842   sa.sa_sigaction = SignalHandler;
    843   sa.sa_flags = SA_RESTART | SA_SIGINFO;
    844   sigemptyset(&sa.sa_mask);
    845   if (sigaction(SIGPROF, &sa, NULL) != 0) {
    846     perror("sigaction");
    847     abort();
    848   }
    849   struct itimerval timer;
    850   timer.it_interval.tv_sec = 0;
    851   timer.it_interval.tv_usec = 1000000 / 10000;
    852   timer.it_value = timer.it_interval;
    853   if (setitimer(ITIMER_PROF, &timer, 0) != 0) {
    854     perror("setitimer");
    855     abort();
    856   }
    857 }
    858 
    859 static void DisableSigprof() {
    860   // Disable the profiling timer.
    861   struct itimerval timer;
    862   timer.it_interval.tv_sec = 0;
    863   timer.it_interval.tv_usec = 0;
    864   timer.it_value = timer.it_interval;
    865   if (setitimer(ITIMER_PROF, &timer, 0) != 0) {
    866     perror("setitimer");
    867     abort();
    868   }
    869   // Ignore SIGPROFs from now on.
    870   struct sigaction sa;
    871   sa.sa_handler = SIG_IGN;
    872   sa.sa_flags = SA_RESTART | SA_SIGINFO;
    873   sigemptyset(&sa.sa_mask);
    874   if (sigaction(SIGPROF, &sa, NULL) != 0) {
    875     perror("sigaction");
    876     abort();
    877   }
    878 }
    879 
    880 void MallocTestWorker() {
    881   for (int i = 0; i < 100000; i++) {
    882     void *x = malloc((i % 64) + 1);
    883     free (x);
    884   }
    885 }
    886 
    887 // Regression test for
    888 // http://code.google.com/p/data-race-test/issues/detail?id=13 .
    889 // Make sure that locking events are handled in signal handlers.
    890 //
    891 // For some reason, invoking the signal handlers causes deadlocks on Mac OS.
    892 #ifndef __APPLE__
    893 Mutex mu;
    894 
    895 void SignalHandlerWithMutex(int, siginfo_t*, void*) {
    896   mu.Lock();
    897   GLOB++;
    898   mu.Unlock();
    899 }
    900 
    901 TEST(Signals, SignalsAndMallocTestWithMutex) {
    902   EnableSigprof(SignalHandlerWithMutex);
    903   MyThreadArray t(MallocTestWorker, MallocTestWorker, MallocTestWorker);
    904   t.Start();
    905   t.Join();
    906   printf("\tGLOB=%d\n", GLOB);
    907   DisableSigprof();
    908 }
    909 #endif
    910 
    911 // Another regression test for
    912 // http://code.google.com/p/data-race-test/issues/detail?id=13 .
    913 // Make sure that locking events are handled in signal handlers.
    914 SpinLock sl;
    915 
    916 void SignalHandlerWithSpinlock(int, siginfo_t*, void*) {
    917   sl.Lock();
    918   GLOB++;
    919   sl.Unlock();
    920 }
    921 
    922 TEST(Signals, DISABLED_SignalsAndMallocTestWithSpinlock) {
    923   EnableSigprof(SignalHandlerWithSpinlock);
    924   MyThreadArray t(MallocTestWorker, MallocTestWorker, MallocTestWorker);
    925   t.Start();
    926   t.Join();
    927   printf("\tGLOB=%d\n", GLOB);
    928   DisableSigprof();
    929 }
    930 
    931 // Regression test for
    932 // http://code.google.com/p/data-race-test/issues/detail?id=14.
    933 static void WaitTestSignalHandler(int, siginfo_t*, void*) {
    934   ANNOTATE_HAPPENS_AFTER((void*)0x1234);
    935 }
    936 
    937 void WaitTestWorker() {
    938   for (int i = 0; i < 1000000; i++) {
    939     ANNOTATE_HAPPENS_AFTER((void*)0x1234);
    940   }
    941 }
    942 
    943 TEST(Signals, SignalsAndWaitTest) {
    944   EnableSigprof(WaitTestSignalHandler);
    945   MyThreadArray t(WaitTestWorker, WaitTestWorker, WaitTestWorker);
    946   t.Start();
    947   t.Join();
    948   DisableSigprof();
    949 }
    950 
    951 #ifndef __APPLE__
    952 // this test crashes on Mac in debug TSan build, see
    953 // http://code.google.com/p/data-race-test/issues/detail?id=47
    954 pid_t child_pid = 0;
    955 
    956 void child_handler(int signum) {
    957   if (signum == SIGCHLD && child_pid == 0) {
    958     printf("Whoops, PID shouldn't be 0!\n");
    959   }
    960 }
    961 
    962 TEST(Signals, PositiveTests_RaceInSignal) {
    963   // Currently the data race on child_pid can't be found,
    964   // see http://code.google.com/p/data-race-test/issues/detail?id=46
    965   //ANNOTATE_EXPECT_RACE(&child_pid, "Race on pid: fork vs signal handler");
    966   signal(SIGCHLD, child_handler);
    967   child_pid = fork();
    968   if (child_pid == 0) {
    969     // in child
    970     exit(0);
    971   }
    972   wait(NULL);
    973 }
    974 #endif  // __APPLE__
    975 
    976 }  // namespace;
    977 
    978 TEST(WeirdSizesTests, FegetenvTest) {
    979   // http://code.google.com/p/data-race-test/issues/detail?id=36
    980   fenv_t tmp;
    981   if (fegetenv(&tmp) != 0)
    982     FAIL() << "fegetenv failed";
    983 }
    984 
    985 namespace NegativeTests_epoll {  // {{{1
    986 #ifdef OS_linux
    987 int GLOB;
    988 
    989 // Currently, ThreadSanitizer should create hb arcs between
    990 // epoll_ctl and epoll_wait regardless of the parameters. Check that.
    991 
    992 void Worker1() {
    993   GLOB++;
    994   struct epoll_event event;
    995   epoll_ctl(0, 0, 0, &event);
    996 }
    997 void Worker2() {
    998   struct epoll_event event;
    999   epoll_wait(0, &event, 0, 0);
   1000   GLOB++;
   1001 }
   1002 
   1003 TEST(NegativeTests,epollTest) {
   1004   MyThreadArray mta(Worker1, Worker2);
   1005   mta.Start();
   1006   mta.Join();
   1007 }
   1008 #endif  // OS_linux
   1009 }
   1010 namespace NegativeTests_LockfTest {  // {{{1
   1011 
   1012 class ShmMutex {
   1013  public:
   1014   ShmMutex() : fd_(-1) { }
   1015   void set_fd(int fd) {
   1016     CHECK(fd_ == -1);
   1017     fd_ = fd;
   1018   }
   1019   void Lock() {
   1020     LockOrUnlockInternal(true);
   1021   }
   1022   void Unlock() {
   1023     LockOrUnlockInternal(false);
   1024   }
   1025  private:
   1026   void LockOrUnlockInternal(bool lock) {
   1027     CHECK(fd_ >= 0);
   1028     while (lockf(fd_, lock ? F_LOCK : F_ULOCK, 0) < 0) {
   1029       if (errno == EINTR) {
   1030         continue;
   1031       } else if (errno == ENOLCK) {
   1032         usleep(5000);
   1033         continue;
   1034       }
   1035       CHECK(0);
   1036     }
   1037 
   1038   }
   1039 
   1040   int fd_;
   1041 } mu;
   1042 
   1043 int GLOB;
   1044 
   1045 void Worker() {
   1046   mu.Lock();
   1047   GLOB++;
   1048   mu.Unlock();
   1049 }
   1050 
   1051 TEST(NegativeTests,DISABLED_LockfTest) {
   1052   mu.set_fd(1 /* stdout */);
   1053   MyThreadArray mta(Worker, Worker);
   1054   mta.Start();
   1055   mta.Join();
   1056 }
   1057 
   1058 }
   1059 namespace PositiveTests_LockThenNoLock {  // {{{1
   1060 // Regression test for a bug fixed by r2312
   1061 int GLOB;
   1062 pthread_mutex_t mu;
   1063 StealthNotification n1, n2;
   1064 
   1065 void Worker1() {
   1066   pthread_mutex_lock(&mu);
   1067   GLOB = 1;
   1068   pthread_mutex_unlock(&mu);
   1069   n1.signal();
   1070   n2.wait();
   1071   GLOB = 2;
   1072 }
   1073 
   1074 void Worker2() {
   1075   pthread_mutex_lock(&mu);
   1076   GLOB = 3;
   1077   pthread_mutex_unlock(&mu);
   1078   n2.signal();
   1079   n1.wait();
   1080   GLOB = 4;
   1081 }
   1082 
   1083 TEST(PositiveTests, LockThenNoLock) {
   1084   pthread_mutex_init(&mu, NULL);
   1085   ANNOTATE_TRACE_MEMORY(&GLOB);
   1086   ANNOTATE_EXPECT_RACE(&GLOB, "race");
   1087   ANNOTATE_NOT_HAPPENS_BEFORE_MUTEX(&mu);
   1088   MyThreadArray t(Worker1, Worker2);
   1089   t.Start();
   1090   t.Join();
   1091   pthread_mutex_destroy(&mu);
   1092 }
   1093 }  // namespace
   1094 
   1095 #ifdef __APPLE__
   1096 namespace NegativeTests_PthreadCondWaitRelativeNp {  // {{{1
   1097 int GLOB = 0;
   1098 pthread_mutex_t mu;
   1099 pthread_cond_t cv;
   1100 
   1101 void Waiter() {
   1102   struct timespec tv = {1000, 1000};
   1103   pthread_mutex_lock(&mu);
   1104   pthread_cond_timedwait_relative_np(&cv, &mu, &tv);
   1105   GLOB = 2;
   1106   pthread_mutex_unlock(&mu);
   1107 }
   1108 
   1109 void Waker() {
   1110   pthread_mutex_lock(&mu);
   1111   GLOB = 1;
   1112   pthread_cond_signal(&cv);
   1113   pthread_mutex_unlock(&mu);
   1114 }
   1115 
   1116 TEST(NegativeTests, PthreadCondWaitRelativeNpTest) {
   1117   pthread_mutex_init(&mu, NULL);
   1118   pthread_cond_init(&cv, NULL);
   1119   MyThreadArray t(Waiter, Waker);
   1120   t.Start();
   1121   t.Join();
   1122   pthread_mutex_destroy(&mu);
   1123   pthread_cond_destroy(&cv);
   1124 }
   1125 }  // namespace
   1126 #endif  // __APPLE__
   1127 
   1128 namespace PositiveTests_RWLockVsRWLockTest {  // {{{1
   1129 // Test that reader lock/unlock do not create a hb-arc.
   1130 RWLock mu;
   1131 int GLOB;
   1132 StealthNotification n;
   1133 
   1134 void Thread1() {
   1135   GLOB = 1;
   1136   mu.ReaderLock();
   1137   mu.ReaderUnlock();
   1138   n.signal();
   1139 }
   1140 
   1141 void Thread2() {
   1142   n.wait();
   1143   mu.ReaderLock();
   1144   mu.ReaderUnlock();
   1145   GLOB = 1;
   1146 }
   1147 
   1148 TEST(PositiveTests, RWLockVsRWLockTest) {
   1149   ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&mu);
   1150   ANNOTATE_EXPECT_RACE(&GLOB, "rwunlock/rwlock is not a hb-arc");
   1151   MyThreadArray t(Thread1, Thread2);
   1152   t.Start();
   1153   t.Join();
   1154 }
   1155 
   1156 }  // namespace
   1157 
   1158 namespace TSDTests {
   1159 // Test the support for libpthread TSD destructors.
   1160 pthread_key_t key;
   1161 const int kInitialValue = 0xfeedface;
   1162 int tsd_array[2];
   1163 
   1164 void Destructor(void *ptr) {
   1165   int *write = (int*) ptr;
   1166   *write = kInitialValue;
   1167 }
   1168 
   1169 void DoWork(int index) {
   1170   int *value = &(tsd_array[index]);
   1171   *value = 42;
   1172   pthread_setspecific(key, value);
   1173   int *read = (int*) pthread_getspecific(key);
   1174   CHECK(read == value);
   1175 }
   1176 
   1177 void Worker0() { DoWork(0); }
   1178 void Worker1() { DoWork(1); }
   1179 
   1180 TEST(TSDTests, TSDDestructorTest) {
   1181   pthread_key_create(&key, Destructor);
   1182   MyThreadArray t(Worker0, Worker1);
   1183   t.Start();
   1184   t.Join();
   1185   for (int i = 0; i < 2; ++i) {
   1186     CHECK(tsd_array[i] == kInitialValue);
   1187   }
   1188 }
   1189 
   1190 }
   1191 
   1192 // End {{{1
   1193  // vim:shiftwidth=2:softtabstop=2:expandtab:foldmethod=marker
   1194