• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use core::fmt::{self, Debug, Display};
2 
3 use crate::arch::SingleStepGdbBehavior;
4 use crate::protocol::{PacketParseError, ResponseWriterError};
5 use crate::util::managed_vec::CapacityError;
6 
7 /// An error which may occur during a GDB debugging session.
8 #[derive(Debug)]
9 #[non_exhaustive]
10 pub enum GdbStubError<T, C> {
11     /// Connection Error while initializing the session.
12     ConnectionInit(C),
13     /// Connection Error while reading request.
14     ConnectionRead(C),
15     /// Connection Error while writing response.
16     ConnectionWrite(C),
17 
18     /// Client nack'd the last packet, but `gdbstub` doesn't implement
19     /// re-transmission.
20     ClientSentNack,
21     /// Packet cannot fit in the provided packet buffer.
22     PacketBufferOverflow,
23     /// Could not parse the packet into a valid command.
24     PacketParse(PacketParseError),
25     /// GDB client sent an unexpected packet. This should never happen!
26     /// Please re-run with `log` trace-level logging enabled and file an issue
27     /// at <https://github.com/daniel5151/gdbstub/issues>
28     PacketUnexpected,
29     /// GDB client sent a packet with too much data for the given target.
30     TargetMismatch,
31     /// Target encountered a fatal error.
32     TargetError(T),
33     /// Target responded with an unsupported stop reason.
34     ///
35     /// Certain stop reasons can only be used when their associated protocol
36     /// feature has been implemented. e.g: a Target cannot return a
37     /// `StopReason::HwBreak` if the hardware breakpoints IDET hasn't been
38     /// implemented.
39     UnsupportedStopReason,
40     /// Target didn't report any active threads when there should have been at
41     /// least one running.
42     NoActiveThreads,
43 
44     /// The target has not opted into using implicit software breakpoints.
45     /// See [`Target::guard_rail_implicit_sw_breakpoints`] for more information.
46     ///
47     /// [`Target::guard_rail_implicit_sw_breakpoints`]:
48     /// crate::target::Target::guard_rail_implicit_sw_breakpoints
49     ImplicitSwBreakpoints,
50     /// The target has not indicated support for optional single stepping. See
51     /// [`Target::guard_rail_single_step_gdb_behavior`] for more information.
52     ///
53     /// If you encountered this error while using an `Arch` implementation
54     /// defined in `gdbstub_arch` and believe this is incorrect, please file an
55     /// issue at <https://github.com/daniel5151/gdbstub/issues>.
56     ///
57     /// [`Target::guard_rail_single_step_gdb_behavior`]:
58     /// crate::target::Target::guard_rail_single_step_gdb_behavior
59     SingleStepGdbBehavior(SingleStepGdbBehavior),
60 
61     // Internal - A non-fatal error occurred (with errno-style error code)
62     //
63     // This "dummy" error is required as part of the internal
64     // `TargetResultExt::handle_error()` machinery, and will never be
65     // propagated up to the end user.
66     #[doc(hidden)]
67     NonFatalError(u8),
68 }
69 
70 impl<T, C> From<ResponseWriterError<C>> for GdbStubError<T, C> {
from(e: ResponseWriterError<C>) -> Self71     fn from(e: ResponseWriterError<C>) -> Self {
72         GdbStubError::ConnectionWrite(e.0)
73     }
74 }
75 
76 impl<A, T, C> From<CapacityError<A>> for GdbStubError<T, C> {
from(_: CapacityError<A>) -> Self77     fn from(_: CapacityError<A>) -> Self {
78         GdbStubError::PacketBufferOverflow
79     }
80 }
81 
82 impl<T, C> Display for GdbStubError<T, C>
83 where
84     C: Debug,
85     T: Debug,
86 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result87     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88         use self::GdbStubError::*;
89         match self {
90             ConnectionInit(e) => write!(f, "Connection Error while initializing the session: {:?}", e),
91             ConnectionRead(e) => write!(f, "Connection Error while reading request: {:?}", e),
92             ConnectionWrite(e) => write!(f, "Connection Error while writing response: {:?}", e),
93             ClientSentNack => write!(f, "Client nack'd the last packet, but `gdbstub` doesn't implement re-transmission."),
94             PacketBufferOverflow => write!(f, "Packet too big for provided buffer!"),
95             PacketParse(e) => write!(f, "Could not parse the packet into a valid command: {:?}", e),
96             PacketUnexpected => write!(f, "Client sent an unexpected packet. Please re-run with `log` trace-level logging enabled and file an issue at https://github.com/daniel5151/gdbstub/issues"),
97             TargetMismatch => write!(f, "GDB client sent a packet with too much data for the given target."),
98             TargetError(e) => write!(f, "Target threw a fatal error: {:?}", e),
99             UnsupportedStopReason => write!(f, "Target responded with an unsupported stop reason."),
100             NoActiveThreads => write!(f, "Target didn't report any active threads when there should have been at least one running."),
101 
102             ImplicitSwBreakpoints => write!(f, "Warning: The target has not opted into using implicit software breakpoints. See `Target::guard_rail_implicit_sw_breakpoints` for more information."),
103             SingleStepGdbBehavior(behavior) => {
104                 use crate::arch::SingleStepGdbBehavior;
105                 write!(
106                     f,
107                     "Warning: Mismatch between the targets' single-step support and arch-level single-step behavior: {} ",
108                     match behavior {
109                         SingleStepGdbBehavior::Optional => "", // unreachable, since optional single step will not result in an error
110                         SingleStepGdbBehavior::Required => "GDB requires single-step support on this arch.",
111                         SingleStepGdbBehavior::Ignored => "GDB ignores single-step support on this arch, yet the target has implemented support for it.",
112                         SingleStepGdbBehavior::Unknown => "This arch's single-step behavior hasn't been tested yet: please conduct a test + upstream your findings!",
113                     }
114                 )?;
115                 write!(f, "See `Target::guard_rail_single_step_gdb_behavior` for more information.")
116             },
117 
118             NonFatalError(_) => write!(f, "Internal non-fatal error. End users should never see this! Please file an issue if you do!"),
119         }
120     }
121 }
122 
123 #[cfg(feature = "std")]
124 impl<T, C> std::error::Error for GdbStubError<T, C>
125 where
126     C: Debug,
127     T: Debug,
128 {
129 }
130