165 lines · 5.0 KB · Rust
RawDownload
// SPDX-License-Identifier: Apache-2.0 OR MIT //! The contents of this file come from the Rust standard library, hosted in//! the <https://github.com/rust-lang/rust> repository, licensed under//! "Apache-2.0 OR MIT" and adapted for kernel use. For copyright details,//! see <https://github.com/rust-lang/rust/blob/master/COPYRIGHT>. /// [`std::dbg`], but using [`pr_info`] instead of [`eprintln`].////// Prints and returns the value of a given expression for quick and dirty/// debugging.////// An example:////// ```rust/// let a = 2;/// # #[allow(clippy::dbg_macro)]/// let b = dbg!(a * 2) + 1;/// //      ^-- prints: [src/main.rs:2] a * 2 = 4/// assert_eq!(b, 5);/// ```////// The macro works by using the `Debug` implementation of the type of/// the given expression to print the value with [`printk`] along with the/// source location of the macro invocation as well as the source code/// of the expression.////// Invoking the macro on an expression moves and takes ownership of it/// before returning the evaluated expression unchanged. If the type/// of the expression does not implement `Copy` and you don't want/// to give up ownership, you can instead borrow with `dbg!(&expr)`/// for some expression `expr`.////// The `dbg!` macro works exactly the same in release builds./// This is useful when debugging issues that only occur in release/// builds or when debugging in release mode is significantly faster.////// Note that the macro is intended as a temporary debugging tool to be/// used during development. Therefore, avoid committing `dbg!` macro/// invocations into the kernel tree.////// For debug output that is intended to be kept in the kernel tree,/// use [`pr_debug`] and similar facilities instead.////// # Stability////// The exact output printed by this macro should not be relied upon/// and is subject to future changes.////// # Further examples////// With a method call:////// ```rust/// # #[allow(clippy::dbg_macro)]/// fn foo(n: usize) {///     if dbg!(n.checked_sub(4)).is_some() {///         // ...///     }/// }////// foo(3)/// ```////// This prints to the kernel log:////// ```text,ignore/// [src/main.rs:4] n.checked_sub(4) = None/// ```////// Naive factorial implementation:////// ```rust/// # #[allow(clippy::dbg_macro)]/// # {/// fn factorial(n: u32) -> u32 {///     if dbg!(n <= 1) {///         dbg!(1)///     } else {///         dbg!(n * factorial(n - 1))///     }/// }////// dbg!(factorial(4));/// # }/// ```////// This prints to the kernel log:////// ```text,ignore/// [src/main.rs:3] n <= 1 = false/// [src/main.rs:3] n <= 1 = false/// [src/main.rs:3] n <= 1 = false/// [src/main.rs:3] n <= 1 = true/// [src/main.rs:4] 1 = 1/// [src/main.rs:5] n * factorial(n - 1) = 2/// [src/main.rs:5] n * factorial(n - 1) = 6/// [src/main.rs:5] n * factorial(n - 1) = 24/// [src/main.rs:11] factorial(4) = 24/// ```////// The `dbg!(..)` macro moves the input:////// ```ignore/// /// A wrapper around `usize` which importantly is not Copyable./// #[derive(Debug)]/// struct NoCopy(usize);////// let a = NoCopy(42);/// let _ = dbg!(a); // <-- `a` is moved here./// let _ = dbg!(a); // <-- `a` is moved again; error!/// ```////// You can also use `dbg!()` without a value to just print the/// file and line whenever it's reached.////// Finally, if you want to `dbg!(..)` multiple values, it will treat them as/// a tuple (and return it, too):////// ```/// # #[allow(clippy::dbg_macro)]/// assert_eq!(dbg!(1usize, 2u32), (1, 2));/// ```////// However, a single argument with a trailing comma will still not be treated/// as a tuple, following the convention of ignoring trailing commas in macro/// invocations. You can use a 1-tuple directly if you need one:////// ```/// # #[allow(clippy::dbg_macro)]/// # {/// assert_eq!(1, dbg!(1u32,)); // trailing comma ignored/// assert_eq!((1,), dbg!((1u32,))); // 1-tuple/// # }/// ```////// [`std::dbg`]: https://doc.rust-lang.org/std/macro.dbg.html/// [`eprintln`]: https://doc.rust-lang.org/std/macro.eprintln.html/// [`printk`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html/// [`pr_info`]: crate::pr_info!/// [`pr_debug`]: crate::pr_debug!#[macro_export]macro_rules! dbg {    // NOTE: We cannot use `concat!` to make a static string as a format argument    // of `pr_info!` because `file!` could contain a `{` or    // `$val` expression could be a block (`{ .. }`), in which case the `pr_info!`    // will be malformed.    () => {        $crate::pr_info!("[{}:{}]\n", ::core::file!(), ::core::line!())    };    ($val:expr $(,)?) => {        // Use of `match` here is intentional because it affects the lifetimes        // of temporaries - https://stackoverflow.com/a/48732525/1063961        match $val {            tmp => {                $crate::pr_info!("[{}:{}] {} = {:#?}\n",                    ::core::file!(), ::core::line!(), ::core::stringify!($val), &tmp);                tmp            }        }    };    ($($val:expr),+ $(,)?) => {        ($($crate::dbg!($val)),+,)    };}