Debugging Deadlocks
Step 1: Get a Thread Dump
Java: jstack <pid> or send SIGQUIT. Go: Send SIGQUIT or use pprof. Python: faulthandler module. The dump shows every thread, its state, and what lock it waits for.
Step 2: Find Blocked Threads
Look for threads in BLOCKED state. Each blocked thread shows which lock it wants and who holds it. Trace the chain: A waits for B, B waits for C, C waits for A. That is your cycle.
Step 3: Identify the Code Paths
Stack traces show where each thread acquired its locks and where it is waiting. Two threads holding locks in opposite order? That is your bug. Find where the ordering diverges.
Prevention for Next Time
Lock ordering: Document and enforce a global order for all locks. Timeout: Use tryLock with timeout, log and retry on failure. Testing: Stress test concurrent code paths. Static analysis: Tools can detect potential lock order inversions.