Skip to content

Commit 1daea45

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 1daea45

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-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: 26 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,8 @@ 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+
#[cfg(feature = "std")]
149+
TargetCoreError(e) => write!(f, "Target threw a fatal error: {}", e),
143150
UnsupportedStopReason => write!(f, "{} {}", unsupported_stop_reason!(), CONTEXT),
144151
UnexpectedStepPacket => write!(f, "{} {}", unexpected_step_packet!(), CONTEXT),
145152

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

164181
impl<T, C> GdbStubError<T, C> {
@@ -175,6 +192,15 @@ impl<T, C> GdbStubError<T, C> {
175192
}
176193
}
177194

195+
/// If the error was due to a core error, return the core error trait.
196+
#[cfg(feature = "std")]
197+
pub fn into_core_error(self) -> Option<Box<dyn core::error::Error>> {
198+
match self.kind {
199+
InternalError::TargetCoreError(e) => Some(e),
200+
_ => None,
201+
}
202+
}
203+
178204
/// Check if the error was due to a connection error.
179205
pub fn is_connection_error(&self) -> bool {
180206
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)