Chapter 27 — A Real Data Race and a Real AB/BA Deadlock
Two deliberately broken programs, each made to fail every run rather than occasionally, debugged with ThreadSanitizer and a live gdb attach.
The full source for this example lives in
examples/concurrency/27-debugging-races-deadlocks/— clone the repo,cdin, and./demo.sh.
Chapter reference: Doc 27 — Debugging Real Races and Deadlocks
What it shows
racy_counter has two threads increment a shared, non-atomic int with no synchronization; the program’s own printed total can look correct or corrupted from run to run, so it’s ThreadSanitizer’s report — not any single run’s output — that proves the defect. ab_ba_deadlock forces two threads into a textbook AB/BA deadlock on every run using a std::latch, and a backgrounded instance gets gdb -p <pid> attached live, reading the lock cycle straight off both threads’ real backtraces rather than inferring it from source. The deadlock build never resolving on its own, and the fixed scoped_lock build always completing, are hard assertions; TSan’s and gdb’s reports are hard whenever the environment lets the respective tool run, and a documented soft skip otherwise.
Running it
cd examples/concurrency/27-debugging-races-deadlocks
./demo.sh # build + run (TSan + gdb checks) + verify.lua
./demo.sh --clean # remove the image