PromptForge Academy
debuggingconcurrencydeadlocksexisting-projects

Debugging Deadlocks and Race Conditions with AI

Concurrency bugs don't reproduce on demand and rarely show up in a single stack trace. A structured approach to feeding thread dumps and timing evidence to AI instead of guessing.

A null-reference exception hands you a stack trace pointing at the exact line. A deadlock hands you a frozen application, no exception, and — if you're lucky — a thread dump full of threads waiting on each other. Concurrency bugs are where "paste the error and ask what's wrong" breaks down completely, because there is no single error; there's a timing relationship between multiple threads that has to be reconstructed.

Why concurrency bugs need a different approach

  • They often don't reproduce reliably — the bug depends on exact timing/interleaving that varies run to run.
  • A single stack trace shows one thread's state, not the relationship between threads that caused the deadlock.
  • The fix that "looks right" (adding a lock) can introduce a new deadlock elsewhere if lock ordering isn't reasoned through explicitly.
The evidence you paste determines whether the analysis is real or guesswork

Pasting one stack trace and asking "why did this deadlock" invites a plausible-sounding guess. Pasting the full thread dump — every thread's state and what it's waiting on — is what actually lets the model (or a human) reconstruct the cycle.

The evidence to gather before asking

EvidenceWhy it matters
Full thread dump at the moment of the hangShows every thread's state (BLOCKED, WAITING) and exactly which lock/monitor it's waiting on
The lock acquisition order in the relevant code pathsA deadlock is fundamentally two threads acquiring the same locks in opposite order — this is the root cause, not the symptom
Whether the hang is 100% reproducible or intermittentIntermittent points to a genuine race; consistent points to a structural lock-ordering bug that will always trigger under a specific code path
Recent changes to the affected code pathsConcurrency bugs are frequently introduced by a change that looked safe in isolation but altered lock ordering or added a new shared-state access

Worked example

Prompt: reconstruct a deadlock from a thread dump
Existing Project Advanced — Debugging module
Context: Application hung under load. Here is the full thread dump at the time of the hang: [paste complete thread dump, not a single thread]

Here is the code for the two classes involved (OrderProcessor, InventoryLock): [paste code]

Task: Identify the deadlock cycle — which threads are waiting on which locks, and in what order each thread acquired them.

Constraints:
- Show the exact cycle: Thread A holds lock X, waits for lock Y; Thread B holds lock Y, waits for lock X.
- Base this only on the thread dump and code provided — do not speculate about threads or locks not shown in the evidence.
- Propose a fix that establishes a single consistent lock acquisition order across both code paths, not just a workaround for this one occurrence.

Output format: 1) the deadlock cycle explained thread-by-thread, 2) the specific lines where ordering diverges, 3) the fix.

Race conditions without a deadlock

Not every concurrency bug hangs — a race condition can silently produce wrong data with no crash at all, which is worse to detect. For these, the useful prompt pattern is the same one used for thread-safety review generally: walk through what happens if two threads execute the suspect code path at the exact same time, step by step, rather than asking a yes/no "is this thread-safe."

Verify the fix under the same conditions that exposed the bug

A proposed fix for a timing-dependent bug should be verified with a stress test that exercises concurrent access, not just a single-threaded unit test passing. The absence of a crash in one run proves very little for concurrency bugs.

This is one of the harder debugging categories precisely because it resists the "paste the error, get the fix" pattern that works for most bugs — the Debugging module treats it separately from the general scientific-debugging method, with its own evidence checklist before any fix is proposed.