agentsclimarketplace

Deadlock analysis

Skill Amey-Thakur/AI-SKILLS/skills/debugging/deadlock-analysis

Find why threads are stuck forever by dumping their state and building the wait-for graph that reveals the lock cycle. Use when a program hangs with no progress and no crash, or throughput drops to zero while CPU sits idle.From its SKILL.md

Install
npx -y skills add Amey-Thakur/AI-SKILLS --skill deadlock-analysis

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 23 days oldThe repository was created 23 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

3.0 KB, 684 tokens by cl100k_base, as published. Nobody here has run it

Deadlock analysis

A deadlock is a cycle of waiting: thread A holds lock 1 and wants lock 2 while thread B holds lock 2 and wants lock 1, and neither will ever move. The process is not crashed, it is frozen, which fools you into looking for a slow operation instead of a stuck one. The cycle is always visible in a thread dump if you know how to read the waits.

Method

  1. Confirm it is a deadlock, not slowness. Idle CPU with zero progress for minutes points at blocking, not computation. A busy CPU spinning forever is a livelock or infinite loop, a different bug. Check that threads are parked in a wait state, not running hot.
  2. Capture a thread dump at the moment of the hang. jstack <pid> or kill -3 on the JVM, py-spy dump --pid for Python, dlv or SIGQUIT for Go (which prints all goroutine stacks), gdb -p <pid> then thread apply all bt for native. Take two dumps a few seconds apart: if the stacks are identical, nothing is moving.
  3. Read who holds what and who waits for what. A good dump names it directly: the JVM prints "Found one Java-level deadlock" with the lock ids, "waiting to lock <0x...>" versus "locked <0x...>". For each blocked thread, write down the lock it holds and the lock it wants.
  4. Draw the wait-for graph and find the cycle. Nodes are threads, an edge runs from a thread to the thread holding the lock it waits on. A cycle in that graph is the deadlock, and the locks on the cycle are the ones acquired in conflicting order. Two locks is the common case; the graph scales to more.
  5. Fix with a global lock ordering. Pick a total order for the locks on the cycle (by address, by name, by a fixed rank) and make every code path acquire them in that order. If ordering is impractical, use a single coarser lock, a tryLock with timeout and backoff, or lock-free structures. Consistent order breaks every cycle by construction.
  6. Prove it under contention. Run the path that hung under many threads for an extended loop. A deadlock that reproduced in minutes should now run indefinitely. Static tools help catch regressions: -Xlint, jcstress, or Clang's -Wthread-safety annotations flag out-of-order acquisition.

Signals

  • Do two thread dumps taken seconds apart show identical, parked stacks?
  • Can you trace a closed cycle through the wait-for graph?
  • Does every path that touches those locks now take them in one fixed order?

Boundaries

This covers mutual-exclusion deadlocks between threads in one process. Distributed deadlocks across services, database lock waits, and connection- pool exhaustion wear the same mask but resolve with transaction timeouts, lock ordering at the database, or pool sizing, not with a thread dump.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,782. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.