Helgrind: a thread error detector
Thread #2 was created
at 0x511C08E: clone (in /lib64/libc-2.8.so)
by 0x4E333A4: do_clone (in /lib64/libpthread-2.8.so)
by 0x4E33A30: pthread_create@@GLIBC_2.2.5 (in /lib64/libpthread-2.8.so)
by 0x4C299D4: pthread_create@* (hg_intercepts.c:214)
by 0x4008F2: main (tc21_pthonce.c:86)
Thread #3 was created
at 0x511C08E: clone (in /lib64/libc-2.8.so)
by 0x4E333A4: do_clone (in /lib64/libpthread-2.8.so)
by 0x4E33A30: pthread_create@@GLIBC_2.2.5 (in /lib64/libpthread-2.8.so)
by 0x4C299D4: pthread_create@* (hg_intercepts.c:214)
by 0x4008F2: main (tc21_pthonce.c:86)
Possible data race during read of size 4 at 0x601070 by thread #3
Locks held: none
at 0x40087A: child (tc21_pthonce.c:74)
by 0x4C29AFF: mythread_wrapper (hg_intercepts.c:194)
by 0x4E3403F: start_thread (in /lib64/libpthread-2.8.so)
by 0x511C0CC: clone (in /lib64/libc-2.8.so)
This conflicts with a previous write of size 4 by thread #2
Locks held: none
at 0x400883: child (tc21_pthonce.c:74)
by 0x4C29AFF: mythread_wrapper (hg_intercepts.c:194)
by 0x4E3403F: start_thread (in /lib64/libpthread-2.8.so)
by 0x511C0CC: clone (in /lib64/libc-2.8.so)
Location 0x601070 is 0 bytes inside local var "unprotected2"
declared at tc21_pthonce.c:51, in frame #0 of thread 3
Helgrind first announces the creation points of any threads referenced in the error message.
This is so it can speak
concisely about threads without repeatedly printing their creation point call stacks. Each thread is only ever announced
once, the first time it appears in any Helgrind error message.
The main error message begins at the text "
Possible data race during read
". At the start is information
you would expect to see -- address and size of the racing access, whether a read or a write, and the call stack at the
point it was detected.
A second call stack is presented starting at the text "
This conflicts with a previous write
".
This
shows a previous access which also accessed the stated address, and which is believed to be racing against the access
in the first call stack. Note that this second call stack is limited to a maximum of 8 entries to limit the memory usage.
Finally, Helgrind may attempt to give a description of the raced-on address in source level terms. In this example, it
identifies it as a local variable, shows its name, declaration point, and in which frame (of the first call stack) it lives.
Note that this information is only shown when
--read-var-info=yes
is specified on the command line. That’s
because reading the DWARF3 debug information in enough detail to capture variable type and location information
makes Helgrind much slower at startup, and also requires considerable amounts of memory, for large programs.
Once you have your two call stacks, how do you find the root cause of the race?
114