1use super::call::CallError;
2use super::call::fmt::FmtCallError;
3use crate::debugger::address::GlobalAddress;
4use crate::debugger::r#async::AsyncError;
5use crate::debugger::debugee::RendezvousError;
6use crate::debugger::debugee::dwarf::unit::DieAddr;
7use crate::debugger::variable::value::ParsingError;
8use gimli::UnitOffset;
9use nix::unistd::Pid;
10use std::str::Utf8Error;
11use std::string::FromUtf8Error;
12
13#[derive(Debug, thiserror::Error)]
14pub enum Error {
15 #[error("debugee already run")]
17 AlreadyRun,
18 #[error(transparent)]
19 IO(#[from] std::io::Error),
20 #[error(transparent)]
21 Utf8(#[from] Utf8Error),
22 #[error(transparent)]
23 FromUtf8(#[from] FromUtf8Error),
24 #[error(transparent)]
25 RegEx(#[from] regex::Error),
26
27 #[error("no debug information for {0}")]
29 NoDebugInformation(&'static str),
30 #[error("unknown register {0:?}")]
31 RegisterNotFound(gimli::Register),
32 #[error("unknown register {0:?}")]
33 RegisterNameNotFound(String),
34 #[error("source place not found at address {0}")]
35 PlaceNotFound(GlobalAddress),
36 #[error("there are no suitable places for this request")]
37 NoSuitablePlace,
38 #[error("unit not found at address {0}")]
39 UnitNotFound(GlobalAddress),
40 #[error("function not found at address {0}")]
41 FunctionNotFound(GlobalAddress),
42 #[error("type not found")]
43 TypeNotFound,
44 #[error("frame number {0} not found")]
45 FrameNotFound(u32),
46 #[error("tracee number {0} not found")]
47 TraceeNotFound(u32),
48 #[error("debug information entry (die) not found, reference: {0:?}")]
49 DieNotFound(DieAddr),
50 #[error("section \"{0}\" not found")]
51 SectionNotFound(&'static str),
52
53 #[error("invalid binary representation of type `{0}`: {1:?}")]
55 TypeBinaryRepr(&'static str, Box<[u8]>),
56 #[error("unknown address")]
57 UnknownAddress,
58 #[error("memory region offset not found ({0})")]
59 MappingOffsetNotFound(&'static str),
60 #[error("memory region not found for a file: {0}")]
61 MappingNotFound(String),
62
63 #[error("waitpid syscall error: {0}")]
65 Waitpid(nix::Error),
66 #[error("ptrace syscall error: {0}")]
67 Ptrace(nix::Error),
68 #[error("{0} syscall error: {1}")]
69 Syscall(&'static str, nix::Error),
70 #[error("multiple syscall errors {0:?}")]
71 MultipleErrors(Vec<Self>),
72
73 #[error("variable or argument to watch not found")]
75 WatchSubjectNotFound,
76 #[error("there is more than one watchpoint candidate, try to specify the expression")]
77 WatchpointCollision,
78 #[error("there is no memory address for watchpoint")]
79 WatchpointNoAddress,
80 #[error("size of watch object is undefined")]
81 WatchpointUndefinedSize,
82 #[error(
83 "the size of the watch object does not fit into one of the size class (1, 2, 4, 8 bytes), try to specify a field to observe"
84 )]
85 WatchpointWrongSize,
86 #[error("watchpoint limit is reached (maximum 4 watchpoints), try to remove unused")]
87 WatchpointLimitReached,
88 #[error("memory location observed by another watchpoint")]
89 AddressAlreadyObserved,
90 #[error("unknown expression scope")]
91 UnknownScope,
92 #[error("variable frame is unavailable")]
93 VarFrameNotFound,
94
95 #[error("dwarf file parsing error: {0}")]
97 DwarfParsing(#[from] gimli::Error),
98 #[error("invalid debug-id note format")]
99 DebugIDFormat,
100 #[error("object file parsing error: {0}")]
101 ObjParsing(#[from] object::Error),
102 #[error(transparent)]
103 VariableParsing(#[from] ParsingError),
104 #[error("function specification ({0:?}) reference to unseen declaration")]
105 InvalidSpecification(UnitOffset),
106
107 #[error("unwind: no unwind context")]
109 UnwindNoContext,
110 #[error("unwind: too deep frame number")]
111 UnwindTooDeepFrame,
112
113 #[error("dwarf expression evaluation: eval option `{0}` required")]
115 EvalOptionRequired(&'static str),
116 #[error("dwarf expression evaluation: unsupported evaluation require ({0})")]
117 EvalUnsupportedRequire(&'static str),
118 #[error("no frame base address")]
119 NoFBA,
120 #[error("frame base address attribute not an expression")]
121 FBANotAnExpression,
122 #[error("range information for function `{0:?}` not exists")]
123 NoFunctionRanges(Option<String>),
124 #[error("die type not exists")]
125 NoDieType,
126 #[error("fail to read/evaluate implicit pointer address")]
127 ImplicitPointer,
128
129 #[error("libthread_db not enabled")]
131 NoThreadDB,
132 #[error("libthread_db: {0}")]
133 ThreadDB(#[from] thread_db::ThreadDbError),
134
135 #[error(transparent)]
137 Rendezvous(#[from] RendezvousError),
138
139 #[error("debugee process exit with code {0}")]
141 ProcessExit(i32),
142 #[error("program is not being started")]
143 ProcessNotStarted,
144
145 #[error("default toolchain not found")]
147 DefaultToolchainNotFound,
148 #[error("unrecognized rustup output")]
149 UnrecognizedRustupOut,
150
151 #[error("install disassembler: {0}")]
153 DisAsmInit(capstone::Error),
154 #[error("instructions disassembly error: {0}")]
155 DisAsm(capstone::Error),
156 #[error("error to determine current function start/end place")]
157 FunctionRangeNotFound,
158
159 #[error("hook: {0}")]
161 Hook(anyhow::Error),
162
163 #[error("process pid {0} not found")]
165 AttachedProcessNotFound(Pid),
166 #[error("attach a running process: {0}")]
167 Attach(nix::Error),
168
169 #[error("{0}. Maybe your async runtime version is unsupported.")]
171 Async(#[from] AsyncError),
172
173 #[error(transparent)]
175 Call(#[from] CallError),
176 #[error(transparent)]
177 FmtCall(#[from] FmtCallError),
178}
179
180impl Error {
181 pub fn is_fatal(&self) -> bool {
183 match self {
184 Error::AlreadyRun => false,
185 Error::IO(_) => false,
186 Error::Utf8(_) => false,
187 Error::FromUtf8(_) => false,
188 Error::RegEx(_) => false,
189 Error::NoDebugInformation(_) => false,
190 Error::RegisterNotFound(_) => false,
191 Error::RegisterNameNotFound(_) => false,
192 Error::PlaceNotFound(_) => false,
193 Error::NoSuitablePlace => false,
194 Error::UnitNotFound(_) => false,
195 Error::FunctionNotFound(_) => false,
196 Error::TypeNotFound => false,
197 Error::FrameNotFound(_) => false,
198 Error::TraceeNotFound(_) => false,
199 Error::DieNotFound(_) => false,
200 Error::TypeBinaryRepr(_, _) => false,
201 Error::UnknownAddress => false,
202 Error::MappingOffsetNotFound(_) => false,
203 Error::MappingNotFound(_) => false,
204 Error::Waitpid(_) => false,
205 Error::Ptrace(_) => false,
206 Error::MultipleErrors(_) => false,
207 Error::DebugIDFormat => false,
208 Error::VariableParsing(_) => false,
209 Error::UnwindNoContext => false,
210 Error::UnwindTooDeepFrame => false,
211 Error::EvalOptionRequired(_) => false,
212 Error::EvalUnsupportedRequire(_) => false,
213 Error::NoFBA => false,
214 Error::FBANotAnExpression => false,
215 Error::NoFunctionRanges(_) => false,
216 Error::NoDieType => false,
217 Error::ImplicitPointer => false,
218 Error::ThreadDB(_) => false,
219 Error::Rendezvous(_) => false,
220 Error::ProcessExit(_) => false,
221 Error::ProcessNotStarted => false,
222 Error::DefaultToolchainNotFound => false,
223 Error::UnrecognizedRustupOut => false,
224 Error::Hook(_) => false,
225 Error::SectionNotFound(_) => false,
226 Error::DisAsm(_) => false,
227 Error::InvalidSpecification(_) => false,
228 Error::FunctionRangeNotFound => false,
229 Error::WatchpointCollision => false,
230 Error::WatchpointNoAddress => false,
231 Error::WatchpointUndefinedSize => false,
232 Error::WatchpointWrongSize => false,
233 Error::WatchpointLimitReached => false,
234 Error::WatchSubjectNotFound => false,
235 Error::AddressAlreadyObserved => false,
236 Error::UnknownScope => false,
237 Error::VarFrameNotFound => false,
238 Error::Async(_) => false,
239 Error::Call(_) => false,
240 Error::FmtCall(_) => false,
241
242 Error::DwarfParsing(_) => true,
244 Error::ObjParsing(_) => true,
245 Error::Syscall(_, _) => true,
246 Error::NoThreadDB => true,
247 Error::DisAsmInit(_) => true,
248 Error::AttachedProcessNotFound(_) => true,
249 Error::Attach(_) => true,
250 }
251 }
252}
253
254#[macro_export]
255macro_rules! _error {
256 ($log_fn: path, $res: expr) => {
257 match $res {
258 Ok(value) => Some(value),
259 Err(e) => {
260 $log_fn!(target: "debugger", "{:#}", e);
261 None
262 }
263 }
264 };
265 ($log_fn: path, $res: expr, $msg: tt) => {
266 match $res {
267 Ok(value) => Some(value),
268 Err(e) => {
269 $log_fn!(target: "debugger", concat!($msg, " {:#}"), e);
270 None
271 }
272 }
273 };
274}
275
276#[macro_export]
278macro_rules! weak_error {
279 ($res: expr) => {
280 $crate::_error!(log::warn, $res)
281 };
282 ($res: expr, $msg: tt) => {
283 $crate::_error!(log::warn, $res, $msg)
284 };
285}
286
287#[macro_export]
289macro_rules! muted_error {
290 ($res: expr) => {
291 $crate::_error!(log::debug, $res)
292 };
293 ($res: expr, $msg: tt) => {
294 $crate::_error!(log::debug, $res, $msg)
295 };
296}
297
298#[macro_export]
300macro_rules! print_warns {
301 ($errors:expr) => {
302 $errors.iter().for_each(|e| {
303 log::warn!(target: "debugger", "{:#}", e);
304 })
305 };
306}