Skip to main content

starry_kernel/
dyn_debug.rs

1use ax_memory_addr::VirtAddr;
2use ax_task::current;
3use ddebug::{ControlFile, DebugOps};
4pub struct DynamicDebugOps;
5
6impl DebugOps for DynamicDebugOps {
7    fn write_kernel_text(addr: *mut u8, data: &[u8]) {
8        crate::mm::write_kernel_text(VirtAddr::from_mut_ptr_of(addr), data)
9            .expect("Failed to write kernel text");
10    }
11
12    fn emit(line: &str) {
13        ax_print!("{}", line);
14    }
15
16    fn thread_id() -> u64 {
17        current().id().as_u64()
18    }
19}
20
21/// Dynamic debug macro. When `dynamic_debug` feature is enabled,
22/// uses per-callsite static key for runtime control via `/proc/dynamic_debug/control`.
23/// Otherwise falls back to `log::debug!`.
24///
25/// # Note
26/// This macro doesn't depend on the derive macro `#[ddebug::named]`, so the 'f' flag can't be used to print the function name.
27#[cfg(feature = "dynamic_debug")]
28#[macro_export]
29macro_rules! debug {
30    ($fmt:literal $(, $arg:expr)* $(,)?) => {{
31        ddebug::pr_debug!($crate::dyn_debug::DynamicDebugOps, $fmt $(, $arg)*);
32    }};
33}
34
35/// Dynamic debug macro. When `dynamic_debug` feature is enabled,
36/// uses per-callsite static key for runtime control via `/proc/dynamic_debug/control`, and also prints the function name of the callsite.
37/// Otherwise falls back to `log::debug!`.
38///
39/// # Note
40/// This macro depends on the derive macro `#[ddebug::named]` to work, which will set the function name for the debug site.
41#[cfg(feature = "dynamic_debug")]
42#[macro_export]
43macro_rules! debug_fn {
44    ($fmt:literal $(, $arg:expr)* $(,)?) => {{
45        ddebug::pr_debug_fn!($crate::dyn_debug::DynamicDebugOps, $fmt $(, $arg)*);
46    }};
47}
48
49/// When `dynamic_debug` feature is disabled, `debug!` and `debug_fn!` both fall back to `log::debug!`.
50#[cfg(not(feature = "dynamic_debug"))]
51#[macro_export]
52macro_rules! debug_fn {
53    ($fmt:literal $(, $arg:expr)* $(,)?) => {{
54        ax_log::debug!($fmt $(, $arg)*);
55    }};
56}
57
58/// Initialize dynamic debug subsystem.
59/// This should be called after static keys are initialized, and before any dynamic debug site is hit.
60pub fn dynamic_debug_init() -> ControlFile<DynamicDebugOps> {
61    info!("debug_init: initializing dynamic debug sites");
62    let ctl = ddebug::dynamic_debug_init::<DynamicDebugOps>();
63    let site_count = ctl.site_count();
64    info!("debug_init: found {site_count} dynamic debug sites");
65    ctl
66}