Concurrency Debugging
Purpose
Guide agents through diagnosing and fixing concurrency bugs: reading ThreadSanitizer race reports, using Helgrind for lock-order analysis, detecting deadlocks with GDB thread inspection, identifying common std::atomic misuse patterns, and applying happens-before reasoning in C++ and Rust.
Triggers
- "ThreadSanitizer reported a data race — how do I read the report?"
- "My program deadlocks — how do I debug it?"
- "How do I use Helgrind to find threading bugs?"
- "Am I using std::atomic correctly?"
- "How does happens-before work in C++ memory ordering?"
- "How do I find which threads are deadlocked in GDB?"
Workflow
1. ThreadSanitizer (TSan) — race detection
Reading a TSan report:
How to read:
- Line 1: type of access (write/read) and address
- Stack under "Write of size": the thread that performed the write
- Stack under "Previous read/write": the conflicting thread
- "Thread T2 created at": where the thread was spawned
- Fix: the
incrementandread_counterfunctions access the same address without synchronization
Common races and fixes:
2. Helgrind — lock-order and race detection
Helgrind uses Valgrind infrastructure to detect lock ordering violations (potential deadlocks) and data races:
Lock-order violation = potential deadlock:
- Thread T1 acquires M1, then tries M2
- Thread T2 acquires M2, then tries M1
- Both can deadlock if they race
Fix: enforce a consistent global lock ordering. Always take M1 before M2 everywhere.
3. Deadlock detection with GDB
4. std::atomic misuse patterns
5. Happens-before reasoning
In C++, happens-before is established by:
6. Rust concurrency — compile-time guarantees
Rust prevents data races at compile time via ownership:
Related skills
- Use
skills/runtimes/sanitizersfor TSan build flags and other sanitizers - Use
skills/profilers/valgrindfor Helgrind and Memcheck integration - Use
skills/debuggers/gdbfor advanced GDB thread inspection - Use
skills/low-level-programming/memory-modelfor C++/Rust memory ordering theory


