All notable changes to this project will be documented in this file.
This project adheres to Semantic Versioning.
- Add new
core_error
feature, to haveGdbStubError
implcore::error::Error
. #154 (ultimaweapon)- Note: Out of an abundance of caution, this has been put behind a
feature-flag, as while
gdbstub
doesn't claim a strict MSRV at this time, it seemed unwise to have a PATCH release break folks stuck on a pre-1.81 Rust toolchain.
- Note: Out of an abundance of caution, this has been put behind a
feature-flag, as while
- Add workaround for vCont packets that specify a '0' (Any) thread-id
- For more context, see
e9a5296c
- For more context, see
- Various README tweaks
- Various clippy lint fixes
- Fix incorrect valid-addr check in armv4t example
LibrariesSvr4
- List an SVR4 (System-V/Unix) target's libraries. #142 (alexcrichton)
stub::GdbStubError
is now an opaquestruct
with a handful of methods to extract user-defined context (as opposed to being anenum
that directly exposed all error internals to the user).- This change will enable future versions of
gdbstub
to fearlessly improve error messages and infrastructure without making semver breaking changes. See #112 for more.
- This change will enable future versions of
common::Signal
is not longer anenum
, and is instead astruct
with a singlepub u8
field + a collection of associated constants.- As a result, yet another instance of
unsafe
could be removed from the codebase!
- As a result, yet another instance of
Arch
API:- Entirely removed
single_step_behavior
. See #132 for details and rationale
- Entirely removed
Target
APIs:SingleThreadBase
/MultiThreadBase
read_addrs
now returns ausize
instead of a()
, allowing implementations to report cases where only a subset of memory could be read. #115 (geigerzaehler)
HostIo
- Reformatted codebase with nightly rustfmt using
imports_granularity = "Item"
ExtendedMode > CurrentActivePid
- Support reporting a non-default active PID #133- Required to fix
vAttach
behavior (see Bugfixes section below)
- Required to fix
- Fix for targets with no active threads #127 (xobs)
- Fix
vAttach
behavior when switching between multiple processes #129 (xobs), and #133 - Minor doc fixes
- Various README tweaks
- Remove some
unsafe
code - CI improvements
- Run no-panic checks on
example_no_std
- Run CI on docs
- Run no-panic checks on
MultiThreadBase > ThreadExtraInfo
- Provide extra information per-thread. #106 (thefaxman)LldbRegisterInfo
- (LLDB specific) Report register information in the LLDB format. #103 (jawilk)- This information can be statically included as part of the
Arch
implemention, or dynamically reported via theLldbRegisterInfoOverride
IDET.
- This information can be statically included as part of the
- Tweak enabled clippy lints
- Added a light dusting of
#[inline]
across the packet parsing code, crunching the code down even further - Expanded on "no-panic guarantee" docs
After over a half-year of development, gdbstub
0.6 has finally been released!
This massive release delivers a slew of new protocol extensions, internal improvements, and key API improvements. Some highlights include:
- A new non-blocking
GdbStubStateMachine
API, enablinggdbstub
to integrate nicely with async event loops!- Moreover, on
no_std
platforms, this new API enablesgdbstub
to be driven directly via breakpoint/serial interrupt handlers! - This API is already being used in several Rust kernel projects, such as
vmware-labs/node-replicated-kernel
andbetrusted-io/xous-core
to enable bare-metal, in-kernel debugging.
- Moreover, on
gdbstub
is now entirely panic free in release builds!- * subject to
rustc
's compiler optimizations - This was a pretty painstaking effort, but the end result is a substantial reduction in binary size on
no_std
platforms.
- * subject to
- Tons of new and exciting protocol extensions, including but not limited to:
- Support for remote file I/O (reading/writing files to the debug target)
- Fetching remote memory maps
- Catching + reporting syscall entry/exit conditions
- ...and many more!
- A new license:
gdbstub
is licensed under MIT OR Apache-2.0
See the changelog for a comprehensive rundown of all the new features.
While this release does come with quite a few breaking changes, the core IDET-based Target
API has remained much the same, which should make porting code over from 0.5.x to 0.6 pretty mechanical. See the transition_guide.md
for guidance on upgrading from 0.5.x
to 0.6
.
And as always, a huge shoutout to the folks who contributed PRs, Issues, and ideas to gdbstub
- this release wouldn't have been possible without you! Special shoutouts to gz and xobs for helping me test and iterate on the new bare-metal state machine API, and bet4it for pointing out and implementing many useful API improvements and internal refactors.
Cheers!
- The new
GdbStubStateMachine
API gives users the power and flexibility to integrategdbstub
into their project-specific event loop infrastructure.- e.g: A global instance of
GdbStubStateMachine
can be driven directly from bare-metal interrupt handlers inno_std
environments - e.g: A project using
async
/await
can wrapGdbStubStateMachine
in a task, yielding execution while waiting for the target to resume / new data to arrive down theConnection
- e.g: A global instance of
- Removed all panicking code from
gdbstub
- See the commit message for more details on how this was achieved.
- Introduced strongly-typed enum for protocol defined signal numbers (instead of using bare
u8
s) - Added basic feature negotiation to support clients that don't support
multiprocess+
extensions. - Relicensed
gdbstub
under MIT OR Apache-2.0 #68 - Added several new "guard rails" to avoid common integration footguns:
Target::guard_rail_implicit_sw_breakpoints
- guards against the GDB client silently overriding target instructions with breakpoints ifSwBreakpoints
hasn't been implemented.Target::guard_rail_single_step_gdb_behavior
- guards against a GDB client bug where support for single step may be required / ignored on certain platforms (e.g: required on x86, ignored on MIPS)
- Added several new "toggle switches" to enable/disable parts of the protocol (all default to
true
)Target::use_x_upcase_packet
- toggle support for the more efficientX
memory write packetTarget::use_resume_stub
- togglegdbstub
's built-in "stub" resume handler that returnsSIGRAP
if a target doesn't implement support for resumptionTarget::use_rle
- toggle whether outgoing packets are Run Length Encoded (RLE)
MemoryMap
- Get memory map XML file from the target. #54 (Tiwalun)CatchSyscalls
- Enable and disable catching syscalls from the inferior process. #57 (mchesser)HostIo
- Perform I/O operations on host. #66 (bet4it)- Support for all Host I/O operations:
open
,close
,pread
,pwrite
,fstat
,unlink
,readlink
,setfs
- Support for all Host I/O operations:
ExecFile
- Get full absolute path of the file that was executed to create a process running on the remote system. #69 (bet4it)Auxv
- Access the target’s auxiliary vector. #86 (bet4it)- Implement
X
packet - More efficient bulk-write to memory (superceding theM
packet). #82 (gz)
Connection
API:- Removed the
read
andpeek
methods fromConnection
- These have been moved to the new
ConnectionExt
trait, which is used in the newGdbStub::run_blocking
API
- These have been moved to the new
- Removed the
Arch
API:Target
APIs:- prefix all IDET methods with
support_
- _makes it far easier to tell at-a-glance whether a method is an IDET, or an actual handler method.
- Introduce strongly-typed enum for protocol defined signal numbers (instead of using bare
u8
s) Base
API:- Make single-stepping optional #92
- Remove
GdbInterrupt
type (interrupt handling lifted to higher-level APIs) - Remove
ResumeAction
type (in favor of separate methods for various resume types)
Breakpoints
API:HwWatchpoint
: Plumb watchpointlength
parameter to public API
TargetXml
API:- Support for
<xi:include>
in target.xml, which required including theannex
parameter in the handler method. annex
is set tob"target.xml"
on the fist call, though it may be set to other values in subsequent calls if<xi:include>
is being used.
- Support for
- Pass
PacketBuf
-backed&mut [u8]
as a response buffer to various APIs #72 (bet4it)- Improvement over the callback-based approach.
- This change is possible thanks to a clause in the GDB spec that specifies that responses will never exceed the size of the
PacketBuf
. - Also see #70, which tracks some other methods that might be refactored to use this approach in the future.
- prefix all IDET methods with
- Documentation
- Use stable
clippy
in CI - Enable logging for responses with only alloc #78 (gz)
- Lots of internal refactoring and cleanup
While the overall structure of the API has remained the same, 0.5.0
does introduce a few breaking API changes that require some attention. That being said, it should not be a difficult migration, and updating to 0.5.0
from 0.4
shouldn't take more than 10 mins of refactoring.
Check out transition_guide.md
for guidance on upgrading from 0.4.x
to 0.5
.
- Implement Run-Length-Encoding (RLE) on outgoing packets
- This significantly cuts down on the data being transferred over the wire when reading from registers/memory
- Add target-specific
kind: Arch::BreakpointKind
parameters to the Breakpoint API- While emulated systems typically implement breakpoints by pausing execution once the PC hits a certain value, "real" systems typically need to patch the instruction stream with a breakpoint instruction. On systems with variable-sized instructions, this
kind
parameter specifies the size of the instruction that should be injected.
- While emulated systems typically implement breakpoints by pausing execution once the PC hits a certain value, "real" systems typically need to patch the instruction stream with a breakpoint instruction. On systems with variable-sized instructions, this
- Implement
ResumeAction::{Step,Continue}WithSignal
- Added the
Exited(u8)
,Terminated(u8)
, andReplayLog("begin"|"end")
stop reasons. - Added
DisconnectReason::Exited(u8)
andDisconnectReason::Terminated(u8)
. - Reworked the
MultiThreadOps::resume
API to be significantly more ergonomic and efficient- See the transition guide for more details.
{Single,Multi}ThreadReverse{Step,Continue}
- Support for reverse-step and reverse-continue. #48 (DrChat){Single,Multi}ThreadRangeStepping
- Optional optimized range stepping support.
gdbstub::arch
has been moved into a separategdbstub_arch
crate- See #45 for details on why this was done.
- (x86) Break GPRs & SRs into individual fields/variants #34
- Base Protocol Refactors
- Reworked the
MultiThreadOps::resume
API - Added a wrapper around the raw
check_gdb_interrupt
callback, hiding the underlying implementation details - Extracted base protocol single-register access methods (
{read,write}_register
) into separateSingleRegisterAccess
trait- These are optional GDB protocol methods, and as such, should be modeled as IDETs
- Reworked the
- Protocol Extension Refactors
- Consolidated the
{Hw,Sw}Breakpoints/Watchpoints
IDETs under a singleBreakpoints
IDET + sub-IDETs - Added new arch-specific
kind: Arch::BreakpointKind
parameter toadd_{hw,sw}_breakpoint
methods - Renamed
target::ext::extended_mod::ConfigureASLR{Ops}
toConfigureAslr{Ops}
(clippy::upper_case_acronyms)
- Consolidated the
- Added
{Step,Continue}WithSignal
variants totarget::ext::base::ResumeAction
- Trait Changes
arch::Arch
: Addedtype BreakpointKind
. Required to support arch-specific breakpoint kindsarch::Arch
: (very minor) Addednum_traits::FromPrimitive
bound toArch::Usize
arch::Registers
: Addedtype ProgramCounter
and associatedfn pc(&self) -> Self::ProgramCounter
method. Added preemptively in anticipation of future GDB Agent support
- Removed the
Halted
stop reason (more accurate to simply return{Exited|Terminated}(SIGSTOP)
instead). - Removed the
Halted
disconnect reason (replaced with theExited
andTerminated
stop reasons instead). - Removed the implicit
ExtendedMode
attached PID tracking whenalloc
was available. See23b56038
rationale behind this change.
- Split monolithic
GdbStubImpl
implementation into separate files (by protocol extension) - Finally rewrite + optimize
GdbStubImpl::do_vcont
, along with streamlining its interactions with the legacys
andc
packets - Sprinkle more IDET-based dead code elimination hints (notably wrt. stop reasons)
- Remove the default
self.current_mem_tid
hack, replacing it with a much more elegant solution - Packet Parser improvements
- Remove last remaining bit of UTF-8 related code
- Eliminate as much panicking bounds-checking code as possible
- support efficient parsing of packets that are parsed differently depending on active protocol extension (namely, the breakpoint packets)
- (currently unused) Zero-cost support for parsing
Z
andz
packets with embedded agent bytecode expressions
- Use intra-doc links whenever possible
TargetDescriptionXmlOverride
- Allow targets to override the target description XML file (target.xml
) specified byTarget::Arch::target_description_xml
. This is useful in cases where aTarget
is expected to be generic over multiple architectures. #43 (with help from DrChat)
- use
write!
instead ofwriteln!
inoutput!
macro #41
- Implement
RegId
for Mips/Mips64 #38 (starfleetcadet75) - Implement
RegId
for MSP430 #38 (starfleetcadet75)
- Switch fatal error signal from
T06
toS05
, - specify cfg-if 0.1.10 or later #33 (keiichiw)
cargo build
fails if cfg-if is 0.1.9 or older
- Don't hard-code u64 when parsing packets (use big-endian byte arrays + late conversion to
Target::Arch::Usize
).
This version includes a major API overhaul, alongside a slew of new features and general improvements. While updating to 0.4.0
will require some substantial code modifications, it's well worth the effort, as 0.4.0
is the safest, leanest, and most featureful release of gdbstub
yet!
Fun fact: Even after adding a bunch of new features and bug-fixes, the in-tree example_no_std
has remained just as small! The example on the semver-fix-0.2.2
branch is 20251
bytes, while the example on 0.4.0
is 20246
bytes.
- Rewrite the
Target
API in terms of "Inlineable Dyn Extension Traits" (IDETs)- By breaking up
Target
into smaller pieces which can be mixed-and-matched, it not only makes it easier to get up-and-running withgdbstub
, but it also unlocks a lot of awesome internal optimizations:- Substantially reduces binary-size footprint by guaranteeing dead-code-elimination of parsing/handling unimplemented GDB protocol features.
- Compile-time enforcement that certain groups of methods are implemented in-tandem (e.g:
add_sw_breakpoint
andremove_sw_breakpoint
).
- By breaking up
- Update the
Target
API with support for non-fatal error handling.- The old approach of only allowing *fatal* errors was woefully inadequate when dealing with potentially fallible operations such as reading from unauthorized memory (which GDB likes to do a bunch), or handling non-fatal
std::io::Error
that occur as a result ofExtendedMode
operations. The newTargetResult
/TargetError
result is much more robust, and opens to door to supporting additional error handling extensions (such as LLDB's ASCII Errors).
- The old approach of only allowing *fatal* errors was woefully inadequate when dealing with potentially fallible operations such as reading from unauthorized memory (which GDB likes to do a bunch), or handling non-fatal
- Update the
Connection
trait with new methods (flush
- required,write_all
,on_session_start
) - Lift
Registers::RegId
toArch::RegId
, and introduce new temporaryRegIdImpl
solution for avoiding breaking API changes due to newRegId
implementations (see #29) - Mark various
RegId
enums as#[non_exhaustive]
, allowing more registers to be added if need be. - Error types are now marked as
#[non_exhaustive]
.
ExtendedMode
- Allow targets to run new processes / attach to existing processes / restart execution.- Includes support for
set disable-randomization
,set environment
,set startup-with-shell
, andset cwd
andcd
.
- Includes support for
SectionOffsets
- Get section/segment relocation offsets from the target. #30 (mchesser)- Uses the
qOffsets
packet under-the-hood.
- Uses the
- Fix issues related to selecting the incorrect thread after hitting a breakpoint in multi-threaded targets.
- Ensure that
set_nodelay
is set when using aTcpStream
as aConnection
(via the newConnection::on_session_start
API)- This should result in a noticeable performance improvement when debugging over TCP.
- Removed
btou
dependency. - Removed all
UTF-8
awarestr
handling code.- GDB uses a pure ASCII protocol, so including code to deal with UTF-8 resulted in unnecessary binary bloat.
This version contains a few minor breaking changes from 0.2.1
. These are only surface-level changes, and can be fixed with minimal effort.
Version 0.3.0
is identical to the yanked version 0.2.2
, except that it adheres to cargo
's modified SemVer rule which states that the pre-0.x.y
breaking changes should still bump the minor version.
Thanks to h33p for reporting this issue (#27)
- Update
Target::resume
API to replace raw&mut dyn Iterator
with a functionally identical concreteActions
iterator. - Mark the
StopReason
enum as#[non_exhaustive]
, allowing further types to be added without being considered as an API breaking change.
- Add
Target::read/write_register
support (to support single register accesses) #22 (thomashk0) - Add
StopReason::Signal(u8)
variant, to send arbitrary signal codes #19 (mchesser)
- Add partial RISC-V support (only integer ISA at the moment) #21 (thomashk0)
- Add i386 (x86) support #23 (jamcleod)
- Add 32-bit PowerPC support #25 (jamcleod)
- Add x86_64 support #11 (jamcleod)
- Add Mips and Mips64 support #13 (starfleetcadet75)
- Documentation improvements
- Document PC adjustment requirements in
Target::resume
- Add docs on handling non-fatal invalid memory reads/writes in
Target::read/write_addrs
.
- Document PC adjustment requirements in
start of changelog