Fix Ctrl-C Handler (#2124)
* fix * fix * win * win clp * a * FMT * aaaaaaaaaaa * aa --------- Co-authored-by: Your Name <you@example.com>
This commit is contained in:
parent
61ac4ea7be
commit
b23180394b
@ -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<S>, LlmpRestartingEventManager<EMH, S, SP>), 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 {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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<S>, TcpRestartingEventManager<EMH, S, SP>), 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 {
|
||||
|
@ -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) {
|
||||
|
@ -53,7 +53,7 @@ impl ChildHandle {
|
||||
unsafe {
|
||||
libc::waitpid(self.pid, &mut status, 0);
|
||||
}
|
||||
status
|
||||
libc::WEXITSTATUS(status)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
GuardPageViolation = STATUS_GUARD_PAGE_VIOLATION,
|
||||
IllegalInstruction = STATUS_ILLEGAL_INSTRUCTION,
|
||||
InPageError = STATUS_IN_PAGE_ERROR,
|
||||
IntegerDivideByZero = STATUS_INTEGER_DIVIDE_BY_ZERO,
|
||||
IntegerOverflow = STATUS_INTEGER_OVERFLOW,
|
||||
InvalidDisposition = STATUS_INVALID_DISPOSITION,
|
||||
InvalidHandle = STATUS_INVALID_HANDLE,
|
||||
NoncontinuableException = STATUS_NONCONTINUABLE_EXCEPTION,
|
||||
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,
|
||||
// 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,
|
||||
DatatypeMisalignment = STATUS_DATATYPE_MISALIGNMENT,
|
||||
Breakpoint = STATUS_BREAKPOINT,
|
||||
SingleStep = STATUS_SINGLE_STEP,
|
||||
Longjump = STATUS_LONGJUMP,
|
||||
DLLNotFound = STATUS_DLL_NOT_FOUND,
|
||||
UnwindConsolidate = STATUS_UNWIND_CONSOLIDATE,
|
||||
AccessViolation = STATUS_ACCESS_VIOLATION,
|
||||
InPageError = STATUS_IN_PAGE_ERROR,
|
||||
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,
|
||||
StackOverflow = STATUS_STACK_OVERFLOW,
|
||||
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::Other => write!(f, "Other/User defined exception")?,
|
||||
};
|
||||
|
||||
Ok(())
|
||||
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::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,
|
||||
ExceptionCode::GuardPageViolation,
|
||||
ExceptionCode::IllegalInstruction,
|
||||
ExceptionCode::InPageError,
|
||||
ExceptionCode::IntegerDivideByZero,
|
||||
ExceptionCode::IntegerOverflow,
|
||||
ExceptionCode::InvalidDisposition,
|
||||
ExceptionCode::InvalidHandle,
|
||||
ExceptionCode::NoncontinuableException,
|
||||
ExceptionCode::PrivilegedInstruction,
|
||||
ExceptionCode::SingleStep,
|
||||
ExceptionCode::StackOverflow,
|
||||
ExceptionCode::UnwindConsolidate,
|
||||
ExceptionCode::Wait0,
|
||||
ExceptionCode::AbandonedWait0,
|
||||
ExceptionCode::UserAPC,
|
||||
pub static EXCEPTION_CODES_MAPPING: [ExceptionCode; 79] = [
|
||||
ExceptionCode::WaitZero,
|
||||
ExceptionCode::AbandonedWaitZero,
|
||||
ExceptionCode::UserApc,
|
||||
ExceptionCode::Timeout,
|
||||
ExceptionCode::Pending,
|
||||
ExceptionCode::SegmentNotification,
|
||||
ExceptionCode::FatalAppExit,
|
||||
ExceptionCode::GuardPageViolation,
|
||||
ExceptionCode::DatatypeMisalignment,
|
||||
ExceptionCode::Breakpoint,
|
||||
ExceptionCode::SingleStep,
|
||||
ExceptionCode::Longjump,
|
||||
ExceptionCode::DLLNotFound,
|
||||
ExceptionCode::UnwindConsolidate,
|
||||
ExceptionCode::AccessViolation,
|
||||
ExceptionCode::InPageError,
|
||||
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::StackOverflow,
|
||||
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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user