Core dump inspection (inspector:coredump)
May 2, 2026 · View on GitHub
inspector:coredump runs the same memory analysis as inspector:memory
against an ELF core file instead of a live process. It's the
post-mortem counterpart to the online analyzer, and a useful fallback
when live dumping cannot be used.
When to use
- The process has already died: you have a core file (from the
kernel
core_pattern,systemd-coredump, Docker runtime dump, cloud platform artifact, CI sidecar, etc.) but no live PID to attach to. - Live dump fails: if
inspector:memory/inspector:memory:dumpcannot attach (ptrace denied, sandboxed container, unusual glibc / musl layout, ZTS TLS scan failing on an exotic target), taking a core dump with a tool you already have (gcore,kill -SIGSEGV, kernel-level dump) and feeding it toinspector:coredumpis a reliable workaround — it reads ELF notes and memory pages out of the core file instead of going through/proc/<pid>/mem. - Reproducing an incident from an archived dump: core files are
portable. A dump taken in production can be analyzed later on a
dev machine, as long as the matching PHP binary and shared libraries
can be provided (see
--dependency-root).
For live analysis of a still-running process, use
inspector:memory or
inspector:memory:dump. For reuse of an analyzer
output across tools, use the captured-snapshot pipeline described in
memory-report.md and rmem-explore-and-serve.md.
Quick start
# Take a non-destructive core dump of a live process
$ sudo gcore -o /tmp/myapp 12345
# → /tmp/myapp.12345
# Run the memory analyzer against the core file (.rmem is the fastest
# format and is what every analyser reads natively)
$ php ./reli inspector:coredump /tmp/myapp.12345 --pid 12345 \
-f rmem -o snapshot.rmem
# Feed the output into the normal analysis pipeline
$ php ./reli inspector:memory:report snapshot.rmem
$ php ./reli rmem:explore snapshot.rmem
-f sqlite3 is also supported if you want to query the same snapshot
with SQL tools — inspector:memory:report / inspector:memory:compare
accept either format. rmem:explore, rmem:query, rmem:serve,
and rmem:mcp read .rmem only.
The output of inspector:coredump uses the same
MemoryProfilerSettings
as inspector:memory, so every output format (json, sqlite3,
rmem, mysql, postgresql, report, report-json) is supported.
Which downstream tool you can feed depends on the format:
inspector:memory:reportandinspector:memory:compareaccept.rmem(binary) or SQLite (.db/.sqlite).rmem:explore,rmem:query,rmem:serve, andrmem:mcprequire.rmem.
Arguments and options
Required
| Argument / option | Description |
|---|---|
<core-file> | Path to the ELF core file to read. |
--pid, -p | The PID the target process had at the time of the dump. This is used to resolve the binary / shared-library layout that matches the core. |
Core-file specific
| Option | Description |
|---|---|
--dependency-root, -r | Path prefix applied to every binary / shared-library path referenced by the core. Use this when the dump was taken inside a container or chroot and the PHP binary / libs are not at the same absolute path on the analysis host. For example, -r /proc/<pid>/root when the target container is still alive on the same host, or -r /var/lib/docker/.../merged / a locally extracted image root. |
--memory-limit | Set the analyzer's own memory_limit (e.g. 2G). Core files can be large; the analyzer holds data structures proportional to the live heap. |
--no-cache | Disable the binary analysis cache (~/.cache/reli/binary-analysis/). Useful if you are analyzing a dump whose binary differs from one the cache already knows about. |
Target PHP options (same as other inspector commands)
--php-version, --php-regex, --libpthread-regex,
--zts-globals-regex, --php-path, --libpthread-path behave the
same way as in inspector:trace / inspector:memory. Auto-detection
usually works; override only if the binary layout inside the core
differs from what reli can infer.
Output options (same as inspector:memory)
--output-format / -f, --output / -o, --pretty-print,
--db-host, --db-port, --db-name, --db-user, --db-password,
--memory-limit-error-file, --memory-limit-error-line,
--memory-limit-error-max-depth — see
memory-profiler.md for full semantics.
Taking a core dump
Any tool that produces a standard ELF core will work. A few common options:
-
gcore(from gdb) — non-destructive, the target keeps running:sudo gcore -o /tmp/myapp <pid> -
Signal-based — for a crash-repro workflow:
kill -SIGSEGV <pid> # process dies, kernel writes a coreMake sure
ulimit -cand/proc/sys/kernel/core_patternare set so that the core actually lands somewhere you can read. -
systemd-coredump— on systems that route cores to the journal:coredumpctl dump <pid-or-unit> --output=/tmp/core -
Containerized / production artifact — many orchestrators capture a core on OOM-kill or segfault automatically; consult your platform.
Include enough memory in the dump
The analyzer needs to read back PHP heap chunks, the VM stack, and
several read-only segments of the binary for symbol resolution. The
kernel's per-process coredump_filter controls which VMAs end up in
the core. For live captures via gcore, set it to 0x7f to include
private + shared + file-backed + ELF-header pages before dumping:
echo 0x7f | sudo tee /proc/<pid>/coredump_filter
sudo gcore -o /tmp/myapp <pid>
See man 5 core for the full bitmask.
Limitations
- ZTS PHP 8.2+ stripped binaries:
_tsrm_ls_cacheisn't in.dynsym, so reli falls back to a brute-force TLS scan over the thread's TLS block. Post-mortem this needs the saved core to contain the TLS pages of a thread that has actually served a request — an idle worker whose slot is still zero will not validate. The integration test inCoreDumpReaderIntegrationTest.phpuses anauto_prepend_filePID-writer that doesn't keep the worker on a request, so the ZTS variants of that suite stay skipped; in production, take the core while the target is mid-request (e.g. ausleep-tail script under load) and ZTS post-mortem succeeds. - Dependencies must be available: the analyzer resolves symbols
from the PHP binary and linked shared objects. If the analysis host
doesn't have the same files at the paths the core references, use
--dependency-rootto point at a directory that does (e.g. a locally extracted container root filesystem). - Core must contain the relevant memory pages. A dump taken with
a restrictive
coredump_filtermay be missing pages the analyzer needs; it will report an error or produce a partial result.
See also
inspector:memory— the live-process equivalent. Output format and downstream pipeline are shared.inspector:memory:dump— reli's own compact.rdumpdump format for offline analysis; prefer it overgcore + inspector:coredumpwhen the target is still alive and reli can attach.inspector:memory:report— generate an automated analysis report from the output.rmem:explore— interactive TUI over the.rmemoutput.gcorecomparison — internals note on trade-offs between reli's native dump and ELF core files.