Provides expertise for analyzing DWARF debug files and understanding the DWARF debug format/standard (v3-v5). Triggers when understanding DWARF information, interacting with DWARF files, answering DWARF-related questions, or working with code that parses DWARF data.
Expertise for DWARF debug info: parsing and searching it, verifying its integrity, answering questions about the standard, and writing code that consumes it. Out of scope: runtime debugging (use gdb/lldb), reverse engineering beyond the DWARF sections (use Ghidra/IDA), and compiler-specific DWARF generation bugs.
When precision matters, look standard details up instead of answering from memory:
llvm/lib/DebugInfo/DWARF/ is a reliable reference implementation:
DWARFDie.cpp (DIE and attribute access), DWARFUnit.cpp (compilation units),
DWARFDebugLine.cpp (line tables), DWARFVerifier.cpp (validation).Prefer dwarfdump over readelf for DWARF-specific work. Two implementations
exist — libdwarf's dwarfdump and LLVM's llvm-dwarfdump — with different
options, and a bare dwarfdump command may be either: check dwarfdump --version
first. The options below are LLVM's.
On macOS, linked Mach-O executables do not carry DWARF: it stays in the .o
files until dsymutil collects it into a .dSYM bundle. Point dwarfdump at
the dSYM (or the object files), not the executable. pyelftools is ELF-only —
for Mach-O scripted work, stay with the LLVM tools.
--all: dump every DWARF section; --debug-info, --debug-line, etc. dump one--show-children [--recurse-depth=<n>]: include child DIEs when printing
selected entries — parameters, locals, and struct members are children of
function and type DIEs--show-parents [--parent-recurse-depth=<n>]: include parent DIEs--show-form: print attribute form types, for when encoding details matter--find=<name>: exact-name lookup via the accelerator tables — fast but not
exhaustive; fall back to --name when it misses--name=<pattern> [--ignore-case] [--regex]: exhaustive DIE-name search--lookup=<address>: find the DIE covering an address--verbose: print low-level encoding detailEscalate through these strategies as the query grows more complex:
--find, then --name; --lookup for addresses.float *): dump and
filter. grep -B pulls in the header line carrying each DIE's offset:
llvm-dwarfdump file | grep -B 5 "float \*" | grep DW_TAG_formal_parameter,
then print each DIE at its offset with --debug-info=<offset> --show-children
(--lookup takes a program address, not a DIE offset).pyelftools instead.llvm-dwarfdump --verify <binary>: structural checks (unit chains, DIE
relationships, address ranges). --error-display=<quiet|summary|details|full>
controls detail; --verify-json=<path> writes a machine-readable error
summary; --quiet for exit-code-only checks.llvm-dwarfdump --statistics <binary>: debug-info quality metrics as JSON —
compare across compiler versions or optimization levels to catch regressions.Verify after producing DWARF (compilers, binary rewriters), when a debugger misbehaves on a binary, and when developing DWARF tooling against known-good files.
When a current-generation compiler emitted an old DWARF version, the build
explicitly passed -gdwarf-N — modern gcc and clang default to v4/v5, so check
the build system rather than assuming a toolchain default. GCC embeds its flags
in DW_AT_producer, so the pin is often readable right there; clang's producer
string carries no flags. Old versions remain common in the wild and read the
same way apart from surface forms: in v2 output, member offsets appear as
location expressions (DW_OP_plus_uconst) and linkage names as
DW_AT_MIPS_linkage_name.
For general ELF structure, or when dwarfdump is unavailable:
--debug-dump=<section>: dump a DWARF section (info, line, ...)--dwarf-depth=<n> / --dwarf-start=<n>: limit DIE depth / start offsetPrefer an existing library over parsing by hand:
| Library | Language | Notes |
|---------|----------|-------|
| libdwarf | C/C++ | github.com/davea42/libdwarf-code — low-level; used to implement dwarfdump |
| pyelftools | Python | github.com/eliben/pyelftools — also parses ELF in general |
| gimli | Rust | github.com/gimli-rs/gimli — pair with object to load container files |
| debug/dwarf | Go | standard library |
| LibObjectFile | .NET | github.com/xoofx/LibObjectFile — also handles ELF/PE object files |
Default to Python with pyelftools for one-off scripts unless the task dictates
otherwise.
DWARF-specific pitfalls to handle — and to check for when reviewing DWARF code:
DW_AT_name, DW_AT_type, ranges, etc.DW_AT_abstract_origin (inlined instances) or DW_AT_specification
(out-of-line definitions) — resolve the chain before concluding data is absent.DW_TAG_const_type,
DW_TAG_pointer_type, ...) wrap the underlying type; walk DW_AT_type links to
reach the base type.npx skills add trailofbits/dwarf-expert下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Delegate coding tasks to Codex, Claude Code, or Pi agents via background process. Use when: (1) building/creating new features or apps, (2) reviewing PRs (spawn in temp dir), (3) refactoring large codebases, (4) iterative coding that needs file exploration. NOT for: simple one-liner fixes (just edit), reading code (use read tool), thread-bound ACP harness requests in chat (for example spawn/run Codex or Claude Code in a Discord thread; use sessions_spawn with runtime:"acp"), or any work in ~/clawd workspace (never spawn agents here). Claude Code: use --print --permission-mode bypassPermissions (no PTY). Codex/Pi/OpenCode: pty:true required.
Gemini CLI for one-shot Q&A, summaries, and generation.
Query Google Places API (New) via the goplaces CLI for text search, place details, resolve, and reviews. Use for human-friendly place lookup or JSON output for scripts.
Remote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.
Send WhatsApp messages to other people or search/sync WhatsApp history via the wacli CLI (not for normal user chats).
Category:developer