My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
RaceCheckerClass  
The RaceChecker class -- helps confirming data races.
Updated Feb 4, 2010 by konstant...@gmail.com

The RaceChecker class helps confirming data races, e.g. those detected by Helgrind or ThreadSanitizer.

If RaceChecker detected a race it is a 100% proof of a race. If it did not detect a race it proves nothing.

How it works

When the program enters RaceChecker's constructor, it remembers the address of the racey object (e.g. &foo) and then sleeps. Then, in the destructor, it forgets &foo.

If Thread2 entered RaceChecker's constructor while Thread1 is sleeping in RaceChecker's constructor with the same racey object (&foo), there are two concurrent accesses to &foo. If one of them is write -- bingo, we found a race. The code is pretty simple, it might be better than my explanation :)

See race_checker.h and all race checker files for details.

Example

int foo = 0;  // The racey address.

// Several reads and writes, nested calls to RaceChecker.
void ReaderAndWriter() {
  for (int i = 0; i < 1000; i++) {
    RaceChecker read_checker(RaceChecker::READ, &foo);
    assert(foo >= 0);  // Just a read.
    if ((i % 10) == 0) {
      RaceChecker write_checker(RaceChecker::WRITE, &foo);
      foo++;
    }
    assert(foo >= 0);  // Just a read.
  }
}

// More functions to make the stack traces more interesting.
static void *Dummy3(void *x) { ReaderAndWriter(); return NULL; }
static void *Dummy2(void *x) { return Dummy3(x); }
static void *Dummy1(void *x) { return Dummy2(x); }

int main() {
  pthread_t threads[3];
  pthread_create(&threads[0], NULL, &Dummy1, NULL);
  pthread_create(&threads[1], NULL, &Dummy2, NULL);
  pthread_create(&threads[2], NULL, &Dummy3, NULL);

  pthread_join(threads[0], NULL);
  pthread_join(threads[1], NULL);
  pthread_join(threads[2], NULL);
}
% g++ -g race_checker.cc race_checker_unittest.cc -lpthread
% RACECHECKER=1 ./a.out 2>&1 | head -19  | ./symbolize.py | c++filt
Race found between these points
=== writer:
./a.out[0x40541a] <ReaderAndWriter()>
./a.out[0x4054a7] <Dummy3(void*)>
./a.out[0x4054c3] <Dummy2(void*)>
./a.out[0x4054db] <Dummy1(void*)>
/lib64/tls/libpthread.so.0[0x2aaaaacc7f9f] <_fini>
/lib64/tls/libc.so.6(clone+0x72)[0x2aaaab719ea2]
=== reader:
./a.out[0x4053ae] <ReaderAndWriter()>
./a.out[0x4054a7] <Dummy3(void*)>
./a.out[0x4054c3] <Dummy2(void*)>
/lib64/tls/libpthread.so.0[0x2aaaaacc7f9f] <_fini>
/lib64/tls/libc.so.6(clone+0x72)[0x2aaaab719ea2]
=== reader:
./a.out[0x4053ae] <ReaderAndWriter()>
./a.out[0x4054a7] <Dummy3(void*)>
/lib64/tls/libpthread.so.0[0x2aaaaacc7f9f] <_fini>
/lib64/tls/libc.so.6(clone+0x72)[0x2aaaab719ea2]
Comment by pharaoh...@gmail.com, May 8, 2009

Bit confused here. How does the race checker class confirm these data races? My understanding is as follows:

1. Get a list of potential data races using ThreadSanitizer or Helgrind, say you got 10 data races.

2. Re run the program again as shown in above example. 3. Only the data races which are confirmed will be reported i.e. filter out the in feasible data races. So at the end of this step we might get only say 2 data races which are certainly present.

Is this correct? How does the race_checker class works?

Comment by project member konstant...@gmail.com, May 8, 2009

If RaceChecker detected a race it is a 100% proof of a race. If it did not detect a race it proves nothing. In my experience, almost all races are confirmed by RaceChecker, but you need play with different values of timeout.

When the program enters RaceChecker?'s constructor, it remembers the address of the racey object (e.g. foo) and then sleeps. Then, in the destructor, it forgets foo.

If Thread2 entered RaceChecker?'s constructor while Thread1 is sleeping in RaceChecker?'s constructor with the same racey object (foo), there are two concurrent accesses to foo. If one of them is write -- bingo, we found a race. The code is pretty simple, it might be better than my explanation :)

Comment by pharaoh...@gmail.com, May 11, 2009

Thanks, this is very helpful.

Comment by bomb...@gmail.com, Jun 5, 2009

A few relevant references:

K. Sen, "Race Directed Random Testing of Concurrent Programs," in Proc. ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI'08), 2008, pp. 11-21.

http://spl.cs.berkeley.edu/~ksen/papers/raced.pdf

http://srl.cs.berkeley.edu/~ksen/calfuzzer/


Sign in to add a comment
Powered by Google Project Hosting