Skip to content

Commit ad2ea07

Browse files
committed
error: support core::error::Error types
Support reporting errors that conform to core::error::Error. This allows for calling e.source(), which may provide more information. As an example, using the `probe-rs` gdbserver. Before: During the execution of GDB an error was encountered: Target threw a fatal error: A RISC-V specific error occurred. (No further information is available) After: During the execution of GDB an error was encountered: Target threw a fatal error: A RISC-V specific error occurred. ... caused by: Error occurred during execution of an abstract command: Exception This is gated by "std", so should not pose any API changes to deeply embedded targets.
1 parent 9857c38 commit ad2ea07

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

src/stub/core_impl.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ pub(crate) mod target_result_ext {
7272
Err(TargetError::Errno(code)) => code,
7373
#[cfg(feature = "std")]
7474
Err(TargetError::Io(e)) => e.raw_os_error().unwrap_or(121) as u8,
75+
#[cfg(feature = "std")]
76+
Err(TargetError::FatalCore(e)) => return Err(InternalError::TargetCoreError(e)),
7577
};
7678

7779
Err(InternalError::NonFatalError(code))

src/stub/error.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ pub(crate) enum InternalError<T, C> {
2828
/// Target encountered a fatal error.
2929
TargetError(T),
3030

31+
/// Target encountered a fatal error. More information may be available
32+
/// in the source of the error.
33+
#[cfg(feature = "std")]
34+
TargetCoreError(Box<dyn core::error::Error + Send + Sync + 'static>),
35+
3136
ClientSentNack,
3237
PacketBufferOverflow,
3338
PacketParse(PacketParseError),
@@ -140,6 +145,7 @@ where
140145
PacketUnexpected => write!(f, "Client sent an unexpected packet. This should never happen! Please re-run with `log` trace-level logging enabled and file an issue at https://github.com/daniel5151/gdbstub/issues"),
141146
TargetMismatch => write!(f, "Received a packet with too much data for the given target"),
142147
TargetError(e) => write!(f, "Target threw a fatal error: {}", e),
148+
TargetCoreError(e) => write!(f, "Target threw a fatal error: {}", e),
143149
UnsupportedStopReason => write!(f, "{} {}", unsupported_stop_reason!(), CONTEXT),
144150
UnexpectedStepPacket => write!(f, "{} {}", unexpected_step_packet!(), CONTEXT),
145151

@@ -159,6 +165,16 @@ where
159165
C: Debug + Display,
160166
T: Debug + Display,
161167
{
168+
#[cfg(feature = "std")]
169+
fn source(&self) -> Option<&(dyn CoreError + 'static)> {
170+
let GdbStubError {
171+
kind: InternalError::TargetCoreError(e),
172+
} = self
173+
else {
174+
return None;
175+
};
176+
e.source()
177+
}
162178
}
163179

164180
impl<T, C> GdbStubError<T, C> {
@@ -175,6 +191,14 @@ impl<T, C> GdbStubError<T, C> {
175191
}
176192
}
177193

194+
/// If the error was due to a target error, return the concrete error type.
195+
pub fn into_core_error(self) -> Option<Box<dyn core::error::Error>> {
196+
match self.kind {
197+
InternalError::TargetCoreError(e) => Some(e),
198+
_ => None,
199+
}
200+
}
201+
178202
/// Check if the error was due to a connection error.
179203
pub fn is_connection_error(&self) -> bool {
180204
matches!(self.kind, InternalError::Connection(..))

src/target/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,13 @@ pub enum TargetError<E> {
324324
/// debugging session, and return a
325325
/// [`GdbStubError`](crate::stub::GdbStubError)!
326326
Fatal(E),
327+
/// A generic fatal error with a core Error implementation.
328+
///
329+
/// **WARNING:** Returning this error will immediately terminate the GDB
330+
/// debugging session, and return a
331+
/// [`GdbStubError`](crate::stub::GdbStubError)!
332+
#[cfg(feature = "std")]
333+
FatalCore(Box<dyn core::error::Error + Send + Sync + 'static>),
327334
}
328335

329336
/// Converts a `()` into a `TargetError::NonFatal`.

0 commit comments

Comments
 (0)