#![allow(clippy::disallowed_macros)] use std::{any::Any, env, panic, sync::LazyLock}; // Export debug proc_macros pub use conduwuit_macros::recursion_depth; use tracing::Level; // Export all of the ancillary tools from here as well. pub use crate::{result::DebugInspect, utils::debug::*}; /// Log event at given level in debug-mode (when debug-assertions are enabled). /// In release-mode it becomes DEBUG level, and possibly subject to elision. #[macro_export] macro_rules! debug_event { ( $level:expr_2021, $($x:tt)+ ) => { if $crate::debug::logging() { ::tracing::event!( $level, _debug = true, $($x)+ ) } else { ::tracing::debug!( $($x)+ ) } } } /// Log message at the ERROR level in debug-mode (when debug-assertions are /// enabled). In release-mode it becomes DEBUG level, and possibly subject to /// elision. #[macro_export] macro_rules! debug_error { ( $($x:tt)+ ) => { $crate::debug_event!(::tracing::Level::ERROR, $($x)+ ) } } /// Log message at the WARN level in debug-mode (when debug-assertions are /// enabled). In release-mode it becomes DEBUG level, and possibly subject to /// elision. #[macro_export] macro_rules! debug_warn { ( $($x:tt)+ ) => { $crate::debug_event!(::tracing::Level::WARN, $($x)+ ) } } /// Log message at the INFO level in debug-mode (when debug-assertions are /// enabled). In release-mode it becomes DEBUG level, and possibly subject to /// elision. #[macro_export] macro_rules! debug_info { ( $($x:tt)+ ) => { $crate::debug_event!(::tracing::Level::INFO, $($x)+ ) } } pub const INFO_SPAN_LEVEL: Level = if cfg!(debug_assertions) { Level::INFO } else { Level::DEBUG }; pub static DEBUGGER: LazyLock = LazyLock::new(|| env::var("_").unwrap_or_default().ends_with("gdb")); #[cfg_attr(debug_assertions, crate::ctor)] #[cfg_attr(not(debug_assertions), allow(dead_code))] fn set_panic_trap() { if !*DEBUGGER { return; } let next = panic::take_hook(); panic::set_hook(Box::new(move |info| { panic_handler(info, &next); })); } #[cold] #[inline(never)] #[allow(deprecated_in_future)] pub fn panic_handler(info: &panic::PanicHookInfo<'_>, next: &dyn Fn(&panic::PanicHookInfo<'_>)) { trap(); next(info); } #[inline(always)] pub fn trap() { #[cfg(core_intrinsics)] //SAFETY: embeds llvm intrinsic for hardware breakpoint unsafe { std::intrinsics::breakpoint(); } #[cfg(all(not(core_intrinsics), target_arch = "x86_64"))] //SAFETY: embeds instruction for hardware breakpoint unsafe { std::arch::asm!("int3"); } } #[must_use] pub fn panic_str(p: &Box) -> &'static str { p.downcast_ref::<&str>().copied().unwrap_or_default() } #[inline(always)] #[must_use] pub fn rttype_name(_: &T) -> &'static str { type_name::() } #[inline(always)] #[must_use] pub fn type_name() -> &'static str { std::any::type_name::() } #[must_use] #[inline] pub const fn logging() -> bool { cfg!(debug_assertions) }