codacrash: crash analysis

codacrash reads the dump of a program that crashed and tells you why: triage, root cause and exploitability, with no network access by default.

To analyse, you do not need WinDbg, DbgHelp or any other debugger.

Ethical boundary. codacrash is strictly defensive: it detects, classifies and helps remediate. It never generates an exploit, an offensive PoC or attack tooling. Telemetry never derives from a dump's contents.

Install

Download the binary from Download: macOS, Linux x64, Windows x64 and x86. Use the x86 one to capture a 32-bit app, such as Delphi 7. codacrash no longer runs on Windows 7, but it analyzes dumps made there. Check the signature (Supply chain). There is no npm package or brew formula. The Linux x64 package also ships the three codaguard modules (below).

Licence. Analysing one artifact is free. Triaging or correlating two or more artifacts needs a Pro, Verified or Platform licence in the public binary (Vibe does not include runtime). See plans.

Analyse a dump

codacrash analyze crash.dmp                 # auto-detects the format
codacrash analyze core.1234 --format json   # coda-crash/1 envelope (kind: analysis)
codacrash analyze app.hprof                 # Java heap → kind: heap
codacrash analyze hs_err_pid1234.log        # JVM fatal error log → kind: hserr
codacrash analyze snapshot.heapsnapshot     # V8 / Node heap
codacrash analyze core.1234 --rt-report valgrind.txt   # + who allocated and who freed (Valgrind/ASan)

Formats: Minidump (Windows), ELF core (Linux), Mach-O core (macOS), HPROF, hs_err, V8 heap, CPython core, plus Valgrind, ASan and OSS-Fuzz reports. Useful flags: --all-threads, --module-path (folders with the binaries, to name internal functions), --managed (.NET heap via dotnet-dump), --dsc (macOS shared cache).

On a Linux (glibc) core, codacrash reports double free, write after free (naming the affected block) and an overwritten block header. A snapshot of a live process on Linux (gcore, heapdump native) is not treated as a crash: it exits 0 when memory is intact and 10 only when the heap is corrupted.

The report carries os, arch, fault, fault_address, fault_insn, crash_id (8 hex, the crash fingerprint), severity and exploitability on the coda-finding/1 scale (critical|high|medium|low · high|medium|low|unknown), heap_corrupt and stack_smash. The human-readable label appears only in text output; the JSON field always carries the scale value.

Triage and correlation

codacrash triage dumps/*.dmp        # groups by CRASH_ID — how many distinct crashes there are
codacrash correlate core.*          # common denominator across several cores of the same app
codacrash correlate core.* --format json   # coda-crash/1 with kind: correlation

In JSON, triage comes out as coda-crash/1 with kind: triage and correlation with kind: correlation. A file that fails to open or is invalid joins the batch as an error, and the others carry on.

Capture

codacrash doctor                              # can this machine produce a dump we can analyse?
codacrash run app.exe -- --config prod.ini    # runs the program and captures the .dmp on crash (Windows only)
codacrash capture app.exe --out ./dumps       # like run, but capture only (Windows only)
codacrash heapdump native <pid>               # snapshot of a LIVE process: gcore, lldb or MiniDumpWriteDump
codacrash heapdump java <pid>                 # Java heap (HPROF) · also: dotnet, python

doctor checks core_pattern, ulimit -c, disk space and ptrace_scope (Linux) plus each system's capture tool, and exits 1 when something prevents capture.

Bench: deep-run

What the dump does not show (uninitialised reads, the exact instruction of the bad access, who wrote to an address) comes from running the program under an instrumentation tool you already have installed:

codacrash deep-run ./app -- --config prod.ini   # detects the engine: drmemory or memcheck (Valgrind)
CODAFORT_DBI=replay codacrash deep-run ./app    # rr: records, replays and names who wrote to the chunk

memcheck runs on Linux and macOS x86-64; drmemory on Linux, Windows and ARM; replay on Linux with a PMU.

Exit codes

CodeMeaning
0analysis finished with nothing to act on: no crash, a clean snapshot, a heap dump with no anti-pattern; under run, the target exited normally
1doctor: the environment has a failure and capture won't work here
2usage error: bad argument, license token refused, activate on a build without licensing
10something to act on: crash analysed, heap corruption in a snapshot, anti-pattern in a heap dump, memory error under deep-run
11Java deadlock (hs_err)
20invalid or corrupt dump, including input that would crash the analyser
30I/O error: couldn't open the file or write the output or the license
40capture failure (or no deep-run engine on PATH)
41paid capability without a license (a precondition failure, distinct from an invalid dump)

codaguard: runtime detection that stays in the core

codaguard is optional and you load it alongside the program. It records what the dump alone lacks: who allocated the corrupted block and out-of-bounds writes on the block, checked on free. That record stays inside the core. On Linux, load it with LD_PRELOAD; on macOS, build it by hand and load it with DYLD_INSERT_LIBRARIES. SG_DENY_MODULES excludes noisy modules (JVM, CLR, V8, Qt…). When saturated, it counts what it stopped tracking, and the report states the ceiling needed.

LD_PRELOAD=/path/codaguard.so SG_DENY_MODULES=libjvm ./my-app
codacrash analyze core.1234          # the analyser correlates the agent block with the heap

The Linux x64 package ships codaguard.so and two sibling modules, codaguard-audit.so (per-thread call journal, loaded with LD_AUDIT) and codaguard-chaos.so (perturbs scheduling so the race shows up), with the codaguard.md guide. For i386 or macOS, the guide gives the compile line.

Profiling

codacrash measures where the program spends its time and emits coda-profile/1. Collection is Linux-only; ingestion works on any system.

codacrash profile ./server                      # on-CPU
codacrash profile ./server --off-cpu            # off-CPU: where it WAITS (mutex, I/O)
codacrash profile --pid 4242 --sample-secs 10   # attaches to a live process
codacrash analyze perf.data                     # ingests perf.data, collapsed stacks or JFR

What it does not do

It does not patch the binary. The analyser injects nothing into the process (codaguard is optional and you are the one who loads it). It does not use the network: symbols only behind an explicit flag. codacrash shows what happened in the process; whether the source code has the problem is for codafort to answer.