core-dumps
Use when loading core files in GDB or LLDB, enabling core dump generation via ulimit or coredumpctl, mapping symbols with debuginfod, or extracting backtraces from production segfaults.
Install
npx skills add https://github.com/OutlineDriven/outline-driven-development/tree/main/.devin/skills/core-dumps
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install outlinedriven-outline-driven-development@llmmart
git clone https://github.com/OutlineDriven/outline-driven-development.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole outlinedriven/outline-driven-development collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Core dumps
Contract
| Field | Bound contract |
|---|---|
| Trigger | A program crashed and left a core file, cores need enabling on Linux or macOS, symbols are missing for a production binary, or a backtrace is needed without re-running the program. |
| Authority | Read-only. Emits analysis and commands for the operator to run on the target; no file writes, no rollback needed. No remote mutation. |
| Side effect | Diagnostic commands and a crash verdict in chat. Nothing is written. |
| Done | The crashing frame, signal, and faulting access are named, or the missing prerequisite (symbols, core file, build ID) is stated. |
Inputs
- Core file or crash record (required): a
corefile, acoredumpctlentry, or a/cores/core.<PID>file on macOS. - Binary (required): the exact executable that crashed, ideally the unstripped build.
- Build ID or debug package access (optional): needed when the binary is stripped.
Procedure
Enable cores on Linux.
ulimit -c unlimited # this shell only ulimit -c # confirm cat /proc/self/limits # per-process viewPersist for all users in
/etc/security/limits.conf:* soft core unlimited * hard core unlimitedControl where cores land:
cat /proc/sys/kernel/core_pattern sudo sysctl -w kernel.core_pattern=/tmp/core-%e-%p-%t%eis the executable name,%pthe PID,%tthe timestamp. If the pattern starts with|, a pipe handler such as systemd-coredump or apport owns core collection; use step 2 instead of looking for files. Done when:ulimit -creports unlimited and the pattern names a writable path or a known pipe handler.Use coredumpctl when systemd collects cores.
coredumpctl list # recorded crashes coredumpctl list myapp # crashes of one executable coredumpctl info # details of the latest coredumpctl gdb # open the latest in GDB coredumpctl gdb 12345 # open a specific PID coredumpctl dump 12345 -o myapp.core # export the core fileCores live in
/var/lib/systemd/coredump/. Done when: the crash is listed andcoredumpctl gdbopens it.Enable cores on macOS.
ulimit -c unlimited ls /cores/ # cores land as /cores/core.<PID>Crash Reporter also writes
.crashand.ipslogs under~/Library/Logs/DiagnosticReports/. Done when: a core or crash report exists for the failed run.Analyze the core with GDB.
gdb ./prog core.12345 gdb ./prog-with-symbols core.12345 # use the unstripped build when stripped(gdb) bt # call stack (gdb) bt full # stack plus locals (gdb) info registers # CPU state at the fault (gdb) frame 2 # jump to a frame (gdb) info locals (gdb) print ptr (gdb) thread apply all bt full # every thread (gdb) print $_siginfo # signal details on LinuxDone when: the crashing frame, the signal, and the faulting address are named.
Analyze the core with LLDB.
lldb ./prog -c core.12345(lldb) target create ./prog --core core.12345 # equivalent, inside LLDB (lldb) bt (lldb) thread backtrace all (lldb) frame select 2 (lldb) frame variable (lldb) register readDone when: the crashing frame and faulting access are named.
Resolve missing symbols with debuginfod. debuginfod maps build IDs to DWARF data over HTTP.
export DEBUGINFOD_URLS="https://debuginfod.ubuntu.com https://debuginfod.elfutils.org" gdb ./prog core # GDB fetches symbols automatically debuginfod-find debuginfo <build-id> debuginfod-find source <build-id> /path/to/file.cDone when: symbols resolve, or the build ID is recorded for manual lookup.
Resolve symbols manually when debuginfod cannot help.
readelf -n ./prog | grep 'Build ID'Install the matching debug package (
prog-dbgsymorprog-dbgon Debian,prog-debuginfoon Fedora/RHEL), then point GDB at it:(gdb) set debug-file-directory /usr/lib/debugDone when: GDB loads the matching debug file and
btshows function names.Strip for distribution while keeping symbols. Build with symbols, split them out, ship the stripped binary.
objcopy --only-keep-debug prog prog.debug objcopy --strip-debug prog prog.stripped objcopy --add-gnu-debuglink=prog.debug prog.strippedeu-strip -f prog.debug progdoes the split in one step. Keepprog.debugin a symbol store indexed by build ID. Done when: the stripped binary resolves symbols through its.gnu_debuglink.Triage without an interactive session.
gdb -batch -ex 'bt full' -ex 'thread apply all bt full' ./prog core 2>&1 | tee crash.txt gdb -batch -ex 'info registers' ./prog core file core # signal, PID, architectureDone when:
crash.txtholds the backtrace and register state.
For the core-pattern token table, the public debuginfod server list, and the full command set, see references/cheatsheet.md.
Failure and recovery
- No core file exists: check
ulimit -c, thekernel.core_patterntarget, and whether a pipe handler intercepted the dump. Re-run the failing program after fixing the limit. coredumpctl listis empty: cores may go to files instead; checkcore_patternand the filesystem it names.- GDB reports
no debugging symbols found: fetch them through debuginfod (step 6) or install the debug package (step 7). A stripped binary still yields addresses and a usablebtskeleton. - The core does not match the binary: GDB warns about mismatched build IDs. Locate the exact binary by build ID; do not trust a same-named rebuild.
- Corrupted stack:
btstops early or shows??frames. Readinfo registersand walk the stack pointer manually withx/.
Output
A crash verdict naming the signal, the faulting frame and address, and the register state, plus the symbol-resolution path used (unstripped binary, debug package, or debuginfod).
Files (outline-driven-development)
-
agents
-
openai.yaml 292 B
interface: display_name: "Core Dumps" short_description: "Use when loading core files in GDB or LLDB, enabling core dump generation via ulimit or coredumpctl, mapping symbols with debuginfod, or extracting backtraces from production segfaults." policy: allow_implicit_invocation: false
-
-
references
-
cheatsheet.md 5.2 KB
# Core dump cheatsheet Sources: `core(5)` man page, the GDB manual's core-file section, and the systemd `coredumpctl` documentation. ## Enable core dumps ```bash # Per-session ulimit -c unlimited # Per-process, in code #include <sys/resource.h> struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY }; setrlimit(RLIMIT_CORE, &rl); # Persistent, all users: /etc/security/limits.conf * soft core unlimited * hard core unlimited # Check ulimit -c cat /proc/self/limits ``` ## Core pattern configuration ```bash cat /proc/sys/kernel/core_pattern # Temporary sudo sysctl -w kernel.core_pattern=/tmp/core-%e-%p-%t # Persistent: /etc/sysctl.d/99-core.conf kernel.core_pattern=/tmp/core-%e-%p-%t kernel.core_uses_pid=1 sudo sysctl -p /etc/sysctl.d/99-core.conf ``` A pattern starting with `|` pipes the core to a handler instead of writing a file: `|/usr/lib/systemd/systemd-coredump ...` for systemd, `|/usr/share/apport/apport ...` for Ubuntu apport. Core pattern tokens: | Token | Meaning | |---|---| | `%e` | Executable filename, no path | | `%E` | Executable path, `/` replaced by `!` | | `%p` | PID in the process's PID namespace | | `%P` | PID in the initial PID namespace | | `%u` | UID | | `%g` | GID | | `%s` | Signal number | | `%t` | Unix timestamp | | `%h` | Hostname | | `%c` | Core file size soft limit | ## systemd / coredumpctl ```bash coredumpctl list # all recorded crashes coredumpctl list myapp # one executable coredumpctl info # latest crash details coredumpctl info 12345 # specific PID coredumpctl gdb # latest crash in GDB coredumpctl gdb myapp # latest crash of one executable coredumpctl dump 12345 -o /tmp/myapp.core # export the core ls /var/lib/systemd/coredump/ # storage location ``` To stop systemd from collecting cores, set `Storage=none` under `[Coredump]` in `/etc/systemd/coredump.conf`. ## Analyze with GDB ```bash gdb ./prog /tmp/core-prog-12345-1700000000 gdb ./prog-with-debug-symbols /tmp/core # stripped binary: use the debug build ``` ```gdb (gdb) bt # call stack (gdb) bt full # stack plus locals (gdb) info registers # CPU registers at the crash (gdb) frame 2 (gdb) info locals (gdb) print ptr (gdb) x/10wx $rsp # memory near the stack pointer (gdb) thread apply all bt full # every thread (gdb) info signals # signal handling table (gdb) print $_siginfo # signal details on Linux (gdb) set print pretty on (gdb) print *my_struct_ptr (gdb) info symbol 0x7fff12345678 # what an address resolves to (gdb) x/s 0x7fff12345678 # read it as a string ``` A `SIGABRT` backtrace usually means an assertion or `abort()`; walk up the frames to the check that fired. ## Analyze with LLDB ```bash lldb ./prog -c core.12345 ``` ```lldb (lldb) target create ./prog --core core.12345 (lldb) bt (lldb) thread backtrace all (lldb) frame select 2 (lldb) frame variable (lldb) register read (lldb) memory read -s8 -fx -c10 0x7fff0000 (lldb) thread info # stop reason and signal ``` ## debuginfod for symbols ```bash sudo apt install debuginfod # Debian/Ubuntu sudo dnf install elfutils-debuginfod-client # Fedora/RHEL export DEBUGINFOD_URLS="https://debuginfod.ubuntu.com https://debuginfod.elfutils.org" gdb ./stripped-prog core # GDB fetches automatically when the variable is set readelf -n ./prog | grep 'Build ID' debuginfod-find debuginfo <build-id-hex> debuginfod-find source <build-id-hex> /path/to/source.c DEBUGINFOD_PROGRESS=1 gdb ./prog core # show fetch progress ``` Public debuginfod servers: | Distro | URL | |---|---| | Ubuntu | `https://debuginfod.ubuntu.com` | | Fedora | `https://debuginfod.fedoraproject.org` | | Debian | `https://debuginfod.debian.net` | | Arch Linux | `https://debuginfod.archlinux.org` | | openSUSE | `https://debuginfod.opensuse.org` | | Generic | `https://debuginfod.elfutils.org` | ## Non-interactive triage ```bash gdb -batch \ -ex 'set print thread-events off' \ -ex 'thread apply all bt full' \ -ex 'info registers' \ -ex 'quit' \ ./prog core 2>&1 | tee crash_report.txt gdb -batch -ex 'bt full' -ex 'info registers' ./prog core eu-readelf -n core | grep -i signal # signal from core notes file core # signal, PID, architecture ``` ## macOS cores ```bash ulimit -c unlimited ls /cores/ # /cores/core.<PID> lldb ./prog -c /cores/core.12345 # Crash Reporter logs ls ~/Library/Logs/DiagnosticReports/ ls /Library/Logs/DiagnosticReports/ ``` ## Stripping and symbol management ```bash # Keep an unstripped copy indexed by build ID BUILD_ID=$(readelf -n prog | grep 'Build ID' | awk '{print $3}') mkdir -p /srv/symbols/${BUILD_ID:0:2} cp prog /srv/symbols/${BUILD_ID:0:2}/${BUILD_ID:2}.debug # Split and strip objcopy --only-keep-debug prog prog.debug strip --strip-debug prog objcopy --add-gnu-debuglink=prog.debug prog # Debug packages sudo apt install myapp-dbgsym # Debian/Ubuntu; or myapp-dbg sudo dnf install myapp-debuginfo # Fedora/RHEL # Tell GDB where debug files live (gdb) set debug-file-directory /usr/lib/debug:/srv/symbols ```
-
-
SKILL.md 6.5 KB
--- name: core-dumps description: 'Use when loading core files in GDB or LLDB, enabling core dump generation via ulimit or coredumpctl, mapping symbols with debuginfod, or extracting backtraces from production segfaults.' disable-model-invocation: true --- # Core dumps ## Contract | Field | Bound contract | |---|---| | Trigger | A program crashed and left a core file, cores need enabling on Linux or macOS, symbols are missing for a production binary, or a backtrace is needed without re-running the program. | | Authority | Read-only. Emits analysis and commands for the operator to run on the target; no file writes, no rollback needed. No remote mutation. | | Side effect | Diagnostic commands and a crash verdict in chat. Nothing is written. | | Done | The crashing frame, signal, and faulting access are named, or the missing prerequisite (symbols, core file, build ID) is stated. | ## Inputs 1. Core file or crash record (required): a `core` file, a `coredumpctl` entry, or a `/cores/core.<PID>` file on macOS. 2. Binary (required): the exact executable that crashed, ideally the unstripped build. 3. Build ID or debug package access (optional): needed when the binary is stripped. ## Procedure 1. Enable cores on Linux. ```bash ulimit -c unlimited # this shell only ulimit -c # confirm cat /proc/self/limits # per-process view ``` Persist for all users in `/etc/security/limits.conf`: ```text * soft core unlimited * hard core unlimited ``` Control where cores land: ```bash cat /proc/sys/kernel/core_pattern sudo sysctl -w kernel.core_pattern=/tmp/core-%e-%p-%t ``` `%e` is the executable name, `%p` the PID, `%t` the timestamp. If the pattern starts with `|`, a pipe handler such as systemd-coredump or apport owns core collection; use step 2 instead of looking for files. Done when: `ulimit -c` reports unlimited and the pattern names a writable path or a known pipe handler. 2. Use coredumpctl when systemd collects cores. ```bash coredumpctl list # recorded crashes coredumpctl list myapp # crashes of one executable coredumpctl info # details of the latest coredumpctl gdb # open the latest in GDB coredumpctl gdb 12345 # open a specific PID coredumpctl dump 12345 -o myapp.core # export the core file ``` Cores live in `/var/lib/systemd/coredump/`. Done when: the crash is listed and `coredumpctl gdb` opens it. 3. Enable cores on macOS. ```bash ulimit -c unlimited ls /cores/ # cores land as /cores/core.<PID> ``` Crash Reporter also writes `.crash` and `.ips` logs under `~/Library/Logs/DiagnosticReports/`. Done when: a core or crash report exists for the failed run. 4. Analyze the core with GDB. ```bash gdb ./prog core.12345 gdb ./prog-with-symbols core.12345 # use the unstripped build when stripped ``` ```gdb (gdb) bt # call stack (gdb) bt full # stack plus locals (gdb) info registers # CPU state at the fault (gdb) frame 2 # jump to a frame (gdb) info locals (gdb) print ptr (gdb) thread apply all bt full # every thread (gdb) print $_siginfo # signal details on Linux ``` Done when: the crashing frame, the signal, and the faulting address are named. 5. Analyze the core with LLDB. ```bash lldb ./prog -c core.12345 ``` ```lldb (lldb) target create ./prog --core core.12345 # equivalent, inside LLDB (lldb) bt (lldb) thread backtrace all (lldb) frame select 2 (lldb) frame variable (lldb) register read ``` Done when: the crashing frame and faulting access are named. 6. Resolve missing symbols with debuginfod. debuginfod maps build IDs to DWARF data over HTTP. ```bash export DEBUGINFOD_URLS="https://debuginfod.ubuntu.com https://debuginfod.elfutils.org" gdb ./prog core # GDB fetches symbols automatically debuginfod-find debuginfo <build-id> debuginfod-find source <build-id> /path/to/file.c ``` Done when: symbols resolve, or the build ID is recorded for manual lookup. 7. Resolve symbols manually when debuginfod cannot help. ```bash readelf -n ./prog | grep 'Build ID' ``` Install the matching debug package (`prog-dbgsym` or `prog-dbg` on Debian, `prog-debuginfo` on Fedora/RHEL), then point GDB at it: ```gdb (gdb) set debug-file-directory /usr/lib/debug ``` Done when: GDB loads the matching debug file and `bt` shows function names. 8. Strip for distribution while keeping symbols. Build with symbols, split them out, ship the stripped binary. ```bash objcopy --only-keep-debug prog prog.debug objcopy --strip-debug prog prog.stripped objcopy --add-gnu-debuglink=prog.debug prog.stripped ``` `eu-strip -f prog.debug prog` does the split in one step. Keep `prog.debug` in a symbol store indexed by build ID. Done when: the stripped binary resolves symbols through its `.gnu_debuglink`. 9. Triage without an interactive session. ```bash gdb -batch -ex 'bt full' -ex 'thread apply all bt full' ./prog core 2>&1 | tee crash.txt gdb -batch -ex 'info registers' ./prog core file core # signal, PID, architecture ``` Done when: `crash.txt` holds the backtrace and register state. For the core-pattern token table, the public debuginfod server list, and the full command set, see `references/cheatsheet.md`. ## Failure and recovery - No core file exists: check `ulimit -c`, the `kernel.core_pattern` target, and whether a pipe handler intercepted the dump. Re-run the failing program after fixing the limit. - `coredumpctl list` is empty: cores may go to files instead; check `core_pattern` and the filesystem it names. - GDB reports `no debugging symbols found`: fetch them through debuginfod (step 6) or install the debug package (step 7). A stripped binary still yields addresses and a usable `bt` skeleton. - The core does not match the binary: GDB warns about mismatched build IDs. Locate the exact binary by build ID; do not trust a same-named rebuild. - Corrupted stack: `bt` stops early or shows `??` frames. Read `info registers` and walk the stack pointer manually with `x/`. ## Output A crash verdict naming the signal, the faulting frame and address, and the register state, plus the symbol-resolution path used (unstripped binary, debug package, or debuginfod).
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.