deloxide 1.1.0

Deloxide scrubs your threads clean by detecting deadlocks in real time—keeping your system smooth, safe, and corrosion-free. 🦀🧼🔒
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Troubleshooting by Symptom

Start by deciding whether the expected outcome is an active [`WaitForGraph`](https://docs.rs/deloxide/1.1.0/deloxide/enum.DeadlockSource.html#variant.WaitForGraph) callback or a potential [`LockOrderViolation`](https://docs.rs/deloxide/1.1.0/deloxide/enum.DeadlockSource.html#variant.LockOrderViolation). A hang with neither can be contention, a missed notification, I/O, starvation, or an untracked synchronization path.

| Symptom | Likely cause | Confirming check | Next action |
| --- | --- | --- | --- |
| No callback fires | No active cycle exists, a raw/third-party lock is outside Deloxide, or the test never reached the contested acquisition. | Add barriers and record lock attempts; capture stacks; verify every relevant primitive is a Deloxide wrapper. | Review [non-cycle hangs]patterns.md#hangs-that-are-not-lock-cycles and make the callback explicit with [`Deloxide::callback`]https://docs.rs/deloxide/1.1.0/deloxide/struct.Deloxide.html#method.callback. |
| Callback fires but no log exists | Logging feature/path is absent, disabled, or unwritable; callback delivery does not require a log. | Check the `logging-and-visualization` feature and the configured [`with_log`]https://docs.rs/deloxide/1.1.0/deloxide/struct.Deloxide.html#method.with_log path. | Preserve the callback payload now; enable a writable timestamped log path for the next run. |
| Visualization opens an empty or stale log | The wrong file was selected or buffered entries were not the active log when it was opened. | Confirm the configured log path and call [`showcase_this`]https://docs.rs/deloxide/1.1.0/deloxide/fn.showcase_this.html, which flushes the active log first. | Use `showcase_this()` for the current run, or [`showcase`]https://docs.rs/deloxide/1.1.0/deloxide/fn.showcase.html with the exact completed file. |
| Only lock-order findings appear | The order graph saw an inversion, but the tested schedule has not produced concurrent blocking. | `source` is `LockOrderViolation` and `lock_order_cycle` is `Some(...)`; there is no active `WaitForGraph`. | Follow [lock-order triage]lock-order.md#triage-rules; reproduce under [stress]stress-testing.md without calling it an outage yet. |
| RwLock report includes the same thread | A thread held a read guard and requested a write guard on that same RwLock. | Map the report's `(thread, lock)` pair and inspect guard lifetimes around [`RwLock::write`]https://docs.rs/deloxide/1.1.0/deloxide/struct.RwLock.html#method.write. | Release the read guard and revalidate before writing; see [read-to-write self-deadlock]patterns.md#rwlock-read-to-write-self-deadlock. |
| Condvar test hangs without a cycle | A missed notification, false predicate, or external wait is blocking progress rather than tracked lock ownership. | Log predicate changes, wait registration, and notification order; use a parent watchdog. | Use the predicate loop and notifier protocol in [Condvar wait and mutex reacquisition]patterns.md#condvar-wait-and-mutex-reacquisition. |
| Benchmark overhead is higher than expected | Optional logging, lock-order checking, or stress mode changed the measured feature set/workload. | Print Cargo features and configuration; compare the same scenario with [`no_lock_order_checking`]https://docs.rs/deloxide/1.1.0/deloxide/struct.Deloxide.html#method.no_lock_order_checking, no logging, and no stress. | Benchmark the exact production feature set; keep [stress]stress-testing.md out of production measurements. |
| Second initialization appears ignored | Rust initialization is process-wide; the first callback/configuration remains installed. C `deloxide_init` also returns `1` once already initialized. | Locate the first [`Deloxide::start`]https://docs.rs/deloxide/1.1.0/deloxide/struct.Deloxide.html#method.start or C initialization call in the process. | Configure once before workers start; use an isolated process for configurations that must differ. |
| C thread relationships are missing | Worker threads were created without the tracked thread wrapper/registration, or were not registered before using tracked locks. | Check that each pthread uses `DEFINE_TRACKED_THREAD` and `CREATE_TRACKED_THREAD`, or calls `deloxide_register_thread_spawn`/`deloxide_register_thread_exit`. | Follow the [C guide]../c-guide.md and register the parent-child relationship before lock activity. |

When escalating an issue, attach `source`, the full `DeadlockInfo` payload, the test command and feature set, relevant thread stacks, and the exact log file if enabled. That evidence lets another engineer distinguish an active cycle from a potential ordering pattern without reproducing the entire production workload first.