DRD: a thread error detector
1. Start at the bottom of both call stacks, and count the number stack frames with identical function name, file name
and line number. In the above example the three bottommost frames are identical (
clone
,
start_thread
and
vg_thread_wrapper
).
2. The next higher stack frame in both call stacks now tells you between in which source code region the other
memory access happened. The above output tells that the other memory access involved in the data race happened
between source code lines 28 and 30 in file
rwlock_race.c
.
8.2.3. Detected Errors: Lock Contention
Threads must be able to make progress without being blocked for too long by other threads. Sometimes a thread
has to wait until a mutex or reader-writer synchronization object is unlocked by another thread. This is called
lock
contention
.
Lock contention causes delays.
Such delays should be as short as possible.
The two command line options
--exclusive-threshold=<n>
and
--shared-threshold=<n>
make it possible to detect excessive lock
contention by making DRD report any lock that has been held longer than the specified threshold. An example:
$ valgrind --tool=drd --exclusive-threshold=10 drd/tests/hold_lock -i 500
...
==10668== Acquired at:
==10668==
at 0x4C267C8: pthread_mutex_lock (drd_pthread_intercepts.c:395)
==10668==
by 0x400D92: main (hold_lock.c:51)
==10668== Lock on mutex 0x7fefffd50 was held during 503 ms (threshold: 10 ms).
==10668==
at 0x4C26ADA: pthread_mutex_unlock (drd_pthread_intercepts.c:441)
==10668==
by 0x400DB5: main (hold_lock.c:55)
...
The
hold_lock
test program holds a lock as long as specified by the
-i
(interval) argument. The DRD output
reports that the lock acquired at line 51 in source file
hold_lock.c
and released at line 55 was held during 503 ms,
while a threshold of 10 ms was specified to DRD.
8.2.4. Detected Errors: Misuse of the POSIX threads API
DRD is able to detect and report the following misuses of the POSIX threads API:
• Passing the address of one type of synchronization object (e.g. a mutex) to a POSIX API call that expects a pointer
to another type of synchronization object (e.g. a condition variable).
• Attempts to unlock a mutex that has not been locked.
• Attempts to unlock a mutex that was locked by another thread.
• Attempts to lock a mutex of type
PTHREAD_MUTEX_NORMAL
or a spinlock recursively.
• Destruction or deallocation of a locked mutex.
• Sending a signal to a condition variable while no lock is held on the mutex associated with the condition variable.
127