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
Connectionforstd::net::TcpStream - Implements
std::error::Errorforgdbstub::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
allocdependency (for lower-end embedded targets)- The current
gdbstubimplementation 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!