1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (C) 2026 Google LLC. 3 4 //! Binder debugging helpers. 5 6 #![allow(dead_code)] 7 8 use kernel::bits::bit_u32; 9 use kernel::sync::atomic::Atomic; 10 11 kernel::impl_flags!( 12 /// Represents multiple debug mask flags. 13 #[derive(Debug, Clone, Default, Copy, PartialEq, Eq)] 14 pub struct DebugMasks(u32); 15 16 /// Represents a single debug mask category. 17 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 18 pub enum DebugMask { 19 UserError = bit_u32(0), 20 FailedTransaction = bit_u32(1), 21 DeadTransaction = bit_u32(2), 22 OpenClose = bit_u32(3), 23 DeadBinder = bit_u32(4), 24 DeathNotification = bit_u32(5), 25 ReadWrite = bit_u32(6), 26 UserRefs = bit_u32(7), 27 Threads = bit_u32(8), 28 Transaction = bit_u32(9), 29 TransactionComplete = bit_u32(10), 30 FreeBuffer = bit_u32(11), 31 InternalRefs = bit_u32(12), 32 PriorityCap = bit_u32(13), 33 Spinlocks = bit_u32(14), 34 } 35 ); 36 37 #[no_mangle] 38 pub(crate) static rust_binder_debug_mask: Atomic<u32> = Atomic::new( 39 (DebugMask::UserError as u32) 40 | (DebugMask::FailedTransaction as u32) 41 | (DebugMask::DeadTransaction as u32), 42 ); 43 44 /// Checks if the given debug logging category is enabled in the mask. 45 pub(crate) fn debug_mask_enabled(mask: DebugMask) -> bool { 46 let current_mask = rust_binder_debug_mask.load(kernel::sync::atomic::Relaxed); 47 DebugMasks(current_mask).contains(mask) 48 } 49 50 /// Prints a debug log if the specified mask category is enabled. 51 #[macro_export] 52 macro_rules! binder_debug { 53 // Rule to explicitly specify a PID (used in kworkers). 54 (pid=$pid:expr, $mask:ident, $($arg:tt)*) => { 55 if $crate::debug::debug_mask_enabled($crate::debug::DebugMask::$mask) { 56 kernel::pr_info!( 57 "{}: {}\n", 58 $pid, 59 kernel::prelude::fmt!($($arg)*) 60 ); 61 } 62 }; 63 64 // Default rule (automatically prepends "PID:TID" of the current calling thread). 65 ($mask:ident, $($arg:tt)*) => { 66 if $crate::debug::debug_mask_enabled($crate::debug::DebugMask::$mask) { 67 let thread = kernel::current!(); 68 kernel::pr_info!( 69 "{}:{} {}\n", 70 thread.tgid(), 71 thread.pid(), 72 kernel::prelude::fmt!($($arg)*) 73 ); 74 } 75 }; 76 } 77