5.3.14 · HinglishBuild Systems & Toolchain

Thread Sanitizer (TSan)

2,205 words10 min readRead in English

5.3.14 · Coding › Build Systems & Toolchain


TSan exist kyun karta hai?

KIS problem class mein: concurrent unsynchronized access se undefined behavior (torn reads/writes, lost updates, visibility bugs). C/C++ mein ek data race seedha undefined behavior hai; compiler kuch bhi kar sakta hai.


Core theory: happens-before


TSan actually kaise detect karta hai? (scratch se derivation)

Hum chahte hain ki har memory location ke liye answer milein: "kya yeh do accesses ordered hain?" Hum data structure ko step by step derive karte hain.

Step 1 — har thread ko ek clock do

Har thread ke paas ek counter hota hai jo har synchronization event par tick karta hai. Ise kehte hain.

Step 2 — vector clocks (dil ki baat)

Ek single counter track nahi kar sakta ek thread doosron ke baare mein kya jaanta hai. Isliye thread ek vector clock rakhta hai: ek array jisme har thread ke liye ek entry hoti hai.

Yeh step kyun? encode karta hai "woh sab kuch jo thread mein abhi tak happens-before hua hai." Agar thread ki ke baare mein current knowledge ki write ko already cover karti hai, toh woh write happened-before hai — koi race nahi.

Rules (happens-before axioms se derive kiye gaye):

  • Local tick: apne sync event par, .
  • Release (unlock ): ko lock ke clock mein copy karo, (componentwise max).
  • Acquire (lock ): lock ka knowledge absorb karo, .

Yeh exactly axiom 2 (release/acquire) ko mechanical banata hai: max histories ko merge karta hai.

Step 3 — har location ke liye shadow memory

Har application byte ke liye, TSan shadow cells store karta hai jo kuch pichle accesses describe karte hain: kaun sa thread, us waqt thread ki clock value, aur read/write flag.

Step 4 — race check

Jab thread location ko access karta hai, thread (clock ) ka pehle se record kiya gaya access dekho:

Figure — Thread Sanitizer (TSan)
Recall Feynman: ek 12-saal ke bacche ko explain karo

Imagine karo do bacche ek hi Google Doc edit kar rahe hain. Agar woh baari-baari karte hain (ek khatam karta hai, phir doosre ko bolta hai "teri baari"), toh kabhi mess nahi hoti. Lekin agar dono bina ek doosre ko bataye ek hi line mein type karte hain, toh words scramble ho jaate hain — aur yeh sirf kabhi-kabhi scramble hota hai, toh tum dobaara padh ke pakad nahi sakte. TSan ek hall monitor ki tarah hai jo har baar likhta hai jab ek baccha kuch likhta hai, aur yeh bhi note karta hai jab bhi koi baccha actually note pass karta hai yeh kehte hue "teri baari." Agar kid B ek aisi line edit karta hai jo kid A ne likhi thi lekin A ne B ko kabhi us baare mein note nahi pass kiya, toh monitor seeti bajata hai: "Tum dono collide kar sakte ho!" — chahe us din woh actually collide na kiye hon.


TSan use karna (practical 20%)

# Compile AUR link dono par flag lagao (yeh runtime change karta hai).
clang -fsanitize=thread -g -O1 race.c -o race
./race          # agar is run par race hoti hai toh report print karta hai
  • clang/gcc ke saath kaam karta hai. Line numbers ke liye -g add karo, -O1 ise fast aur readable rakhta hai.
  • Runtime cost: ~5–15× slower, ~5–10× zyada memory. Tests/CI par chalao, prod par nahi.
  • Detect karta hai: data races, deadlocks (lock-order inversions), pthread/std::mutex ka kuch galat istemal, destructors mein use-after-free.
  • TSAN_OPTIONS=halt_on_error=1 pehli race par rokne ke liye; known-benign waalon ko chup karaane ke liye suppression files.

Common galtiyan (steel-manned)


Forecast-then-Verify drill


Flashcards

Data race define karne waali teen conditions kya hain?
Same location, kam se kam ek write, aur accesses happens-before se ordered nahi hain (concurrent).
Do concurrent reads kabhi data race kyun nahi ho sakti?
Na hi koi value change karta hai, isliye order irrelevant hai — result interleaving se independent rehta hai.
Happens-before relation kya hai?
(1) ek thread ke andar program order, (2) same object par release→acquire synchronization, aur (3) transitivity se ek partial order.
TSan ordering track karne ke liye kaun sa data structure istemal karta hai?
Har thread ka ek vector clock (ek counter per thread), synchronization events par componentwise max se merge kiya jaata hai.
Thread t ke liye TSan ka race check jab thread u ka u-time k par pichla access dekhe?
Race agar (ek write hai) AUR V_t[u] < k, yaani u ki access cover nahi hui jo t u ke baare mein jaanta hai.
-fsanitize=thread compile aur link dono par kyun hona chahiye?
Compile memory/sync accesses ko instrument karta hai; link special TSan runtime substitute karta hai. Dono zaroori hain.
volatile data race kyun fix nahi karta?
Yeh compiler caching rokta hai lekin koi atomicity ya happens-before ordering nahi deta; TSan phir bhi concurrent unsynchronized access dekhta hai.
Kya TSan aur ASan ek binary mein combine ho sakte hain?
Nahi — unke runtimes/shadow memory conflict karte hain; alag binaries build karo.
Kya clean TSan run prove karta hai ki program race-free hai?
Nahi — yeh sirf executed code paths analyze karta hai; report ka na aana ≠ absence ka proof.
TSan ka runtime overhead roughly kitna hai?
Lagbhag 5–15× slower aur 5–10× zyada memory; tests/CI mein istemal karo, production mein nahi.
Classic counter++ race khatam karne wala synchronization, HB terms mein?
Ek mutex: unlock (release) clock ko lock mein push karta hai, baad mein lock (acquire) ise absorb karta hai, toh V_B[A] ≥ k — ordered.
Race conditions ke liye mnemonic?
WORN — Write, Order absent, Reached by both, Not atomic.

Connections

  • Data Race vs Race Condition — data race ek memory concept hai; race condition ek logic timing bug hai; overlapping hain lekin alag.
  • Memory Models — happens-before C++/Java/C11 memory model se aata hai.
  • std::atomic and Memory Ordering — acquire/release woh edges hain jo TSan track karta hai.
  • AddressSanitizer (ASan) — memory errors ke liye sibling sanitizer (mutually exclusive binary).
  • Mutexes and Locks — release/acquire pairs provide karte hain.
  • Vector Clocks — distributed-systems concept jo TSan reuse karta hai.
  • Undefined Behavior in C and C++ — isliye data race itna dangerous hai.

Concept Map

is

requires

requires

requires

makes

motivates

detects

watches

watches

defines

built from

built from

implemented via

uses

Data Race

Undefined Behavior in C/C++

Same memory location

At least one write

Not ordered by happens-before

Non-deterministic bug

Testing unreliable

ThreadSanitizer

Memory accesses

Synchronization events

Happens-before relation

Program order

Release/Acquire

Vector clocks