1use std::{any::Any, env, panic, sync::LazyLock};
2
3use tracing::Level;
4pub use tuwunel_macros::recursion_depth;
6
7pub use crate::{result::DebugInspect, utils::debug::*};
9
10#[macro_export]
13#[collapse_debuginfo(yes)]
14macro_rules! debug_event {
15 ( $level:expr_2021, $($x:tt)+ ) => {
16 if $crate::debug::logging() {
17 ::tracing::event!( $level, _debug = true, $($x)+ )
18 } else {
19 ::tracing::debug!( $($x)+ )
20 }
21 }
22}
23
24#[macro_export]
28macro_rules! debug_error {
29 ( $($x:tt)+ ) => {
30 $crate::debug_event!(::tracing::Level::ERROR, $($x)+ )
31 }
32}
33
34#[macro_export]
38macro_rules! debug_warn {
39 ( $($x:tt)+ ) => {
40 $crate::debug_event!(::tracing::Level::WARN, $($x)+ )
41 }
42}
43
44#[macro_export]
48macro_rules! debug_info {
49 ( $($x:tt)+ ) => {
50 $crate::debug_event!(::tracing::Level::INFO, $($x)+ )
51 }
52}
53
54pub const INFO_SPAN_LEVEL: Level = if logging() { Level::INFO } else { Level::DEBUG };
55
56pub static DEBUGGER: LazyLock<bool> =
57 LazyLock::new(|| env::var("_").unwrap_or_default().ends_with("gdb"));
58
59#[cfg_attr(debug_assertions, crate::ctor)]
60#[cfg_attr(not(debug_assertions), allow(dead_code))]
61fn set_panic_trap() {
62 if !*DEBUGGER {
63 return;
64 }
65
66 let next = panic::take_hook();
67 panic::set_hook(Box::new(move |info| {
68 panic_handler(info, &next);
69 }));
70}
71
72#[cold]
73#[inline(never)]
74pub fn panic_handler(info: &panic::PanicHookInfo<'_>, next: &dyn Fn(&panic::PanicHookInfo<'_>)) {
75 trap();
76 next(info);
77}
78
79#[inline(always)]
80pub fn trap() {
81 #[cfg(core_intrinsics)]
82 unsafe {
84 std::intrinsics::breakpoint();
85 }
86
87 #[cfg(all(not(core_intrinsics), target_arch = "x86_64"))]
88 unsafe {
90 std::arch::asm!("int3");
91 }
92}
93
94#[must_use]
95pub fn panic_str(p: &Box<dyn Any + Send + 'static>) -> &'static str {
96 (**p)
97 .downcast_ref::<&str>()
98 .copied()
99 .unwrap_or_default()
100}
101
102#[inline(always)]
103#[must_use]
104pub fn rttype_name<T: ?Sized>(_: &T) -> &'static str { type_name::<T>() }
105
106#[inline(always)]
107#[must_use]
108pub fn type_name<T: ?Sized>() -> &'static str { std::any::type_name::<T>() }
109
110#[must_use]
115#[inline]
116pub const fn logging() -> bool {
117 cfg!(debug_assertions)
118 || cfg!(tuwunel_debug_logging)
119 || !cfg!(feature = "release_max_log_level")
120}