use std::cell::Cell;
thread_local! {
static DEBUG_SESSION_ACTIVE: Cell<bool> = const { Cell::new(false) };
static WARNED_LOAD_BYPASS: Cell<bool> = const { Cell::new(false) };
}
pub fn set_debug_session_active(active: bool) {
DEBUG_SESSION_ACTIVE.with(|c| c.set(active));
if active {
WARNED_LOAD_BYPASS.with(|c| c.set(false));
}
}
pub fn is_debug_session_active() -> bool {
DEBUG_SESSION_ACTIVE.with(|c| c.get())
}
pub fn warn_load_bypass_once(form: &str, path: &str) {
if !is_debug_session_active() {
return;
}
let already = WARNED_LOAD_BYPASS.with(|c| c.replace(true));
if already {
return;
}
sema_core::write_stderr(&format!(
"Debugger: code reached via ({form} \"{path}\") is not stepped by the \
debugger (it runs outside the attached debug session), so breakpoints \
set in dynamically loaded or imported files are not hit. Stepping the \
main program is unaffected. (This warning is shown once per debug \
session.)\n"
));
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::{Arc, Mutex};
fn capture_stderr(f: impl FnOnce()) -> String {
let buf = Arc::new(Mutex::new(String::new()));
let buf_hook = buf.clone();
sema_core::set_stderr_hook(Some(Box::new(move |s: &str| {
buf_hook.lock().unwrap().push_str(s);
})));
f();
sema_core::set_stderr_hook(None);
let out = buf.lock().unwrap().clone();
out
}
#[test]
fn no_warning_when_session_inactive() {
set_debug_session_active(false);
let out = capture_stderr(|| {
warn_load_bypass_once("load", "helpers.sema");
});
assert!(out.is_empty(), "should not warn outside a debug session");
}
#[test]
fn warns_once_per_session() {
set_debug_session_active(true);
let out = capture_stderr(|| {
warn_load_bypass_once("load", "helpers.sema");
warn_load_bypass_once("import", "other.sema");
});
assert!(out.contains("not stepped by the debugger"));
assert!(out.contains("helpers.sema"));
assert!(!out.contains("other.sema"));
set_debug_session_active(true);
let out2 = capture_stderr(|| {
warn_load_bypass_once("import", "again.sema");
});
assert!(out2.contains("again.sema"));
set_debug_session_active(false);
}
}