brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · 29f0964 Raw
233 lines · cpp
1//===-- tsan_mop.cpp ------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of ThreadSanitizer (TSan), a race detector.10//11//===----------------------------------------------------------------------===//12#include "tsan_interface.h"13#include "tsan_test_util.h"14#include "gtest/gtest.h"15#include <stddef.h>16#include <stdint.h>17 18TEST_F(ThreadSanitizer, SimpleWrite) {19  ScopedThread t;20  MemLoc l;21  t.Write1(l);22}23 24TEST_F(ThreadSanitizer, SimpleWriteWrite) {25  ScopedThread t1, t2;26  MemLoc l1, l2;27  t1.Write1(l1);28  t2.Write1(l2);29}30 31TEST_F(ThreadSanitizer, WriteWriteRace) {32  ScopedThread t1, t2;33  MemLoc l;34  t1.Write1(l);35  t2.Write1(l, true);36}37 38TEST_F(ThreadSanitizer, ReadWriteRace) {39  ScopedThread t1, t2;40  MemLoc l;41  t1.Read1(l);42  t2.Write1(l, true);43}44 45TEST_F(ThreadSanitizer, WriteReadRace) {46  ScopedThread t1, t2;47  MemLoc l;48  t1.Write1(l);49  t2.Read1(l, true);50}51 52TEST_F(ThreadSanitizer, ReadReadNoRace) {53  ScopedThread t1, t2;54  MemLoc l;55  t1.Read1(l);56  t2.Read1(l);57}58 59TEST_F(ThreadSanitizer, WriteThenRead) {60  MemLoc l;61  ScopedThread t1, t2;62  t1.Write1(l);63  t1.Read1(l);64  t2.Read1(l, true);65}66 67TEST_F(ThreadSanitizer, WriteThenLockedRead) {68  UserMutex m(UserMutex::RW);69  MainThread t0;70  t0.Create(m);71  MemLoc l;72  {73    ScopedThread t1, t2;74 75    t1.Write8(l);76 77    t1.Lock(m);78    t1.Read8(l);79    t1.Unlock(m);80 81    t2.Read8(l, true);82  }83  t0.Destroy(m);84}85 86TEST_F(ThreadSanitizer, LockedWriteThenRead) {87  UserMutex m(UserMutex::RW);88  MainThread t0;89  t0.Create(m);90  MemLoc l;91  {92    ScopedThread t1, t2;93 94    t1.Lock(m);95    t1.Write8(l);96    t1.Unlock(m);97 98    t1.Read8(l);99 100    t2.Read8(l, true);101  }102  t0.Destroy(m);103}104 105 106TEST_F(ThreadSanitizer, RaceWithOffset) {107  ScopedThread t1, t2;108  {109    MemLoc l;110    t1.Access(l.loc(), true, 8, false);111    t2.Access((char*)l.loc() + 4, true, 4, true);112  }113  {114    MemLoc l;115    t1.Access(l.loc(), true, 8, false);116    t2.Access((char*)l.loc() + 7, true, 1, true);117  }118  {119    MemLoc l;120    t1.Access((char*)l.loc() + 4, true, 4, false);121    t2.Access((char*)l.loc() + 4, true, 2, true);122  }123  {124    MemLoc l;125    t1.Access((char*)l.loc() + 4, true, 4, false);126    t2.Access((char*)l.loc() + 6, true, 2, true);127  }128  {129    MemLoc l;130    t1.Access((char*)l.loc() + 3, true, 2, false);131    t2.Access((char*)l.loc() + 4, true, 1, true);132  }133  {134    MemLoc l;135    t1.Access((char*)l.loc() + 1, true, 8, false);136    t2.Access((char*)l.loc() + 3, true, 1, true);137  }138}139 140TEST_F(ThreadSanitizer, RaceWithOffset2) {141  ScopedThread t1, t2;142  {143    MemLoc l;144    t1.Access((char*)l.loc(), true, 4, false);145    t2.Access((char*)l.loc() + 2, true, 1, true);146  }147  {148    MemLoc l;149    t1.Access((char*)l.loc() + 2, true, 1, false);150    t2.Access((char*)l.loc(), true, 4, true);151  }152}153 154TEST_F(ThreadSanitizer, NoRaceWithOffset) {155  ScopedThread t1, t2;156  {157    MemLoc l;158    t1.Access(l.loc(), true, 4, false);159    t2.Access((char*)l.loc() + 4, true, 4, false);160  }161  {162    MemLoc l;163    t1.Access((char*)l.loc() + 3, true, 2, false);164    t2.Access((char*)l.loc() + 1, true, 2, false);165    t2.Access((char*)l.loc() + 5, true, 2, false);166  }167}168 169TEST_F(ThreadSanitizer, RaceWithDeadThread) {170  MemLoc l;171  ScopedThread t;172  ScopedThread().Write1(l);173  t.Write1(l, true);174}175 176TEST_F(ThreadSanitizer, BenignRaceOnVptr) {177  void *vptr_storage;178  MemLoc vptr(&vptr_storage), val;179  vptr_storage = val.loc();180  ScopedThread t1, t2;181  t1.VptrUpdate(vptr, val);182  t2.Read8(vptr);183}184 185TEST_F(ThreadSanitizer, HarmfulRaceOnVptr) {186  void *vptr_storage;187  MemLoc vptr(&vptr_storage), val1, val2;188  vptr_storage = val1.loc();189  ScopedThread t1, t2;190  t1.VptrUpdate(vptr, val2);191  t2.Read8(vptr, true);192}193 194static void foo() {195  volatile int x = 42;196  int x2 = x;197  (void)x2;198}199 200static void bar() {201  volatile int x = 43;202  int x2 = x;203  (void)x2;204}205 206TEST_F(ThreadSanitizer, ReportDeadThread) {207  MemLoc l;208  ScopedThread t1;209  {210    ScopedThread t2;211    t2.Call(&foo);212    t2.Call(&bar);213    t2.Write1(l);214  }215  t1.Write1(l, true);216}217 218struct ClassWithStatic {219  static int Data[4];220};221 222int ClassWithStatic::Data[4];223 224static void foobarbaz() {}225 226TEST_F(ThreadSanitizer, ReportRace) {227  ScopedThread t1;228  MainThread().Access(&ClassWithStatic::Data, true, 4, false);229  t1.Call(&foobarbaz);230  t1.Access(&ClassWithStatic::Data, true, 2, true);231  t1.Return();232}233