crash_handler/windows.rs
1pub mod jmp;
2mod signal;
3mod state;
4
5use crate::Error;
6
7/// Possible exception codes values for the the `exception_code` field
8/// in the crash context.
9///
10/// This is mainly for testing purposes, and is not exhaustive nor really accurate,
11/// as eg. a distinction is made between a divide by zero between integers and
12/// floats.
13#[derive(Copy, Clone)]
14#[repr(i32)]
15#[allow(overflowing_literals)]
16pub enum ExceptionCode {
17 Abort = 0x40000015, // STATUS_FATAL_APP_EXIT
18 Fpe = -1073741676, // EXCEPTION_INT_DIVIDE_BY_ZERO
19 Illegal = -1073741795, // EXCEPTION_ILLEGAL_INSTRUCTION
20 Segv = -1073741819, // EXCEPTION_ACCESS_VIOLATION
21 StackOverflow = -1073741571, // EXCEPTION_STACK_OVERFLOW
22 Trap = -2147483645, // EXCEPTION_BREAKPOINT
23 InvalidParameter = -1073741811, // STATUS_INVALID_PARAMETER
24 Purecall = -1073741787, // STATUS_NONCONTINUABLE_EXCEPTION
25 User = 0xcca11ed, // https://github.com/chromium/crashpad/blob/fca8871ca3fb721d3afab370ca790122f9333bfd/util/win/exception_codes.h#L32
26 HeapCorruption = 0xc0000374, // STATUS_HEAP_CORRUPTION
27}
28
29/// A Windows exception handler
30pub struct CrashHandler;
31
32#[allow(clippy::unused_self)]
33impl CrashHandler {
34 /// Attaches the crash handler.
35 ///
36 /// The provided callback will be invoked if an exception is caught,
37 /// providing a [`crate::CrashContext`] with the details of the thread where
38 /// the exception was thrown.
39 pub fn attach(on_crash: Box<dyn crate::CrashEvent>) -> Result<Self, Error> {
40 state::attach(on_crash)?;
41 Ok(Self)
42 }
43
44 /// Detaches this handler, removing it from the handler stack.
45 ///
46 /// This is done automatically when this [`CrashHandler`] is dropped.
47 #[inline]
48 pub fn detach(self) {
49 state::detach();
50 }
51
52 /// Creates an exception with the specified exception code that is passed
53 /// through the user provided callback.
54 pub fn simulate_exception(&self, exception_code: Option<i32>) -> crate::CrashEventResult {
55 // Normally this would be an unsafe function, since this unsafe encompasses
56 // the entirety of the body, however the user is really not required to
57 // uphold any guarantees on their end, so no real need to declare the
58 // function itself unsafe.
59 unsafe { state::simulate_exception(exception_code) }
60 }
61}
62
63impl Drop for CrashHandler {
64 fn drop(&mut self) {
65 state::detach();
66 }
67}