gdbstub
An implementation of the GDB Remote Serial Protocol in Rust, primarily for use in emulators.
gdbstub
tries to make as few assumptions as possible about a project's architecture, and aims to provide a "drop-in" way to add GDB support, without requiring any large refactoring / ownership juggling. It is particularly useful in emulators, where it provides a powerful, non-intrusive way to debug code running within an emulated system.
Disclaimer: gdbstub
is still in it's early stages of development! Expect breaking API changes between minor releases.
Debugging Features
At the moment, gdbstub
implements enough of the GDB Remote Serial Protocol to support step-through + breakpoint debugging of single-threaded code.
- Core GDB Protocol
- Step + Continue
- Add + Remove Breakpoints
- Read/Write memory
- Read/Write registers
- Read/Write/Access Watchpoints (i.e: value breakpoints) (currently broken)
- Extended GDB Protocol
- (optional) Automatic architecture detection
The GDB Remote Serial Protocol is surprisingly complex, supporting advanced features such as remote file I/O, spawning new processes, "rewinding" program execution, and much, much more. Thankfully, most of these features are completely optional, and getting a basic debugging session up-and-running only requires a small subset of commands to be implemented.
Feature flags
gdbstub
is no_std
by default, though it does have a dependency on alloc
.
Additional functionality can be enabled by activating certain features.
std
- (disabled by default)- Implements
Connection
forstd::net::TcpStream
- Implements
std::error::Error
forgdbstub::Error
- Outputs protocol responses via
log::trace!
- Implements
Future Plans
- Improve packet-parsing infrastructure
- Macros can be clever, but sometimes, they can be too clever...
- Improve multiprocess / multi-thread / multi-core support?
- Re-architect internals to remove
alloc
dependency (for lower-end embedded targets)- The current
gdbstub
implementation clearly separates packet parsing and command execution, and uses intermediate allocations to store structured command data. Interleaving packet parsing and command execution would remove the need for these intermediate allocations, at the expense of potentially less clear code... - Would require users to allocate packet buffers themselves
- The current
Using gdbstub
on bare-metal hardware
While the target use-case for gdbstub
is emulation, the crate is no_std
compatible (albeit with a dependency on alloc
), which means it should be possible to use in embedded contexts as well.
At the moment, this is not a "first-class" use-case, and has not been tested. Please let me know if you've had any success using gdbstub
on actual hardware!