Tuesday, November 18, 2008

TotT: Finding Data Races in C++

If you've got some multi-threaded code, you may have data races in it. Data races are hard to find and reproduce – usually they will not occur in testing but will fire once a month in production.

For example, you ask each of your two interns to bring you a bottle of beer. This will usually result in your getting two bottles (perhaps empty), but in a rare situation that the interns collide near the fridge, you may get fewer bottles.

4 int bottles_of_beer = 0;
5 void Intern1() { bottles_of_beer++; } // Intern1 forgot to use Mutex.
6 void Intern2() { bottles_of_beer++; } // Intern2 copied from Intern1.
7 int main() {
8 // Folks, bring me one bottle of beer each, please.
9 ClosureThread intern1(NewPermanentCallback(Intern1)),
10 intern2(NewPermanentCallback(Intern2));
11 intern1.SetJoinable(true); intern2.SetJoinable(true);
12 intern1.Start(); intern2.Start();
13 intern1.Join(); intern2.Join();
14 CHECK_EQ(2, bottles_of_beer) << "Who didn't bring me my beer!?";
15 }

Want to find data races in your code? Run your program under Helgrind!

$ helgrind path/to/your/program
Possible data race during read of size 4 at 0x5429C8
at 0x400523: Intern2() tott.cc:6

by 0x400913: _FunctionResultCallback_0_0::Run() ...
by 0x4026BB: ClosureThread::Run() ...
Location 0x5429C8 has never been protected by any lock
Location 0x5429C8 is 0 bytes inside global var "bottles_of_beer"
declared at tott.cc:4

Helgrind will also detect deadlocks for you.

Helgrind is a tool based on Valgrind. Valgrind is a binary translation framework which has other useful tools such as a memory debugger and a cache simulator. Related TotT episodes will follow.

No beer was wasted in the making of this TotT.

Remember to download this episode of Testing on the Toilet and post it in your office.
[NFGB] Link - from Google Testing Blog
Related From Google Blogs:
Better targeting your indic language site
Voice and video chat now in Gmail
Drum roll please: Introducing SketchUp 7
Sites goes international

No comments: