From b23180394b5e8c2d69bc5bb90132c24931dd375c Mon Sep 17 00:00:00 2001 From: "Dongjia \"toka\" Zhang" Date: Tue, 30 Apr 2024 17:18:39 +0200 Subject: [PATCH] Fix Ctrl-C Handler (#2124) * fix * fix * win * win clp * a * FMT * aaaaaaaaaaa * aa --------- Co-authored-by: Your Name --- libafl/src/events/llmp.rs | 64 ++-- libafl/src/events/mod.rs | 60 ++-- libafl/src/events/simple.rs | 55 ++- libafl/src/events/tcp.rs | 56 ++- libafl/src/executors/hooks/windows.rs | 5 +- libafl_bolts/src/os/mod.rs | 2 +- libafl_bolts/src/os/windows_exceptions.rs | 401 +++++++++++++++------- 7 files changed, 371 insertions(+), 272 deletions(-) diff --git a/libafl/src/events/llmp.rs b/libafl/src/events/llmp.rs index f80404f1fe..e604de0583 100644 --- a/libafl/src/events/llmp.rs +++ b/libafl/src/events/llmp.rs @@ -50,7 +50,7 @@ use typed_builder::TypedBuilder; use super::{hooks::EventManagerHooksTuple, CustomBufEventResult, CustomBufHandlerFn}; #[cfg(any(feature = "std", feature = "adaptive_serialization"))] use crate::events::AdaptiveSerializer; -#[cfg(all(unix, feature = "std"))] +#[cfg(all(unix, feature = "std", not(miri)))] use crate::events::EVENTMGR_SIGHANDLER_STATE; #[cfg(feature = "adaptive_serialization")] use crate::observers::TimeObserver; @@ -1426,19 +1426,6 @@ where S: State + HasExecutions, MT: Monitor + Clone, { - /// Internal function, returns true when shuttdown is requested by a `SIGINT` signal - #[inline] - #[allow(clippy::unused_self)] - fn is_shutting_down() -> bool { - #[cfg(unix)] - unsafe { - core::ptr::read_volatile(core::ptr::addr_of!(EVENTMGR_SIGHANDLER_STATE.shutting_down)) - } - - #[cfg(windows)] - false - } - /// Launch the broker and the clients and fuzz pub fn launch(&mut self) -> Result<(Option, LlmpRestartingEventManager), Error> { // We start ourself as child process to actually fuzz @@ -1549,15 +1536,6 @@ where // Store the information to a map. staterestorer.write_to_env(_ENV_FUZZER_SENDER)?; - // We setup signal handlers to clean up shmem segments used by state restorer - #[cfg(all(unix, not(miri)))] - if let Err(_e) = - unsafe { setup_signal_handler(addr_of_mut!(EVENTMGR_SIGHANDLER_STATE)) } - { - // We can live without a proper ctrl+c signal handler. Print and ignore. - log::error!("Failed to setup signal handlers: {_e}"); - } - let mut ctr: u64 = 0; // Client->parent loop loop { @@ -1570,31 +1548,56 @@ where match unsafe { fork() }? { ForkResult::Parent(handle) => { unsafe { - EVENTMGR_SIGHANDLER_STATE.set_exit_from_main(); + libc::signal(libc::SIGINT, libc::SIG_IGN); } self.shmem_provider.post_fork(false)?; handle.status() } ForkResult::Child => { + // We setup signal handlers to clean up shmem segments used by state restorer + #[cfg(all(unix, not(miri)))] + if let Err(_e) = unsafe { + setup_signal_handler(addr_of_mut!(EVENTMGR_SIGHANDLER_STATE)) + } { + // We can live without a proper ctrl+c signal handler. Print and ignore. + log::error!("Failed to setup signal handlers: {_e}"); + } + // println!("child {}", std::process::id()); self.shmem_provider.post_fork(true)?; break (staterestorer, self.shmem_provider.clone(), core_id); } } }; - #[cfg(all(unix, not(feature = "fork")))] + // If this guy wants to fork, then ignore sigit + #[cfg(any(windows, not(feature = "fork")))] unsafe { - EVENTMGR_SIGHANDLER_STATE.set_exit_from_main(); + #[cfg(windows)] + libafl_bolts::os::windows_exceptions::signal( + libafl_bolts::os::windows_exceptions::SIGINT, + libafl_bolts::os::windows_exceptions::sig_ign(), + ); + + #[cfg(unix)] + libc::signal(libc::SIGINT, libc::SIG_IGN); } // On Windows (or in any case without fork), we spawn ourself again #[cfg(any(windows, not(feature = "fork")))] let child_status = startable_self()?.status()?; - #[cfg(all(unix, not(feature = "fork")))] + #[cfg(any(windows, not(feature = "fork")))] let child_status = child_status.code().unwrap_or_default(); compiler_fence(Ordering::SeqCst); + if child_status == crate::events::CTRL_C_EXIT || staterestorer.wants_to_exit() { + // if ctrl-c is pressed, we end up in this branch + if let Err(err) = mgr.detach_from_broker(self.broker_port) { + log::error!("Failed to detach from broker: {err}"); + } + return Err(Error::shutting_down()); + } + #[allow(clippy::manual_assert)] if !staterestorer.has_content() && !self.serialize_state.oom_safe() { if let Err(err) = mgr.detach_from_broker(self.broker_port) { @@ -1608,13 +1611,6 @@ where panic!("Fuzzer-respawner: Storing state in crashed fuzzer instance did not work, no point to spawn the next client! This can happen if the child calls `exit()`, in that case make sure it uses `abort()`, if it got killed unrecoverable (OOM), or if there is a bug in the fuzzer itself. (Child exited with: {child_status})"); } - if staterestorer.wants_to_exit() || Self::is_shutting_down() { - // if ctrl-c is pressed, we end up in this branch - if let Err(err) = mgr.detach_from_broker(self.broker_port) { - log::error!("Failed to detach from broker: {err}"); - } - return Err(Error::shutting_down()); - } ctr = ctr.wrapping_add(1); } } else { diff --git a/libafl/src/events/mod.rs b/libafl/src/events/mod.rs index ec90d44d0e..c7f6f3c706 100644 --- a/libafl/src/events/mod.rs +++ b/libafl/src/events/mod.rs @@ -55,31 +55,23 @@ use crate::{ state::HasScalabilityMonitor, }; +/// The special exit code when the target exited throught ctrl-c +#[cfg(unix)] +pub const CTRL_C_EXIT: i32 = 100; +/// The special exit code when the target exited throught ctrl-c +#[cfg(windows)] +pub const CTRL_C_EXIT: i32 = -1073741510; + /// Check if ctrl-c is sent with this struct #[cfg(all(unix, feature = "std"))] -pub static mut EVENTMGR_SIGHANDLER_STATE: ShutdownSignalData = ShutdownSignalData { - shutting_down: false, - exit_from_main: false, -}; +pub static mut EVENTMGR_SIGHANDLER_STATE: ShutdownSignalData = ShutdownSignalData {}; -/// A signal handler for releasing `StateRestore` `ShMem` -/// This struct holds a pointer to `StateRestore` and clean up the `ShMem` segment used by it. +/// A signal handler for catching ctrl-c. +/// The purpose of this signal handler is solely for calling `exit()` with a specific exit code 100 +/// In this way, the restarting manager can tell that we really want to exit #[cfg(all(unix, feature = "std"))] #[derive(Debug, Clone)] -pub struct ShutdownSignalData { - shutting_down: bool, - exit_from_main: bool, -} - -#[cfg(all(unix, feature = "std"))] -impl ShutdownSignalData { - /// Set the flag to true, indicating that this process has allocated shmem - pub fn set_exit_from_main(&mut self) { - unsafe { - core::ptr::write_volatile(core::ptr::addr_of_mut!(self.exit_from_main), true); - } - } -} +pub struct ShutdownSignalData {} /// Shutdown handler. `SigTerm`, `SigInterrupt`, `SigQuit` call this /// We can't handle SIGKILL in the signal handler, this means that you shouldn't kill your fuzzer with `kill -9` because then the shmem segments are never freed @@ -91,27 +83,15 @@ impl Handler for ShutdownSignalData { _info: &mut siginfo_t, _context: Option<&mut ucontext_t>, ) { - /* - println!( - "in handler! {} {}", - self.exit_from_main, - std::process::id() - ); - */ - // if this process has not allocated any shmem. then simply exit() - if !self.exit_from_main { - unsafe { - #[cfg(unix)] - libc::_exit(0); - - #[cfg(windows)] - windows::Win32::System::Threading::ExitProcess(1); - } - } - - // else wait till the next is_shutting_down() is called. then the process will exit throught main(). + // println!("in handler! {}", std::process::id()); unsafe { - core::ptr::write_volatile(core::ptr::addr_of_mut!(self.shutting_down), true); + // println!("Exiting from the handler...."); + + #[cfg(unix)] + libc::_exit(100); + + #[cfg(windows)] + windows::Win32::System::Threading::ExitProcess(100); } } diff --git a/libafl/src/events/simple.rs b/libafl/src/events/simple.rs index 2eae589ff6..ffcf1de112 100644 --- a/libafl/src/events/simple.rs +++ b/libafl/src/events/simple.rs @@ -23,7 +23,7 @@ use libafl_bolts::{shmem::ShMemProvider, staterestore::StateRestorer}; use serde::{de::DeserializeOwned, Serialize}; use super::{CustomBufEventResult, CustomBufHandlerFn, HasCustomBufHandlers, ProgressReporter}; -#[cfg(all(unix, feature = "std"))] +#[cfg(all(unix, feature = "std", not(miri)))] use crate::events::EVENTMGR_SIGHANDLER_STATE; use crate::{ events::{ @@ -453,19 +453,6 @@ where } } - /// Internal function, returns true when shuttdown is requested by a `SIGINT` signal - #[inline] - #[allow(clippy::unused_self)] - fn is_shutting_down() -> bool { - #[cfg(unix)] - unsafe { - core::ptr::read_volatile(core::ptr::addr_of!(EVENTMGR_SIGHANDLER_STATE.shutting_down)) - } - - #[cfg(windows)] - false - } - /// Launch the simple restarting manager. /// This [`EventManager`] is simple and single threaded, /// but can still used shared maps to recover from crashes and timeouts. @@ -488,15 +475,6 @@ where //let staterestorer = { LlmpSender::new(shmem_provider.clone(), 0, false)? }; staterestorer.write_to_env(_ENV_FUZZER_SENDER)?; - // We setup signal handlers to clean up shmem segments used by state restorer - #[cfg(all(unix, not(miri)))] - if let Err(_e) = - unsafe { setup_signal_handler(addr_of_mut!(EVENTMGR_SIGHANDLER_STATE)) } - { - // We can live without a proper ctrl+c signal handler. Print and ignore. - log::error!("Failed to setup signal handlers: {_e}"); - } - let mut ctr: u64 = 0; // Client->parent loop loop { @@ -509,37 +487,48 @@ where match unsafe { fork() }? { ForkResult::Parent(handle) => { unsafe { - // The parent will later exit through is_shutting down below - // if the process exits gracefully, it cleans up the shmem. - EVENTMGR_SIGHANDLER_STATE.set_exit_from_main(); + libc::signal(libc::SIGINT, libc::SIG_IGN); } shmem_provider.post_fork(false)?; handle.status() } ForkResult::Child => { + // We setup signal handlers to clean up shmem segments used by state restorer + #[cfg(all(unix, not(miri)))] + if let Err(_e) = unsafe { + setup_signal_handler(addr_of_mut!(EVENTMGR_SIGHANDLER_STATE)) + } { + // We can live without a proper ctrl+c signal handler. Print and ignore. + log::error!("Failed to setup signal handlers: {_e}"); + } shmem_provider.post_fork(true)?; break staterestorer; } } }; - // Same, as fork version, mark this main thread as the shmem allocator - // then it will not call exit or exitprocess in the sigint handler - // so that it exits after cleaning up the shmem segments - #[cfg(all(unix, not(feature = "fork")))] + // If this guy wants to fork, then ignore sigit + #[cfg(any(windows, not(feature = "fork")))] unsafe { - EVENTMGR_SIGHANDLER_STATE.set_exit_from_main(); + #[cfg(windows)] + libafl_bolts::os::windows_exceptions::signal( + libafl_bolts::os::windows_exceptions::SIGINT, + libafl_bolts::os::windows_exceptions::sig_ign(), + ); + + #[cfg(unix)] + libc::signal(libc::SIGINT, libc::SIG_IGN); } // On Windows (or in any case without forks), we spawn ourself again #[cfg(any(windows, not(feature = "fork")))] let child_status = startable_self()?.status()?; - #[cfg(all(unix, not(feature = "fork")))] + #[cfg(any(windows, not(feature = "fork")))] let child_status = child_status.code().unwrap_or_default(); compiler_fence(Ordering::SeqCst); - if staterestorer.wants_to_exit() || Self::is_shutting_down() { + if child_status == crate::events::CTRL_C_EXIT || staterestorer.wants_to_exit() { return Err(Error::shutting_down()); } diff --git a/libafl/src/events/tcp.rs b/libafl/src/events/tcp.rs index ed98184673..0b33cfd12b 100644 --- a/libafl/src/events/tcp.rs +++ b/libafl/src/events/tcp.rs @@ -36,7 +36,7 @@ use tokio::{ use typed_builder::TypedBuilder; use super::{CustomBufEventResult, CustomBufHandlerFn}; -#[cfg(all(unix, feature = "std"))] +#[cfg(all(unix, feature = "std", not(miri)))] use crate::events::EVENTMGR_SIGHANDLER_STATE; use crate::{ events::{ @@ -1156,19 +1156,6 @@ where S: State + HasExecutions + HasMetadata, MT: Monitor + Clone, { - /// Internal function, returns true when shuttdown is requested by a `SIGINT` signal - #[inline] - #[allow(clippy::unused_self)] - fn is_shutting_down() -> bool { - #[cfg(unix)] - unsafe { - core::ptr::read_volatile(core::ptr::addr_of!(EVENTMGR_SIGHANDLER_STATE.shutting_down)) - } - - #[cfg(windows)] - false - } - /// Launch the restarting manager pub fn launch(&mut self) -> Result<(Option, TcpRestartingEventManager), Error> { // We start ourself as child process to actually fuzz @@ -1257,15 +1244,6 @@ where // Store the information to a map. staterestorer.write_to_env(_ENV_FUZZER_SENDER)?; - // We setup signal handlers to clean up shmem segments used by state restorer - #[cfg(all(unix, not(miri)))] - if let Err(_e) = - unsafe { setup_signal_handler(addr_of_mut!(EVENTMGR_SIGHANDLER_STATE)) } - { - // We can live without a proper ctrl+c signal handler. Print and ignore. - log::error!("Failed to setup signal handlers: {_e}"); - } - let mut ctr: u64 = 0; // Client->parent loop loop { @@ -1279,31 +1257,51 @@ where match unsafe { fork() }? { ForkResult::Parent(handle) => { unsafe { - EVENTMGR_SIGHANDLER_STATE.set_exit_from_main(); + libc::signal(libc::SIGINT, libc::SIG_IGN); } self.shmem_provider.post_fork(false)?; handle.status() } ForkResult::Child => { + // We setup signal handlers to clean up shmem segments used by state restorer + #[cfg(all(unix, not(miri)))] + if let Err(_e) = unsafe { + setup_signal_handler(addr_of_mut!(EVENTMGR_SIGHANDLER_STATE)) + } { + // We can live without a proper ctrl+c signal handler. Print and ignore. + log::error!("Failed to setup signal handlers: {_e}"); + } self.shmem_provider.post_fork(true)?; break (staterestorer, self.shmem_provider.clone(), core_id); } } }; - #[cfg(all(unix, not(feature = "fork")))] + // If this guy wants to fork, then ignore sigit + #[cfg(any(windows, not(feature = "fork")))] unsafe { - EVENTMGR_SIGHANDLER_STATE.set_exit_from_main(); + #[cfg(windows)] + libafl_bolts::os::windows_exceptions::signal( + libafl_bolts::os::windows_exceptions::SIGINT, + libafl_bolts::os::windows_exceptions::sig_ign(), + ); + + #[cfg(unix)] + libc::signal(libc::SIGINT, libc::SIG_IGN); } // On Windows (or in any case without fork), we spawn ourself again #[cfg(any(windows, not(feature = "fork")))] let child_status = startable_self()?.status()?; - #[cfg(all(unix, not(feature = "fork")))] + #[cfg(any(windows, not(feature = "fork")))] let child_status = child_status.code().unwrap_or_default(); compiler_fence(Ordering::SeqCst); + if child_status == crate::events::CTRL_C_EXIT || staterestorer.wants_to_exit() { + return Err(Error::shutting_down()); + } + #[allow(clippy::manual_assert)] if !staterestorer.has_content() && self.serialize_state { #[cfg(unix)] @@ -1317,10 +1315,6 @@ where panic!("Fuzzer-respawner: Storing state in crashed fuzzer instance did not work, no point to spawn the next client! This can happen if the child calls `exit()`, in that case make sure it uses `abort()`, if it got killed unrecoverable (OOM), or if there is a bug in the fuzzer itself. (Child exited with: {child_status})"); } - if staterestorer.wants_to_exit() || Self::is_shutting_down() { - return Err(Error::shutting_down()); - } - ctr = ctr.wrapping_add(1); } } else { diff --git a/libafl/src/executors/hooks/windows.rs b/libafl/src/executors/hooks/windows.rs index d5e7efadd5..660661e4ff 100644 --- a/libafl/src/executors/hooks/windows.rs +++ b/libafl/src/executors/hooks/windows.rs @@ -329,15 +329,14 @@ pub mod windows_exception_handler { let mut is_crash = true; #[cfg(feature = "std")] if let Some(exception_pointers) = exception_pointers.as_mut() { - let code = ExceptionCode::try_from( + let code: ExceptionCode = ExceptionCode::from( exception_pointers .ExceptionRecord .as_mut() .unwrap() .ExceptionCode .0, - ) - .unwrap(); + ); let exception_list = data.exceptions(); if exception_list.contains(&code) { diff --git a/libafl_bolts/src/os/mod.rs b/libafl_bolts/src/os/mod.rs index 69ff1ad954..4eaabf92a9 100644 --- a/libafl_bolts/src/os/mod.rs +++ b/libafl_bolts/src/os/mod.rs @@ -53,7 +53,7 @@ impl ChildHandle { unsafe { libc::waitpid(self.pid, &mut status, 0); } - status + libc::WEXITSTATUS(status) } } diff --git a/libafl_bolts/src/os/windows_exceptions.rs b/libafl_bolts/src/os/windows_exceptions.rs index f491e98390..9105bed5dd 100644 --- a/libafl_bolts/src/os/windows_exceptions.rs +++ b/libafl_bolts/src/os/windows_exceptions.rs @@ -11,7 +11,7 @@ use core::{ use std::os::raw::{c_long, c_void}; use log::info; -use num_enum::TryFromPrimitive; +use num_enum::FromPrimitive; pub use windows::Win32::{ Foundation::{BOOL, NTSTATUS}, System::{ @@ -94,65 +94,130 @@ pub const STATUS_SXS_EARLY_DEACTIVATION: i32 = 0xC015000F; pub const STATUS_SXS_INVALID_DEACTIVATION: i32 = 0xC0150010; pub const STATUS_NOT_IMPLEMENTED: i32 = 0xC0000002; -#[derive(Debug, TryFromPrimitive, Clone, Copy)] +// from https://github.com/x64dbg/x64dbg/blob/4d631707b89d97e199844c08f5b65d8ea5d5d3f3/bin/exceptiondb.txt +pub const STATUS_WX86_UNSIMULATE: i32 = 0x4000001C; +pub const STATUS_WX86_CONTINUE: i32 = 0x4000001D; +pub const STATUS_WX86_SINGLE_STEP: i32 = 0x4000001E; +pub const STATUS_WX86_BREAKPOINT: i32 = 0x4000001F; +pub const STATUS_WX86_EXCEPTION_CONTINUE: i32 = 0x40000020; +pub const STATUS_WX86_EXCEPTION_LASTCHANCE: i32 = 0x40000021; +pub const STATUS_WX86_EXCEPTION_CHAIN: i32 = 0x40000022; +pub const STATUS_WX86_CREATEWX86TIB: i32 = 0x40000028; +pub const DBG_TERMINATE_THREAD: i32 = 0x40010003; +pub const DBG_TERMINATE_PROCESS: i32 = 0x40010004; +pub const DBG_CONTROL_C: i32 = 0x40010005; +pub const DBG_PRINTEXCEPTION_C: i32 = 0x40010006; +pub const DBG_RIPEXCEPTION: i32 = 0x40010007; +pub const DBG_CONTROL_BREAK: i32 = 0x40010008; +pub const DBG_COMMAND_EXCEPTION: i32 = 0x40010009; +pub const DBG_PRINTEXCEPTION_WIDE_C: i32 = 0x4001000A; +pub const EXCEPTION_RO_ORIGINATEERROR: i32 = 0x40080201; +pub const EXCEPTION_RO_TRANSFORMERROR: i32 = 0x40080202; +pub const MS_VC_EXCEPTION: i32 = 0x406D1388; +pub const DBG_EXCEPTION_NOT_HANDLED: i32 = 0x80010001; +pub const STATUS_INVALID_PARAMETER: i32 = 0xC000000D; +pub const STATUS_ILLEGAL_FLOAT_CONTEXT: i32 = 0xC000014A; +pub const EXCEPTION_POSSIBLE_DEADLOCK: i32 = 0xC0000194; +pub const STATUS_INVALID_EXCEPTION_HANDLER: i32 = 0xC00001A5; +pub const STATUS_DATATYPE_MISALIGNMENT_ERROR: i32 = 0xC00002C5; +pub const STATUS_USER_CALLBACK: i32 = 0xC000041D; +pub const CLR_EXCEPTION: i32 = 0xE0434352; +pub const CPP_EH_EXCEPTION: i32 = 0xE06D7363; +pub const VCPP_EXCEPTION_ERROR_INVALID_PARAMETER: i32 = 0xC06D0057; +pub const VCPP_EXCEPTION_ERROR_MOD_NOT_FOUND: i32 = 0xC06D007E; +pub const VCPP_EXCEPTION_ERROR_PROC_NOT_FOUND: i32 = 0xC06D007F; + +#[derive(Debug, FromPrimitive, Clone, Copy)] #[repr(i32)] pub enum ExceptionCode { - // From https://docs.microsoft.com/en-us/windows/win32/debug/getexceptioncode - AccessViolation = STATUS_ACCESS_VIOLATION, - ArrayBoundsExceeded = STATUS_ARRAY_BOUNDS_EXCEEDED, - Breakpoint = STATUS_BREAKPOINT, - DatatypeMisalignment = STATUS_DATATYPE_MISALIGNMENT, - FltDenormalOperand = STATUS_FLOAT_DENORMAL_OPERAND, - FltDivideByZero = STATUS_FLOAT_DIVIDE_BY_ZERO, - FltInexactResult = STATUS_FLOAT_INEXACT_RESULT, - FltInvalidOperation = STATUS_FLOAT_INVALID_OPERATION, - FltOverflow = STATUS_FLOAT_OVERFLOW, - FltStackCheck = STATUS_FLOAT_STACK_CHECK, - FltUnderflow = STATUS_FLOAT_UNDERFLOW, + // From https://github.com/wine-mirror/wine/blob/master/include/winnt.h#L611 + WaitZero = STATUS_WAIT_0, + AbandonedWaitZero = STATUS_ABANDONED_WAIT_0, + UserApc = STATUS_USER_APC, + Timeout = STATUS_TIMEOUT, + Pending = STATUS_PENDING, + SegmentNotification = STATUS_SEGMENT_NOTIFICATION, + FatalAppExit = STATUS_FATAL_APP_EXIT, GuardPageViolation = STATUS_GUARD_PAGE_VIOLATION, - IllegalInstruction = STATUS_ILLEGAL_INSTRUCTION, + DatatypeMisalignment = STATUS_DATATYPE_MISALIGNMENT, + Breakpoint = STATUS_BREAKPOINT, + SingleStep = STATUS_SINGLE_STEP, + Longjump = STATUS_LONGJUMP, + UnwindConsolidate = STATUS_UNWIND_CONSOLIDATE, + AccessViolation = STATUS_ACCESS_VIOLATION, InPageError = STATUS_IN_PAGE_ERROR, - IntegerDivideByZero = STATUS_INTEGER_DIVIDE_BY_ZERO, - IntegerOverflow = STATUS_INTEGER_OVERFLOW, - InvalidDisposition = STATUS_INVALID_DISPOSITION, InvalidHandle = STATUS_INVALID_HANDLE, + NoMemory = STATUS_NO_MEMORY, + IllegalInstruction = STATUS_ILLEGAL_INSTRUCTION, NoncontinuableException = STATUS_NONCONTINUABLE_EXCEPTION, + InvalidDisposition = STATUS_INVALID_DISPOSITION, + ArrayBoundsExceeded = STATUS_ARRAY_BOUNDS_EXCEEDED, + FloatDenormalOperand = STATUS_FLOAT_DENORMAL_OPERAND, + FloatDivideByZero = STATUS_FLOAT_DIVIDE_BY_ZERO, + FloatInexactResult = STATUS_FLOAT_INEXACT_RESULT, + FloatInvalidOperation = STATUS_FLOAT_INVALID_OPERATION, + FloatOverflow = STATUS_FLOAT_OVERFLOW, + FloatStackCheck = STATUS_FLOAT_STACK_CHECK, + FloatUnderflow = STATUS_FLOAT_UNDERFLOW, + IntegerDivideByZero = STATUS_INTEGER_DIVIDE_BY_ZERO, + IntegerOverflow = STATUS_INTEGER_OVERFLOW, PrivilegedInstruction = STATUS_PRIVILEGED_INSTRUCTION, - SingleStep = STATUS_SINGLE_STEP, StackOverflow = STATUS_STACK_OVERFLOW, - UnwindConsolidate = STATUS_UNWIND_CONSOLIDATE, - // Addition exceptions - Wait0 = STATUS_WAIT_0, - AbandonedWait0 = STATUS_ABANDONED_WAIT_0, - UserAPC = STATUS_USER_APC, - Timeout = STATUS_TIMEOUT, - Pending = STATUS_PENDING, - SegmentNotification = STATUS_SEGMENT_NOTIFICATION, - FatalAppExit = STATUS_FATAL_APP_EXIT, - Longjump = STATUS_LONGJUMP, - DLLNotFound = STATUS_DLL_NOT_FOUND, + DllNotFound = STATUS_DLL_NOT_FOUND, OrdinalNotFound = STATUS_ORDINAL_NOT_FOUND, - EntryPointNotFound = STATUS_ENTRYPOINT_NOT_FOUND, + EntrypointNotFound = STATUS_ENTRYPOINT_NOT_FOUND, ControlCExit = STATUS_CONTROL_C_EXIT, DllInitFailed = STATUS_DLL_INIT_FAILED, - FltMultipleFaults = STATUS_FLOAT_MULTIPLE_FAULTS, - FltMultipleTraps = STATUS_FLOAT_MULTIPLE_TRAPS, + FloatMultipleFaults = STATUS_FLOAT_MULTIPLE_FAULTS, + FloatMultipleTraps = STATUS_FLOAT_MULTIPLE_TRAPS, RegNatConsumption = STATUS_REG_NAT_CONSUMPTION, HeapCorruption = STATUS_HEAP_CORRUPTION, StackBufferOverrun = STATUS_STACK_BUFFER_OVERRUN, - InvalidCRuntimeParameter = STATUS_INVALID_CRUNTIME_PARAMETER, + InvalidCruntimeParameter = STATUS_INVALID_CRUNTIME_PARAMETER, AssertionFailure = STATUS_ASSERTION_FAILURE, - SXSEarlyDeactivation = STATUS_SXS_EARLY_DEACTIVATION, - SXSInvalidDeactivation = STATUS_SXS_INVALID_DEACTIVATION, + SxsEarlyDeactivation = STATUS_SXS_EARLY_DEACTIVATION, + SxsInvalidDeactivation = STATUS_SXS_INVALID_DEACTIVATION, NotImplemented = STATUS_NOT_IMPLEMENTED, - #[num_enum(default)] - Other, + // from https://github.com/x64dbg/x64dbg/blob/4d631707b89d97e199844c08f5b65d8ea5d5d3f3/bin/exceptiondb.txt + Wx86Unsimulate = STATUS_WX86_UNSIMULATE, + Wx86Continue = STATUS_WX86_CONTINUE, + Wx86SingleStep = STATUS_WX86_SINGLE_STEP, + Wx86Breakpoint = STATUS_WX86_BREAKPOINT, + Wx86ExceptionContinue = STATUS_WX86_EXCEPTION_CONTINUE, + Wx86ExceptionLastchance = STATUS_WX86_EXCEPTION_LASTCHANCE, + Wx86ExceptionChain = STATUS_WX86_EXCEPTION_CHAIN, + Wx86Createwx86Tib = STATUS_WX86_CREATEWX86TIB, + DbgTerminateThread = DBG_TERMINATE_THREAD, + DbgTerminateProcess = DBG_TERMINATE_PROCESS, + DbgControlC = DBG_CONTROL_C, + DbgPrintexceptionC = DBG_PRINTEXCEPTION_C, + DbgRipexception = DBG_RIPEXCEPTION, + DbgControlBreak = DBG_CONTROL_BREAK, + DbgCommandException = DBG_COMMAND_EXCEPTION, + DbgPrintexceptionWideC = DBG_PRINTEXCEPTION_WIDE_C, + ExceptionRoOriginateError = EXCEPTION_RO_ORIGINATEERROR, + ExceptionRoTransformError = EXCEPTION_RO_TRANSFORMERROR, + MsVcException = MS_VC_EXCEPTION, + DbgExceptionNotHandled = DBG_EXCEPTION_NOT_HANDLED, + InvalidParameter = STATUS_INVALID_PARAMETER, + IllegalFloatContext = STATUS_ILLEGAL_FLOAT_CONTEXT, + ExceptionPossibleDeadlock = EXCEPTION_POSSIBLE_DEADLOCK, + InvalidExceptionHandler = STATUS_INVALID_EXCEPTION_HANDLER, + DatatypeMisalignmentError = STATUS_DATATYPE_MISALIGNMENT_ERROR, + UserCallback = STATUS_USER_CALLBACK, + ClrException = CLR_EXCEPTION, + CppEhException = CPP_EH_EXCEPTION, + VcppExceptionErrorInvalidParameter = VCPP_EXCEPTION_ERROR_INVALID_PARAMETER, + VcppExceptionErrorModNotFound = VCPP_EXCEPTION_ERROR_MOD_NOT_FOUND, + VcppExceptionErrorProcNotFound = VCPP_EXCEPTION_ERROR_PROC_NOT_FOUND, + #[default] + Others, } pub static CRASH_EXCEPTIONS: &[ExceptionCode] = &[ ExceptionCode::AccessViolation, ExceptionCode::ArrayBoundsExceeded, - ExceptionCode::FltDivideByZero, + ExceptionCode::FloatDivideByZero, ExceptionCode::GuardPageViolation, ExceptionCode::IllegalInstruction, ExceptionCode::InPageError, @@ -177,111 +242,181 @@ impl Eq for ExceptionCode {} unsafe impl Sync for ExceptionCode {} impl Display for ExceptionCode { - fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - ExceptionCode::AccessViolation => write!(f, "STATUS_ACCESS_VIOLATION")?, - ExceptionCode::ArrayBoundsExceeded => write!(f, "STATUS_ARRAY_BOUNDS_EXCEEDED")?, - ExceptionCode::Breakpoint => write!(f, "STATUS_BREAKPOINT")?, - ExceptionCode::DatatypeMisalignment => write!(f, "STATUS_DATATYPE_MISALIGNMENT")?, - ExceptionCode::FltDenormalOperand => write!(f, "STATUS_FLOAT_DENORMAL_OPERAND")?, - ExceptionCode::FltDivideByZero => write!(f, "STATUS_FLOAT_DIVIDE_BY_ZERO")?, - ExceptionCode::FltInexactResult => write!(f, "STATUS_FLOAT_INEXACT_RESULT")?, - ExceptionCode::FltInvalidOperation => write!(f, "STATUS_FLOAT_INVALID_OPERATION")?, - ExceptionCode::FltOverflow => write!(f, "STATUS_FLOAT_OVERFLOW")?, - ExceptionCode::FltStackCheck => write!(f, "STATUS_FLOAT_STACK_CHECK")?, - ExceptionCode::FltUnderflow => write!(f, "STATUS_FLOAT_UNDERFLOW")?, - ExceptionCode::GuardPageViolation => write!(f, "STATUS_GUARD_PAGE_VIOLATION")?, - ExceptionCode::IllegalInstruction => write!(f, "STATUS_ILLEGAL_INSTRUCTION")?, - ExceptionCode::InPageError => write!(f, "STATUS_IN_PAGE_ERROR")?, - ExceptionCode::IntegerDivideByZero => write!(f, "STATUS_INTEGER_DIVIDE_BY_ZERO")?, - ExceptionCode::IntegerOverflow => write!(f, "STATUS_INTEGER_OVERFLOW")?, - ExceptionCode::InvalidDisposition => write!(f, "STATUS_INVALID_DISPOSITION")?, - ExceptionCode::InvalidHandle => write!(f, "STATUS_INVALID_HANDLE")?, - ExceptionCode::NoncontinuableException => write!(f, "STATUS_NONCONTINUABLE_EXCEPTION")?, - ExceptionCode::PrivilegedInstruction => write!(f, "STATUS_PRIVILEGED_INSTRUCTION")?, - ExceptionCode::SingleStep => write!(f, "STATUS_SINGLE_STEP")?, - ExceptionCode::StackOverflow => write!(f, "STATUS_STACK_OVERFLOW")?, - ExceptionCode::UnwindConsolidate => write!(f, "STATUS_UNWIND_CONSOLIDATE")?, - ExceptionCode::Wait0 => write!(f, "STATUS_WAIT_0")?, - ExceptionCode::AbandonedWait0 => write!(f, "STATUS_ABANDONED_WAIT_0")?, - ExceptionCode::UserAPC => write!(f, "STATUS_USER_APC")?, - ExceptionCode::Timeout => write!(f, "STATUS_TIMEOUT")?, - ExceptionCode::Pending => write!(f, "STATUS_PENDING")?, - ExceptionCode::SegmentNotification => write!(f, "STATUS_SEGMENT_NOTIFICATION")?, - ExceptionCode::FatalAppExit => write!(f, "STATUS_FATAL_APP_EXIT")?, - ExceptionCode::Longjump => write!(f, "STATUS_LONGJUMP")?, - ExceptionCode::DLLNotFound => write!(f, "STATUS_DLL_NOT_FOUND")?, - ExceptionCode::OrdinalNotFound => write!(f, "STATUS_ORDINAL_NOT_FOUND")?, - ExceptionCode::EntryPointNotFound => write!(f, "STATUS_ENTRYPOINT_NOT_FOUND")?, - ExceptionCode::ControlCExit => write!(f, "STATUS_CONTROL_C_EXIT")?, - ExceptionCode::DllInitFailed => write!(f, "STATUS_DLL_INIT_FAILED")?, - ExceptionCode::FltMultipleFaults => write!(f, "STATUS_FLOAT_MULTIPLE_FAULTS")?, - ExceptionCode::FltMultipleTraps => write!(f, "STATUS_FLOAT_MULTIPLE_TRAPS")?, - ExceptionCode::RegNatConsumption => write!(f, "STATUS_REG_NAT_CONSUMPTION")?, - ExceptionCode::HeapCorruption => write!(f, "STATUS_HEAP_CORRUPTION")?, - ExceptionCode::StackBufferOverrun => write!(f, "STATUS_STACK_BUFFER_OVERRUN")?, - ExceptionCode::InvalidCRuntimeParameter => { - write!(f, "STATUS_INVALID_CRUNTIME_PARAMETER")?; + ExceptionCode::WaitZero => write!(f, "STATUS_WAIT_0"), + ExceptionCode::AbandonedWaitZero => write!(f, "STATUS_ABANDONED_WAIT_0"), + ExceptionCode::UserApc => write!(f, "STATUS_USER_APC"), + ExceptionCode::Timeout => write!(f, "STATUS_TIMEOUT"), + ExceptionCode::Pending => write!(f, "STATUS_PENDING"), + ExceptionCode::SegmentNotification => write!(f, "STATUS_SEGMENT_NOTIFICATION"), + ExceptionCode::FatalAppExit => write!(f, "STATUS_FATAL_APP_EXIT"), + ExceptionCode::GuardPageViolation => write!(f, "STATUS_GUARD_PAGE_VIOLATION"), + ExceptionCode::DatatypeMisalignment => write!(f, "STATUS_DATATYPE_MISALIGNMENT"), + ExceptionCode::Breakpoint => write!(f, "STATUS_BREAKPOINT"), + ExceptionCode::SingleStep => write!(f, "STATUS_SINGLE_STEP"), + ExceptionCode::Longjump => write!(f, "STATUS_LONGJUMP"), + ExceptionCode::UnwindConsolidate => write!(f, "STATUS_UNWIND_CONSOLIDATE"), + ExceptionCode::AccessViolation => write!(f, "STATUS_ACCESS_VIOLATION"), + ExceptionCode::InPageError => write!(f, "STATUS_IN_PAGE_ERROR"), + ExceptionCode::InvalidHandle => write!(f, "STATUS_INVALID_HANDLE"), + ExceptionCode::NoMemory => write!(f, "STATUS_NO_MEMORY"), + ExceptionCode::IllegalInstruction => write!(f, "STATUS_ILLEGAL_INSTRUCTION"), + ExceptionCode::NoncontinuableException => write!(f, "STATUS_NONCONTINUABLE_EXCEPTION"), + ExceptionCode::InvalidDisposition => write!(f, "STATUS_INVALID_DISPOSITION"), + ExceptionCode::ArrayBoundsExceeded => write!(f, "STATUS_ARRAY_BOUNDS_EXCEEDED"), + ExceptionCode::FloatDenormalOperand => write!(f, "STATUS_FLOAT_DENORMAL_OPERAND"), + ExceptionCode::FloatDivideByZero => write!(f, "STATUS_FLOAT_DIVIDE_BY_ZERO"), + ExceptionCode::FloatInexactResult => write!(f, "STATUS_FLOAT_INEXACT_RESULT"), + ExceptionCode::FloatInvalidOperation => write!(f, "STATUS_FLOAT_INVALID_OPERATION"), + ExceptionCode::FloatOverflow => write!(f, "STATUS_FLOAT_OVERFLOW"), + ExceptionCode::FloatStackCheck => write!(f, "STATUS_FLOAT_STACK_CHECK"), + ExceptionCode::FloatUnderflow => write!(f, "STATUS_FLOAT_UNDERFLOW"), + ExceptionCode::IntegerDivideByZero => write!(f, "STATUS_INTEGER_DIVIDE_BY_ZERO"), + ExceptionCode::IntegerOverflow => write!(f, "STATUS_INTEGER_OVERFLOW"), + ExceptionCode::PrivilegedInstruction => write!(f, "STATUS_PRIVILEGED_INSTRUCTION"), + ExceptionCode::StackOverflow => write!(f, "STATUS_STACK_OVERFLOW"), + ExceptionCode::DllNotFound => write!(f, "STATUS_DLL_NOT_FOUND"), + ExceptionCode::OrdinalNotFound => write!(f, "STATUS_ORDINAL_NOT_FOUND"), + ExceptionCode::EntrypointNotFound => write!(f, "STATUS_ENTRYPOINT_NOT_FOUND"), + ExceptionCode::ControlCExit => write!(f, "STATUS_CONTROL_C_EXIT"), + ExceptionCode::DllInitFailed => write!(f, "STATUS_DLL_INIT_FAILED"), + ExceptionCode::FloatMultipleFaults => write!(f, "STATUS_FLOAT_MULTIPLE_FAULTS"), + ExceptionCode::FloatMultipleTraps => write!(f, "STATUS_FLOAT_MULTIPLE_TRAPS"), + ExceptionCode::RegNatConsumption => write!(f, "STATUS_REG_NAT_CONSUMPTION"), + ExceptionCode::HeapCorruption => write!(f, "STATUS_HEAP_CORRUPTION"), + ExceptionCode::StackBufferOverrun => write!(f, "STATUS_STACK_BUFFER_OVERRUN"), + ExceptionCode::InvalidCruntimeParameter => { + write!(f, "STATUS_INVALID_CRUNTIME_PARAMETER") + } + ExceptionCode::AssertionFailure => write!(f, "STATUS_ASSERTION_FAILURE"), + ExceptionCode::SxsEarlyDeactivation => write!(f, "STATUS_SXS_EARLY_DEACTIVATION"), + ExceptionCode::SxsInvalidDeactivation => write!(f, "STATUS_SXS_INVALID_DEACTIVATION"), + ExceptionCode::NotImplemented => write!(f, "STATUS_NOT_IMPLEMENTED"), + ExceptionCode::Wx86Unsimulate => write!(f, "STATUS_WX86_UNSIMULATE"), + ExceptionCode::Wx86Continue => write!(f, "STATUS_WX86_CONTINUE"), + ExceptionCode::Wx86SingleStep => write!(f, "STATUS_WX86_SINGLE_STEP"), + ExceptionCode::Wx86Breakpoint => write!(f, "STATUS_WX86_BREAKPOINT"), + ExceptionCode::Wx86ExceptionContinue => write!(f, "STATUS_WX86_EXCEPTION_CONTINUE"), + ExceptionCode::Wx86ExceptionLastchance => write!(f, "STATUS_WX86_EXCEPTION_LASTCHANCE"), + ExceptionCode::Wx86ExceptionChain => write!(f, "STATUS_WX86_EXCEPTION_CHAIN"), + ExceptionCode::Wx86Createwx86Tib => write!(f, "STATUS_WX86_CREATEWX86TIB"), + ExceptionCode::DbgTerminateThread => write!(f, "DBG_TERMINATE_THREAD"), + ExceptionCode::DbgTerminateProcess => write!(f, "DBG_TERMINATE_PROCESS"), + ExceptionCode::DbgControlC => write!(f, "DBG_CONTROL_C"), + ExceptionCode::DbgPrintexceptionC => write!(f, "DBG_PRINTEXCEPTION_C"), + ExceptionCode::DbgRipexception => write!(f, "DBG_RIPEXCEPTION"), + ExceptionCode::DbgControlBreak => write!(f, "DBG_CONTROL_BREAK"), + ExceptionCode::DbgCommandException => write!(f, "DBG_COMMAND_EXCEPTION"), + ExceptionCode::DbgPrintexceptionWideC => write!(f, "DBG_PRINTEXCEPTION_WIDE_C"), + ExceptionCode::ExceptionRoOriginateError => write!(f, "EXCEPTION_RO_ORIGINATEERROR"), + ExceptionCode::ExceptionRoTransformError => write!(f, "EXCEPTION_RO_TRANSFORMERROR"), + ExceptionCode::MsVcException => write!(f, "MS_VC_EXCEPTION"), + ExceptionCode::DbgExceptionNotHandled => write!(f, "DBG_EXCEPTION_NOT_HANDLED"), + ExceptionCode::InvalidParameter => write!(f, "STATUS_INVALID_PARAMETER"), + ExceptionCode::IllegalFloatContext => write!(f, "STATUS_ILLEGAL_FLOAT_CONTEXT"), + ExceptionCode::ExceptionPossibleDeadlock => write!(f, "EXCEPTION_POSSIBLE_DEADLOCK"), + ExceptionCode::InvalidExceptionHandler => write!(f, "STATUS_INVALID_EXCEPTION_HANDLER"), + ExceptionCode::DatatypeMisalignmentError => { + write!(f, "STATUS_DATATYPE_MISALIGNMENT_ERROR") + } + ExceptionCode::UserCallback => write!(f, "STATUS_USER_CALLBACK"), + ExceptionCode::ClrException => write!(f, "CLR_EXCEPTION"), + ExceptionCode::CppEhException => write!(f, "CPP_EH_EXCEPTION"), + ExceptionCode::VcppExceptionErrorInvalidParameter => { + write!(f, "VCPP_EXCEPTION_ERROR_INVALID_PARAMETER") + } + ExceptionCode::VcppExceptionErrorModNotFound => { + write!(f, "VCPP_EXCEPTION_ERROR_MOD_NOT_FOUND") + } + ExceptionCode::VcppExceptionErrorProcNotFound => { + write!(f, "VCPP_EXCEPTION_ERROR_PROC_NOT_FOUND") } - ExceptionCode::AssertionFailure => write!(f, "STATUS_ASSERTION_FAILURE")?, - ExceptionCode::SXSEarlyDeactivation => write!(f, "STATUS_SXS_EARLY_DEACTIVATION")?, - ExceptionCode::SXSInvalidDeactivation => write!(f, "STATUS_SXS_INVALID_DEACTIVATION")?, - ExceptionCode::NotImplemented => write!(f, "STATUS_NOT_IMPLEMENTED")?, - ExceptionCode::Other => write!(f, "Other/User defined exception")?, - }; - - Ok(()) + ExceptionCode::Others => write!(f, "Unknown exception code"), + } } } -pub static EXCEPTION_CODES_MAPPING: [ExceptionCode; 47] = [ - ExceptionCode::AccessViolation, - ExceptionCode::ArrayBoundsExceeded, - ExceptionCode::Breakpoint, - ExceptionCode::DatatypeMisalignment, - ExceptionCode::FltDenormalOperand, - ExceptionCode::FltDivideByZero, - ExceptionCode::FltInexactResult, - ExceptionCode::FltInvalidOperation, - ExceptionCode::FltOverflow, - ExceptionCode::FltStackCheck, - ExceptionCode::FltUnderflow, +pub static EXCEPTION_CODES_MAPPING: [ExceptionCode; 79] = [ + ExceptionCode::WaitZero, + ExceptionCode::AbandonedWaitZero, + ExceptionCode::UserApc, + ExceptionCode::Timeout, + ExceptionCode::Pending, + ExceptionCode::SegmentNotification, + ExceptionCode::FatalAppExit, ExceptionCode::GuardPageViolation, - ExceptionCode::IllegalInstruction, + ExceptionCode::DatatypeMisalignment, + ExceptionCode::Breakpoint, + ExceptionCode::SingleStep, + ExceptionCode::Longjump, + ExceptionCode::UnwindConsolidate, + ExceptionCode::AccessViolation, ExceptionCode::InPageError, - ExceptionCode::IntegerDivideByZero, - ExceptionCode::IntegerOverflow, - ExceptionCode::InvalidDisposition, ExceptionCode::InvalidHandle, + ExceptionCode::NoMemory, + ExceptionCode::IllegalInstruction, ExceptionCode::NoncontinuableException, + ExceptionCode::InvalidDisposition, + ExceptionCode::ArrayBoundsExceeded, + ExceptionCode::FloatDenormalOperand, + ExceptionCode::FloatDivideByZero, + ExceptionCode::FloatInexactResult, + ExceptionCode::FloatInvalidOperation, + ExceptionCode::FloatOverflow, + ExceptionCode::FloatStackCheck, + ExceptionCode::FloatUnderflow, + ExceptionCode::IntegerDivideByZero, + ExceptionCode::IntegerOverflow, ExceptionCode::PrivilegedInstruction, - ExceptionCode::SingleStep, ExceptionCode::StackOverflow, - ExceptionCode::UnwindConsolidate, - ExceptionCode::Wait0, - ExceptionCode::AbandonedWait0, - ExceptionCode::UserAPC, - ExceptionCode::Timeout, - ExceptionCode::Pending, - ExceptionCode::SegmentNotification, - ExceptionCode::FatalAppExit, - ExceptionCode::Longjump, - ExceptionCode::DLLNotFound, + ExceptionCode::DllNotFound, ExceptionCode::OrdinalNotFound, - ExceptionCode::EntryPointNotFound, + ExceptionCode::EntrypointNotFound, ExceptionCode::ControlCExit, ExceptionCode::DllInitFailed, - ExceptionCode::FltMultipleFaults, - ExceptionCode::FltMultipleTraps, + ExceptionCode::FloatMultipleFaults, + ExceptionCode::FloatMultipleTraps, ExceptionCode::RegNatConsumption, ExceptionCode::HeapCorruption, ExceptionCode::StackBufferOverrun, - ExceptionCode::InvalidCRuntimeParameter, + ExceptionCode::InvalidCruntimeParameter, ExceptionCode::AssertionFailure, - ExceptionCode::SXSEarlyDeactivation, - ExceptionCode::SXSInvalidDeactivation, + ExceptionCode::SxsEarlyDeactivation, + ExceptionCode::SxsInvalidDeactivation, ExceptionCode::NotImplemented, - ExceptionCode::Other, + ExceptionCode::Wx86Unsimulate, + ExceptionCode::Wx86Continue, + ExceptionCode::Wx86SingleStep, + ExceptionCode::Wx86Breakpoint, + ExceptionCode::Wx86ExceptionContinue, + ExceptionCode::Wx86ExceptionLastchance, + ExceptionCode::Wx86ExceptionChain, + ExceptionCode::Wx86Createwx86Tib, + ExceptionCode::DbgTerminateThread, + ExceptionCode::DbgTerminateProcess, + ExceptionCode::DbgControlC, + ExceptionCode::DbgPrintexceptionC, + ExceptionCode::DbgRipexception, + ExceptionCode::DbgControlBreak, + ExceptionCode::DbgCommandException, + ExceptionCode::DbgPrintexceptionWideC, + ExceptionCode::ExceptionRoOriginateError, + ExceptionCode::ExceptionRoTransformError, + ExceptionCode::MsVcException, + ExceptionCode::DbgExceptionNotHandled, + ExceptionCode::InvalidParameter, + ExceptionCode::IllegalFloatContext, + ExceptionCode::ExceptionPossibleDeadlock, + ExceptionCode::InvalidExceptionHandler, + ExceptionCode::DatatypeMisalignmentError, + ExceptionCode::UserCallback, + ExceptionCode::ClrException, + ExceptionCode::CppEhException, + ExceptionCode::VcppExceptionErrorInvalidParameter, + ExceptionCode::VcppExceptionErrorModNotFound, + ExceptionCode::VcppExceptionErrorProcNotFound, + ExceptionCode::Others, ]; #[cfg(feature = "alloc")] @@ -361,17 +496,23 @@ pub unsafe extern "system" fn handle_exception( .as_mut() .unwrap() .ExceptionCode; - let exception_code = match ExceptionCode::try_from(code.0) { - Ok(x) => x, - Err(_) => ExceptionCode::Other, - }; + let exception_code = From::from(code.0); log::info!("Received exception; code: {}", exception_code); internal_handle_exception(exception_code, exception_pointers) } +/// Return `SIGIGN` this is 1 (when represented as u64) +/// Check `https://github.com/ziglang/zig/blob/956f53beb09c07925970453d4c178c6feb53ba70/lib/libc/include/any-windows-any/signal.h#L51` +/// # Safety +/// It is just casting into another type, nothing unsafe. +#[must_use] +pub const unsafe fn sig_ign() -> NativeSignalHandlerType { + core::mem::transmute(1u64) +} + type NativeSignalHandlerType = unsafe extern "C" fn(i32); extern "C" { - fn signal(signum: i32, func: NativeSignalHandlerType) -> *const c_void; + pub fn signal(signum: i32, func: NativeSignalHandlerType) -> *const c_void; } unsafe extern "C" fn handle_signal(_signum: i32) {