Skip to content

Commit a351fa1

Browse files
authored
Merge pull request #20 from greymattergames/fix/debugger
Debugger presence detection
2 parents 2d01832 + 268c599 commit a351fa1

File tree

8 files changed

+80
-49
lines changed

8 files changed

+80
-49
lines changed

.vscode/launch.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
"args": [
1010
"build",
1111
"--bin=unbug_basic_example",
12-
"--package=unbug_basic_example",
13-
"--features=dev_debug"
12+
"--package=unbug_basic_example"
1413
],
1514
"filter": {
1615
"name": "unbug_basic_example",

.vscode/tasks.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
"command": "build",
77
"args": [
88
"--bin=unbug_basic_example",
9-
"--package=unbug_basic_example",
10-
"--features=dev_debug"
9+
"--package=unbug_basic_example"
1110
],
1211
"problemMatcher": [
1312
"$rustc"

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,19 @@ documentation = "https://docs.rs/unbug"
88
license = "MIT OR Apache-2.0"
99
keywords = ["debug", "debugging", "ensure", "assert", "breakpoint"]
1010
authors = [
11-
"Brian Jesse <[email protected]>",
11+
"Brian Jesse <[email protected]>",
12+
"Scott Girton <[email protected]>",
1213
]
1314
categories = ["development-tools::debugging"]
1415
exclude = [".vscode/", "assets/"]
1516

16-
[features]
17-
default = []
18-
enable = []
19-
2017
[dependencies]
2118
tracing = "0.1"
19+
dbg_breakpoint = "0.1.1"
20+
21+
[features]
22+
default = []
23+
no_cache_debugger = []
2224

2325
[[example]]
2426
name = "basic"

examples/basic/.vscode/launch.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
"args": [
1010
"build",
1111
"--bin=unbug_basic_example",
12-
"--package=unbug_basic_example",
13-
"--features=dev_debug"
12+
"--package=unbug_basic_example"
1413
],
1514
"filter": {
1615
"name": "unbug_basic_example",

examples/basic/.vscode/tasks.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
"command": "build",
77
"args": [
88
"--bin=unbug_basic_example",
9-
"--package=unbug_basic_example",
10-
"--features=dev_debug"
9+
"--package=unbug_basic_example"
1110
],
1211
"problemMatcher": [
1312
"$rustc"

examples/basic/Cargo.toml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@ version = "1.0.0"
44
edition = "2021"
55
publish = false
66

7-
[features]
8-
default = []
9-
dev_debug = [
10-
"unbug/enable"
11-
]
12-
137
[dependencies]
148
unbug = { path = "../../" }
159
tracing-subscriber = "0.3"

src/lib.rs

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#![doc = include_str!("../README.md")]
22

3+
// mod debugger;
4+
35
#[doc(hidden)]
46
pub mod _internal {
57

@@ -23,6 +25,34 @@ pub mod _internal {
2325
// macro_export will move the macro to the root module, thus it is necessary to use `super::` here
2426
#[doc(hidden)]
2527
pub use super::_internal_once as _once;
28+
29+
#[cfg(not(feature = "no_cache_debugger"))]
30+
pub fn _is_debugger_present() -> bool {
31+
use ::core::sync::atomic::{AtomicBool, Ordering};
32+
33+
static DEBUGGER_CHECKED: AtomicBool = AtomicBool::new(false);
34+
static DEBUGGER_ATTACHED: AtomicBool = AtomicBool::new(false);
35+
36+
if !DEBUGGER_CHECKED.swap(true, Ordering::Relaxed) {
37+
DEBUGGER_ATTACHED.swap(check_debugger(), Ordering::Relaxed);
38+
}
39+
40+
DEBUGGER_ATTACHED.load(Ordering::Relaxed)
41+
}
42+
#[cfg(feature = "no_cache_debugger")]
43+
pub fn _is_debugger_present() -> bool {
44+
check_debugger()
45+
}
46+
47+
fn check_debugger() -> bool {
48+
use ::dbg_breakpoint::{is_debugger_present, DebuggerPresence};
49+
50+
let Some(DebuggerPresence::Detected) = is_debugger_present() else {
51+
return false;
52+
};
53+
54+
true
55+
}
2656
}
2757

2858
/// When enabled, will pause execution with a break point
@@ -35,50 +65,43 @@ pub mod _internal {
3565
/// unbug::breakpoint!();
3666
/// ```
3767
#[macro_export]
38-
#[cfg(not(all(debug_assertions, feature = "enable")))]
68+
#[cfg(not(debug_assertions))]
3969
macro_rules! breakpoint {
4070
() => {};
4171
}
4272
#[macro_export]
43-
#[cfg(all(
44-
any(target_arch = "x86", target_arch = "x86_64"),
45-
debug_assertions,
46-
feature = "enable"
47-
))]
73+
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), debug_assertions))]
4874
macro_rules! breakpoint {
4975
() => {
50-
unsafe {
51-
::core::arch::asm!("int3;nop");
76+
if $crate::_internal::_is_debugger_present() {
77+
unsafe {
78+
::core::arch::asm!("int3;nop");
79+
}
5280
}
5381
};
5482
}
5583
#[macro_export]
56-
#[cfg(all(
57-
target_arch = "aarch64",
58-
debug_assertions,
59-
feature = "enable"
60-
))]
84+
#[cfg(all(target_arch = "aarch64", debug_assertions))]
6185
macro_rules! breakpoint {
6286
() => {
63-
unsafe {
64-
::core::arch::asm!("brk#0xF000\nnop");
87+
if $crate::_internal::_is_debugger_present() {
88+
unsafe {
89+
::core::arch::asm!("brk#0xF000\nnop");
90+
}
6591
}
6692
};
6793
}
6894
#[macro_export]
6995
#[cfg(all(
70-
not(any(
71-
target_arch = "x86",
72-
target_arch = "x86_64",
73-
target_arch = "aarch64",
74-
)),
75-
debug_assertions,
76-
feature = "enable"
96+
not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64",)),
97+
debug_assertions
7798
))]
7899
macro_rules! breakpoint {
79100
() => {
80-
unsafe {
81-
::core::arch::breakpoint();
101+
if $crate::_internal::_is_debugger_present() {
102+
unsafe {
103+
::core::arch::breakpoint();
104+
}
82105
}
83106
};
84107
}
@@ -99,13 +122,13 @@ macro_rules! breakpoint {
99122
/// unbug::ensure_always!(false, "a formatted message to log {:?}", some_var);
100123
/// ```
101124
#[macro_export]
102-
#[cfg(not(all(debug_assertions, feature = "enable")))]
125+
#[cfg(not(debug_assertions))]
103126
macro_rules! ensure_always {
104127
($expression: expr) => {};
105128
($expression: expr, $($argument: tt),+ $(,)?) => {};
106129
}
107130
#[macro_export]
108-
#[cfg(all(debug_assertions, feature = "enable"))]
131+
#[cfg(debug_assertions)]
109132
macro_rules! ensure_always {
110133
($expression: expr) => {
111134
if !$expression {
@@ -136,13 +159,13 @@ macro_rules! ensure_always {
136159
/// unbug::ensure!(false, "a formatted message to log {:?}", some_var);
137160
/// ```
138161
#[macro_export]
139-
#[cfg(not(all(debug_assertions, feature = "enable")))]
162+
#[cfg(not(debug_assertions))]
140163
macro_rules! ensure {
141164
($expression: expr) => {};
142165
($expression: expr, $($argument: tt),+ $(,)?) => {};
143166
}
144167
#[macro_export]
145-
#[cfg(all(debug_assertions, feature = "enable"))]
168+
#[cfg(debug_assertions)]
146169
macro_rules! ensure {
147170
($expression: expr) => {
148171
if !$expression {
@@ -178,14 +201,14 @@ macro_rules! ensure {
178201
/// unbug::fail_always!("failed to do something: {:?}", some_var);
179202
/// ```
180203
#[macro_export]
181-
#[cfg(not(all(debug_assertions, feature = "enable")))]
204+
#[cfg(not(debug_assertions))]
182205
macro_rules! fail_always {
183206
($($argument: tt),+ $(,)?) => {
184207
$crate::_internal::_error!($($argument),+);
185208
};
186209
}
187210
#[macro_export]
188-
#[cfg(all(debug_assertions, feature = "enable"))]
211+
#[cfg(debug_assertions)]
189212
macro_rules! fail_always {
190213
($($argument: tt),+ $(,)?) => {
191214
$crate::_internal::_error!($($argument),+);

0 commit comments

Comments
 (0)