#![cfg_attr(feature = "cargo-clippy", allow(inline_always))]
#[derive(Debug, Copy, Clone, Hash, PartialEq)]
pub enum DebugtrapError {
CannotImplement,
NotImplementedYet,
DebuggerMightNotBeAttached,
NonDebugBuild,
}
use DebugtrapError::*;
use std::fmt::{self, Display, Formatter};
use std::error::Error;
impl Display for DebugtrapError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for DebugtrapError {
fn description(&self) -> &'static str {
match *self {
CannotImplement => "This target currently provides no way to check if a debugger is attached",
NotImplementedYet => "Not implemented yet! Contributions are welcome",
DebuggerMightNotBeAttached => "Can't prove that a debugger is attached to this process",
NonDebugBuild => "Requested to trap only for debug builds",
}
}
}
pub fn debugger_is_attached() -> Result<(), DebugtrapError> {
Err(NotImplementedYet)
}
#[inline(always)]
pub fn debugtrap_checked() -> Result<(), DebugtrapError> {
if let Err(e) = debugger_is_attached() {
Err(e)
} else {
debugtrap();
Ok(())
}
}
#[cfg(debug_assertions)]
#[inline(always)]
pub fn debugbuild_trap_checked() -> Result<(), DebugtrapError> {
debugtrap_checked()
}
#[cfg(not(debug_assertions))]
#[inline(always)]
pub fn debugbuild_trap_checked() -> Result<(), DebugtrapError> {
Err(NonDebugBuild)
}
#[cfg(not(debug_assertions))]
#[inline(always)]
pub fn debugbuild_trap() {}
#[cfg(debug_assertions)]
#[inline(always)]
pub fn debugbuild_trap() {
debugtrap()
}
#[inline(always)]
pub fn debugtrap() {
unsafe {
llvm_debugtrap()
}
}
#[cfg(debug_assertions)]
#[inline(always)]
pub fn debugbuild_trap_or_else<F: Fn()>(_: F) {
debugtrap()
}
#[cfg(not(debug_assertions))]
#[inline(always)]
pub fn debugbuild_trap_or_else<F: Fn()>(f: F) {
f()
}
extern {
#[inline(always)]
#[link_name = "llvm.debugtrap"]
fn llvm_debugtrap();
}