Debugging Tools
CHERI debugging tools expose capability addresses, bounds, permissions, tags, and faults so developers can diagnose authority errors directly.
A conventional crash may report only a segmentation fault at an address. A CHERI fault can provide more useful context: which capability register was used, whether its tag was valid, which permission was missing, and how the access related to its bounds.
The debugger and operating system must understand capability state to make that information useful.
Read the fault first
When a capability exception occurs, capture the complete diagnostic before changing code. Useful fields may include:
- exception or fault type
- program counter
- capability register involved
- attempted address and access size
- base and top bounds
- permissions
- tag and sealing state
- process, thread, or compartment identity
- stack trace
Terminology and formatting differ across CheriBSD, CHERIoT, Linux, Morello, and CHERI-RISC-V tools.
GDB and LLDB
CHERI-aware debugger builds can display capability registers and decode their metadata. They support familiar operations such as breakpoints, stack traces, source stepping, memory inspection, and core-file analysis while adding capability-aware register views.
Use the debugger built for the same target and application binary interface (ABI) as the program. A stock host GDB may see a large value but not interpret its tag, bounds, permissions, or architecture-specific registers correctly.
cheribuild can build supported CHERI GDB targets for host-side or guest-side debugging. CHERI Alliance and CTSRD-CHERI repositories also publish target-specific debugger work.
QEMU diagnostics
QEMU is useful for repeatable capability faults in full operating-system tests. It can support:
- remote debugger connections
- instruction and exception logging
- deterministic test inputs
- continuous-integration reproduction without hardware
- comparison with architecture tests
Large instruction traces can hide the relevant event. Reducing the failing input first makes it practical to trace the short interval around the fault.
CheriBSD tools
CheriBSD integrates capability state into operating-system facilities such as:
- signal and exception reports
- core dumps
- process tracing
- capability-aware debuggers
- binary inspection tools
- kernel diagnostics
The versioned CheriBSD Getting Started guides document the supported debugger and remote-access flow for each release.
CHERIoT debugging
CHERIoT development builds include features intended to make compartment and capability failures visible. The simulator can report traps, while platform headers and error handlers can turn unexpected faults into useful test failures.
The CHERIoT toolchain also includes auditing support that inspects firmware images and their compartment structure. Static audit information complements runtime debugging by showing declared components, imports, exports, and authority relationships.
Use the CHERIoT Programmer’s Guide sections on debug builds and firmware auditing for current interfaces.
Binary inspection
llvm-readelf, llvm-objdump, nm, and related target tools help answer:
- Which architecture and ABI was built?
- Which symbols and relocations create capabilities?
- Are all linked objects compatible?
- Which sections are executable, writable, or capability-bearing?
- Did the expected compartment entry point reach the final image?
Use the tools from the target software development kit (SDK). Host versions may not understand capability relocation types.
A fault-classification workflow
- Reproduce the failure with a pinned build and input.
- Record the complete fault and stack trace.
- Identify the capability and print its tag, bounds, permissions, and sealing state.
- Determine where that capability was created or narrowed.
- Classify the problem: bounds, permission, invalid tag, sealing, lifetime, ABI, or logic.
- Fix the source authority model rather than widening the capability blindly.
- Add a regression test that checks both valid and denied behaviour.
- Repeat on representative hardware if the bug depends on implementation details.
Common interpretations
- Invalid tag: Was the capability reconstructed from bytes or overwritten by an integer store?
- Bounds fault: Is the pointer bounded to the intended object, and is the access size correct?
- Permission fault: Did the interface intentionally remove write, execute, or capability-load authority?
- Sealed-capability fault: Was an opaque token used as a direct pointer?
- Failure after free: Which temporal-safety or revocation mechanism is meant to invalidate the stale reference?
- Link or loader failure: Are all objects, libraries, relocations, and application binary interfaces compatible?
Sources
cheribuildfor supported debugger build targets- CHERI Alliance GDB for Alliance-hosted CHERI-RISC-V work
- CTSRD-CHERI GDB for CHERI debugger sources
- CHERIoT Programmer’s Guide for embedded debug and audit workflows
A useful bug report includes the complete stack: architecture, processor or simulator, operating system or real-time operating system (RTOS), ABI, compiler, debugger, source revisions, build flags, input, and fault output.
