Skip to main content

starry_kernel/
dyn_debug.rs

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