1 use core::fmt::{self, Debug, Display}; 2 3 use crate::protocol::{PacketParseError, ResponseWriterError}; 4 use crate::util::managed_vec::CapacityError; 5 6 /// An error which may occur during a GDB debugging session. 7 #[derive(Debug)] 8 #[non_exhaustive] 9 pub enum GdbStubError<T, C> { 10 /// Connection Error while reading request. 11 ConnectionRead(C), 12 /// Connection Error while writing response. 13 ConnectionWrite(C), 14 /// Client nack'd the last packet, but `gdbstub` doesn't implement 15 /// re-transmission. 16 ClientSentNack, 17 /// Packet cannot fit in the provided packet buffer. 18 PacketBufferOverflow, 19 /// Could not parse the packet into a valid command. 20 PacketParse(PacketParseError), 21 /// GDB client sent an unexpected packet. This should never happen! 22 /// Please file an issue at https://github.com/daniel5151/gdbstub/issues 23 PacketUnexpected, 24 /// GDB client sent a packet with too much data for the given target. 25 TargetMismatch, 26 /// Target encountered a fatal error. 27 TargetError(T), 28 /// Target responded with an unsupported stop reason. 29 /// 30 /// Certain stop reasons can only be used when their associated protocol 31 /// feature has been implemented. e.g: a Target cannot return a 32 /// `StopReason::HwBreak` if the hardware breakpoints IDET hasn't been 33 /// implemented. 34 UnsupportedStopReason, 35 /// Target didn't report any active threads when there should have been at 36 /// least one running. 37 NoActiveThreads, 38 /// Internal - A non-fatal error occurred (with errno-style error code) 39 /// 40 /// This "dummy" error is required as part of the internal 41 /// `TargetResultExt::handle_error()` machinery, and will never be 42 /// propagated up to the end user. 43 #[doc(hidden)] 44 NonFatalError(u8), 45 } 46 47 impl<T, C> From<ResponseWriterError<C>> for GdbStubError<T, C> { from(e: ResponseWriterError<C>) -> Self48 fn from(e: ResponseWriterError<C>) -> Self { 49 GdbStubError::ConnectionWrite(e.0) 50 } 51 } 52 53 impl<A, T, C> From<CapacityError<A>> for GdbStubError<T, C> { from(_: CapacityError<A>) -> Self54 fn from(_: CapacityError<A>) -> Self { 55 GdbStubError::PacketBufferOverflow 56 } 57 } 58 59 impl<T, C> Display for GdbStubError<T, C> 60 where 61 C: Debug, 62 T: Debug, 63 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 65 use self::GdbStubError::*; 66 match self { 67 ConnectionRead(e) => write!(f, "Connection Error while reading request: {:?}", e), 68 ConnectionWrite(e) => write!(f, "Connection Error while writing response: {:?}", e), 69 ClientSentNack => write!(f, "Client nack'd the last packet, but `gdbstub` doesn't implement re-transmission."), 70 PacketBufferOverflow => write!(f, "Packet too big for provided buffer!"), 71 PacketParse(e) => write!(f, "Could not parse the packet into a valid command: {:?}", e), 72 PacketUnexpected => write!(f, "Client sent an unexpected packet. This should never happen! Please file an issue at https://github.com/daniel5151/gdbstub/issues"), 73 TargetMismatch => write!(f, "GDB client sent a packet with too much data for the given target."), 74 TargetError(e) => write!(f, "Target threw a fatal error: {:?}", e), 75 UnsupportedStopReason => write!(f, "Target responded with an unsupported stop reason."), 76 NoActiveThreads => write!(f, "Target didn't report any active threads when there should have been at least one running."), 77 NonFatalError(_) => write!(f, "Internal - A non-fatal error occurred (with errno-style error code)"), 78 } 79 } 80 } 81 82 #[cfg(feature = "std")] 83 impl<T, C> std::error::Error for GdbStubError<T, C> 84 where 85 C: Debug, 86 T: Debug, 87 { 88 } 89