The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH 0/7] rust_binder : Implement dynamic debug logging mask
@ 2026-07-03 15:29 Jahnavi MN via B4 Relay
  2026-07-03 15:29 ` [PATCH 1/7] rust_binder: Add " Jahnavi MN via B4 Relay
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Jahnavi MN via B4 Relay @ 2026-07-03 15:29 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
	Christian Brauner, Carlos Llamas, Alice Ryhl, Miguel Ojeda,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Trevor Gross, Danilo Krummrich, Daniel Almeida,
	Tamir Duberstein, Alexandre Courbot, Onur Özkan
  Cc: linux-kernel, rust-for-linux, Jahnavi MN

Why we implemented this feature : 

While working with and testing the Rust implementation of the Binder 
driver (rust_binder), we realized that diagnosing transaction failures 
and protocol errors was extremely difficult. When a user-space application 
sends malformed data or makes a lifecycle mistake, the driver rejects it 
with a generic error code (like `-EINVAL`). Without internal logs, the 
driver acts as a "black box," forcing developers to guess which check 
failed.

In the legacy C Binder driver, this issue is solved using a dynamic 
`debug_mask` module parameter that toggles verbose logs for specific 
subsystems. This series brings the same critical capability to the Rust 
Binder driver to provide developers with clear, real-time feedback.

How this helps and simplifies debugging : 
Instead of rebuilds, reboots, or guessing:
- Developers can enable logs instantly on a running device by writing to 
  `/sys/module/rust_binder/parameters/debug_mask`.
- It prints the exact reason for failures (such as alignment errors, 
  mismatched call stacks, or invalid handle references) directly into 
  `dmesg`, reducing debugging time from hours to seconds.
- It protects system logs by keeping logging off by default and only 
  enabling it when developers are actively troubleshooting.

Code development approach : 
We built this system in a structured, progressive approach:
1. Infrastructure Bridging (C/Rust FFI) :
   Because the Rust `module!` macro cannot yet declare parameters, we 
   declared `debug_mask` in a C companion file and linked to it in Rust via 
   FFI. We used volatile memory reads to ensure changes to the mask are 
   detected instantly at runtime.
   
2. Verification Setup :
   We created a `binder_debug!` macro and instrumented process `open`, 
   `flush`, and `release` calls under the `BINDER_DEBUG_OPEN_CLOSE` mask. 
   These low-frequency events allowed us to verify the setup without log 
   flooding.
   
3. Targeted Instrumentation :
   We then systematically added detailed logs across 3 major categories:
   - User Error : Captures API misuse like misaligned FD arrays, 
     negative reference count transitions, and invalid death/freeze 
     notifications.
   - Failed Transaction : Dumps a complete diagnostics log on 
     transaction errors (IDs, PIDs, sizes, OOM states, and line numbers).
   - Dead Transaction : Logs in-flight cancellations, aborted 
     replies, and notification cleanups when processes exit prematurely.

Signed-off-by: Jahnavi MN <jahnavimn@google.com>
---
Jahnavi MN (7):
      rust_binder: Add dynamic debug logging mask
      rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for freezer-related operation
      rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for reference counting and death notification operations
      rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for transaction parsing and protocol validation failures
      rust_binder: Implement the BINDER_DEBUG_FAILED_TRANSACTION logging mask for transaction parsing and routing failures
      rust_binder: Implement BINDER_DEBUG_FAILED_TRANSACTION logging for death notification allocation failures
      rust_binder: Implement the BINDER_DEBUG_DEAD_TRANSACTION logging mask to trace in-flight cancellations during teardown

 drivers/android/binder/debug.rs            |  49 ++++++++++
 drivers/android/binder/freeze.rs           |  57 ++++++++---
 drivers/android/binder/node.rs             |  24 ++++-
 drivers/android/binder/process.rs          |  71 +++++++++++---
 drivers/android/binder/rust_binder_main.rs |  11 ++-
 drivers/android/binder/rust_binderfs.c     |   3 +
 drivers/android/binder/thread.rs           | 147 +++++++++++++++++++++++++----
 drivers/android/binder/transaction.rs      |  16 +++-
 8 files changed, 328 insertions(+), 50 deletions(-)
---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 20260702-rust_binder_debug_mask-636737015624

Best regards,
-- 
Jahnavi MN <jahnavimn@google.com>



^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/7] rust_binder: Add dynamic debug logging mask
  2026-07-03 15:29 [PATCH 0/7] rust_binder : Implement dynamic debug logging mask Jahnavi MN via B4 Relay
@ 2026-07-03 15:29 ` Jahnavi MN via B4 Relay
  2026-07-03 16:23   ` Gary Guo
  2026-07-04 21:03   ` Alice Ryhl
  2026-07-03 15:29 ` [PATCH 2/7] rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for freezer-related operation Jahnavi MN via B4 Relay
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 12+ messages in thread
From: Jahnavi MN via B4 Relay @ 2026-07-03 15:29 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
	Christian Brauner, Carlos Llamas, Alice Ryhl, Miguel Ojeda,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Trevor Gross, Danilo Krummrich, Daniel Almeida,
	Tamir Duberstein, Alexandre Courbot, Onur Özkan
  Cc: linux-kernel, rust-for-linux, Jahnavi MN

From: Jahnavi MN <jahnavimn@google.com>

Implement a dynamic debug logging mask (`debug_mask`) for the
`rust_binder` module to allow dynamic runtime configuration of log
levels. This enables parity with the legacy C driver's debug mask.

Since the Rust `module!` macro in the current kernel build does not yet
support declaring module parameters directly in Rust, we define the
`debug_mask` variable in a C companion file to expose it to the kernel
runtime and import it using FFI with volatile reads.

To verify the setup, instrument process lifecycle events (open, flush,
and release) in `process.rs` under the new `BINDER_DEBUG_OPEN_CLOSE`
logging mask. These entry-point events are chosen for initial validation
because they represent the start of the Binder lifecycle and occur
at low frequency, allowing simple runtime verification of the dynamic
toggle without log noise.

Signed-off-by: Jahnavi MN <jahnavimn@google.com>
---
 drivers/android/binder/debug.rs            | 49 ++++++++++++++++++++++++++++++
 drivers/android/binder/process.rs          | 15 +++++++--
 drivers/android/binder/rust_binder_main.rs |  2 ++
 drivers/android/binder/rust_binderfs.c     |  3 ++
 drivers/android/binder/thread.rs           |  1 +
 drivers/android/binder/transaction.rs      |  5 +--
 6 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/drivers/android/binder/debug.rs b/drivers/android/binder/debug.rs
new file mode 100644
index 000000000000..5e4daa823377
--- /dev/null
+++ b/drivers/android/binder/debug.rs
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0
+
+// Copyright (C) 2026 Google LLC.
+
+//! Binder debugging helpers.
+
+#![allow(dead_code)]
+
+pub(crate) const BINDER_DEBUG_USER_ERROR: u32 = 1 << 0;
+pub(crate) const BINDER_DEBUG_FAILED_TRANSACTION: u32 = 1 << 1;
+pub(crate) const BINDER_DEBUG_DEAD_TRANSACTION: u32 = 1 << 2;
+pub(crate) const BINDER_DEBUG_OPEN_CLOSE: u32 = 1 << 3;
+pub(crate) const BINDER_DEBUG_DEAD_BINDER: u32 = 1 << 4;
+pub(crate) const BINDER_DEBUG_DEATH_NOTIFICATION: u32 = 1 << 5;
+pub(crate) const BINDER_DEBUG_READ_WRITE: u32 = 1 << 6;
+pub(crate) const BINDER_DEBUG_USER_REFS: u32 = 1 << 7;
+pub(crate) const BINDER_DEBUG_THREADS: u32 = 1 << 8;
+pub(crate) const BINDER_DEBUG_TRANSACTION: u32 = 1 << 9;
+pub(crate) const BINDER_DEBUG_TRANSACTION_COMPLETE: u32 = 1 << 10;
+pub(crate) const BINDER_DEBUG_FREE_BUFFER: u32 = 1 << 11;
+pub(crate) const BINDER_DEBUG_INTERNAL_REFS: u32 = 1 << 12;
+pub(crate) const BINDER_DEBUG_PRIORITY_CAP: u32 = 1 << 13;
+pub(crate) const BINDER_DEBUG_SPINLOCKS: u32 = 1 << 14;
+
+extern "C" {
+    static rust_binder_debug_mask: u32;
+}
+
+/// Checks if the given debug logging category is enabled in the mask.
+pub(crate) fn debug_mask_enabled(mask: u32) -> bool {
+    let ptr = &raw const rust_binder_debug_mask;
+    // SAFETY: `rust_binder_debug_mask` is defined in the companion C code linked in the module.
+    let current_mask = unsafe { core::ptr::read_volatile(ptr) };
+    (current_mask & mask) != 0
+}
+
+/// Prints a debug log if the specified mask category is enabled.
+#[macro_export]
+macro_rules! binder_debug {
+    ($mask:expr, $fmt:literal $(, $($arg:tt)*)?) => {
+        if $crate::debug::debug_mask_enabled($mask) {
+            kernel::pr_info!(
+                "{}: {}\n",
+                kernel::current!().pid(),
+                format_args!($fmt $(, $($arg)*)?)
+            );
+        }
+    };
+}
diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs
index 96b8440ceac6..c13a04a3afcb 100644
--- a/drivers/android/binder/process.rs
+++ b/drivers/android/binder/process.rs
@@ -898,7 +898,6 @@ pub(crate) fn insert_or_update_handle(
     }
 
     pub(crate) fn get_transaction_node(&self, handle: u32) -> BinderResult<NodeRef> {
-        // When handle is zero, try to get the context manager.
         if handle == 0 {
             Ok(self.ctx.get_manager_node(true)?)
         } else {
@@ -1314,6 +1313,11 @@ pub(crate) fn lock_with_nodes(&self) -> WithNodes<'_> {
     }
 
     fn deferred_flush(&self) {
+        binder_debug!(
+            crate::debug::BINDER_DEBUG_OPEN_CLOSE,
+            "binder_flush: process {}",
+            self.pid_in_current_ns()
+        );
         let inner = self.inner.lock();
         for thread in inner.threads.values() {
             thread.exit_looper();
@@ -1321,6 +1325,11 @@ fn deferred_flush(&self) {
     }
 
     fn deferred_release(self: Arc<Self>) {
+        binder_debug!(
+            crate::debug::BINDER_DEBUG_OPEN_CLOSE,
+            "binder_deferred_release: process {}",
+            self.pid_in_current_ns()
+        );
         let is_manager = {
             let mut inner = self.inner.lock();
             inner.is_dead = true;
@@ -1616,7 +1625,9 @@ fn ioctl_write_read(
 /// The file operations supported by `Process`.
 impl Process {
     pub(crate) fn open(ctx: ArcBorrow<'_, Context>, file: &File) -> Result<Arc<Process>> {
-        Self::new(ctx.into(), ARef::from(file.cred()))
+        let proc = Self::new(ctx.into(), ARef::from(file.cred()))?;
+        binder_debug!(crate::debug::BINDER_DEBUG_OPEN_CLOSE, "opened process");
+        Ok(proc)
     }
 
     pub(crate) fn release(this: Arc<Process>, _file: &File) {
diff --git a/drivers/android/binder/rust_binder_main.rs b/drivers/android/binder/rust_binder_main.rs
index dc1941cd2407..bf15021524a4 100644
--- a/drivers/android/binder/rust_binder_main.rs
+++ b/drivers/android/binder/rust_binder_main.rs
@@ -37,6 +37,8 @@
 mod context;
 mod deferred_close;
 mod defs;
+#[macro_use]
+mod debug;
 mod error;
 mod node;
 mod page_range;
diff --git a/drivers/android/binder/rust_binderfs.c b/drivers/android/binder/rust_binderfs.c
index ade1c4d92499..fa8b38465550 100644
--- a/drivers/android/binder/rust_binderfs.c
+++ b/drivers/android/binder/rust_binderfs.c
@@ -51,6 +51,9 @@ DEFINE_SHOW_ATTRIBUTE(rust_binder_proc);
 char *rust_binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES;
 module_param_named(rust_devices, rust_binder_devices_param, charp, 0444);
 
+u32 rust_binder_debug_mask = 7;
+module_param_named(debug_mask, rust_binder_debug_mask, uint, 0644);
+
 static dev_t binderfs_dev;
 static DEFINE_MUTEX(binderfs_minors_mutex);
 static DEFINE_IDA(binderfs_minors);
diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs
index 97d5f31e8fe3..c908dde5796a 100644
--- a/drivers/android/binder/thread.rs
+++ b/drivers/android/binder/thread.rs
@@ -1222,6 +1222,7 @@ fn read_transaction_info(
         info.buffers_size = td.buffers_size as usize;
         // SAFETY: Above `read` call initializes all bytes, so this union read is ok.
         info.target_handle = unsafe { td.transaction_data.target.handle };
+        info.debug_id = super::next_debug_id();
         Ok(())
     }
 
diff --git a/drivers/android/binder/transaction.rs b/drivers/android/binder/transaction.rs
index 1d9b66920a21..f9285eb93fc0 100644
--- a/drivers/android/binder/transaction.rs
+++ b/drivers/android/binder/transaction.rs
@@ -42,6 +42,7 @@ pub(crate) struct TransactionInfo {
     pub(crate) reply: u32,
     pub(crate) oneway_spam_suspect: bool,
     pub(crate) is_reply: bool,
+    pub(crate) debug_id: usize,
 }
 
 impl TransactionInfo {
@@ -93,7 +94,7 @@ pub(crate) fn new(
         from: &Arc<Thread>,
         info: &mut TransactionInfo,
     ) -> BinderResult<DLArc<Self>> {
-        let debug_id = super::next_debug_id();
+        let debug_id = info.debug_id;
         let allow_fds = node_ref.node.flags & FLAT_BINDER_FLAG_ACCEPTS_FDS != 0;
         let txn_security_ctx = node_ref.node.flags & FLAT_BINDER_FLAG_TXN_SECURITY_CTX != 0;
         let mut txn_security_ctx_off = if txn_security_ctx { Some(0) } else { None };
@@ -152,7 +153,7 @@ pub(crate) fn new_reply(
         info: &mut TransactionInfo,
         allow_fds: bool,
     ) -> BinderResult<DLArc<Self>> {
-        let debug_id = super::next_debug_id();
+        let debug_id = info.debug_id;
         let mut alloc =
             match from.copy_transaction_data(to.clone(), info, debug_id, allow_fds, None) {
                 Ok(alloc) => alloc,

-- 
2.55.0.rc0.799.gd6f94ed593-goog



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/7] rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for freezer-related operation
  2026-07-03 15:29 [PATCH 0/7] rust_binder : Implement dynamic debug logging mask Jahnavi MN via B4 Relay
  2026-07-03 15:29 ` [PATCH 1/7] rust_binder: Add " Jahnavi MN via B4 Relay
@ 2026-07-03 15:29 ` Jahnavi MN via B4 Relay
  2026-07-03 15:29 ` [PATCH 3/7] rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for reference counting and death notification operations Jahnavi MN via B4 Relay
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Jahnavi MN via B4 Relay @ 2026-07-03 15:29 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
	Christian Brauner, Carlos Llamas, Alice Ryhl, Miguel Ojeda,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Trevor Gross, Danilo Krummrich, Daniel Almeida,
	Tamir Duberstein, Alexandre Courbot, Onur Özkan
  Cc: linux-kernel, rust-for-linux, Jahnavi MN

From: Jahnavi MN <jahnavimn@google.com>

This adds dynamic debug logs for:
- Requesting freeze notifications on invalid references, duplicate
  cookies, or already active registrations.
- Completing freeze notifications that are not pending or not found.
- Clearing freeze notifications on invalid references, inactive
  notifications, or cookie mismatches.

Signed-off-by: Jahnavi MN <jahnavimn@google.com>
---
 drivers/android/binder/freeze.rs | 49 ++++++++++++++++++++++++++++++++--------
 1 file changed, 39 insertions(+), 10 deletions(-)

diff --git a/drivers/android/binder/freeze.rs b/drivers/android/binder/freeze.rs
index 53b60035639a..d0559ed308ef 100644
--- a/drivers/android/binder/freeze.rs
+++ b/drivers/android/binder/freeze.rs
@@ -176,11 +176,18 @@ pub(crate) fn request_freeze_notif(
         let mut node_refs_guard = self.node_refs.lock();
         let node_refs = &mut *node_refs_guard;
         let Some(info) = node_refs.by_handle.get_mut(&handle) else {
-            pr_warn!("BC_REQUEST_FREEZE_NOTIFICATION invalid ref {}\n", handle);
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "BC_REQUEST_FREEZE_NOTIFICATION invalid ref {}",
+                handle
+            );
             return Err(EINVAL);
         };
         if info.freeze().is_some() {
-            pr_warn!("BC_REQUEST_FREEZE_NOTIFICATION already set\n");
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "BC_REQUEST_FREEZE_NOTIFICATION already set"
+            );
             return Err(EINVAL);
         }
         let node_ref = info.node_ref();
@@ -188,7 +195,10 @@ pub(crate) fn request_freeze_notif(
 
         if let rbtree::Entry::Occupied(ref dupe) = freeze_entry {
             if !dupe.get().allow_duplicate(&node_ref.node) {
-                pr_warn!("BC_REQUEST_FREEZE_NOTIFICATION duplicate cookie\n");
+                binder_debug!(
+                    crate::debug::BINDER_DEBUG_USER_ERROR,
+                    "BC_REQUEST_FREEZE_NOTIFICATION duplicate cookie"
+                );
                 return Err(EINVAL);
             }
         }
@@ -238,7 +248,11 @@ pub(crate) fn freeze_notif_done(self: &Arc<Self>, reader: &mut UserSliceReader)
         let mut node_refs_guard = self.node_refs.lock();
         let node_refs = &mut *node_refs_guard;
         let Some(freeze) = node_refs.freeze_listeners.get_mut(&cookie) else {
-            pr_warn!("BC_FREEZE_NOTIFICATION_DONE {:016x} not found\n", cookie.0);
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "BC_FREEZE_NOTIFICATION_DONE {:016x} not found",
+                cookie.0
+            );
             return Err(EINVAL);
         };
         let mut clear_msg = None;
@@ -248,8 +262,9 @@ pub(crate) fn freeze_notif_done(self: &Arc<Self>, reader: &mut UserSliceReader)
             freeze.num_cleared_duplicates += 1;
         } else {
             if !freeze.is_pending {
-                pr_warn!(
-                    "BC_FREEZE_NOTIFICATION_DONE {:016x} not pending\n",
+                binder_debug!(
+                    crate::debug::BINDER_DEBUG_USER_ERROR,
+                    "BC_FREEZE_NOTIFICATION_DONE {:016x} not pending",
                     cookie.0
                 );
                 return Err(EINVAL);
@@ -277,19 +292,33 @@ pub(crate) fn clear_freeze_notif(self: &Arc<Self>, reader: &mut UserSliceReader)
         let mut node_refs_guard = self.node_refs.lock();
         let node_refs = &mut *node_refs_guard;
         let Some(info) = node_refs.by_handle.get_mut(&handle) else {
-            pr_warn!("BC_CLEAR_FREEZE_NOTIFICATION invalid ref {}\n", handle);
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "BC_CLEAR_FREEZE_NOTIFICATION invalid ref {}",
+                handle
+            );
             return Err(EINVAL);
         };
         let Some(info_cookie) = info.freeze() else {
-            pr_warn!("BC_CLEAR_FREEZE_NOTIFICATION freeze notification not active\n");
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "BC_CLEAR_FREEZE_NOTIFICATION freeze notification not active"
+            );
             return Err(EINVAL);
         };
         if *info_cookie != cookie {
-            pr_warn!("BC_CLEAR_FREEZE_NOTIFICATION freeze notification cookie mismatch\n");
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "BC_CLEAR_FREEZE_NOTIFICATION freeze notification cookie mismatch"
+            );
             return Err(EINVAL);
         }
         let Some(listener) = node_refs.freeze_listeners.get_mut(&cookie) else {
-            pr_warn!("BC_CLEAR_FREEZE_NOTIFICATION invalid cookie {}\n", handle);
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "BC_CLEAR_FREEZE_NOTIFICATION invalid cookie {}",
+                handle
+            );
             return Err(EINVAL);
         };
         listener.is_clearing = true;

-- 
2.55.0.rc0.799.gd6f94ed593-goog



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/7] rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for reference counting and death notification operations
  2026-07-03 15:29 [PATCH 0/7] rust_binder : Implement dynamic debug logging mask Jahnavi MN via B4 Relay
  2026-07-03 15:29 ` [PATCH 1/7] rust_binder: Add " Jahnavi MN via B4 Relay
  2026-07-03 15:29 ` [PATCH 2/7] rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for freezer-related operation Jahnavi MN via B4 Relay
@ 2026-07-03 15:29 ` Jahnavi MN via B4 Relay
  2026-07-04 21:14   ` Alice Ryhl
  2026-07-03 15:29 ` [PATCH 4/7] rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for transaction parsing and protocol validation failures Jahnavi MN via B4 Relay
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Jahnavi MN via B4 Relay @ 2026-07-03 15:29 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
	Christian Brauner, Carlos Llamas, Alice Ryhl, Miguel Ojeda,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Trevor Gross, Danilo Krummrich, Daniel Almeida,
	Tamir Duberstein, Alexandre Courbot, Onur Özkan
  Cc: linux-kernel, rust-for-linux, Jahnavi MN

From: Jahnavi MN <jahnavimn@google.com>

This adds dynamic debug logs for:
- Decrementing handle reference counts that are already zero.
- Mismatched reference states (calling inc_ref_done with no active
  inc_refs, or using a weak reference as a strong reference).
- Requesting or clearing death notifications on invalid references,
  already active notifications, or with mismatched cookies.

Signed-off-by: Jahnavi MN <jahnavimn@google.com>
---
 drivers/android/binder/node.rs    | 16 +++++++++---
 drivers/android/binder/process.rs | 53 +++++++++++++++++++++++++++++++--------
 2 files changed, 55 insertions(+), 14 deletions(-)

diff --git a/drivers/android/binder/node.rs b/drivers/android/binder/node.rs
index 69f757ff7461..d71f55739772 100644
--- a/drivers/android/binder/node.rs
+++ b/drivers/android/binder/node.rs
@@ -343,7 +343,10 @@ pub(crate) fn inc_ref_done_locked(
     ) -> Option<DLArc<Node>> {
         let inner = self.inner.access_mut(owner_inner);
         if inner.active_inc_refs == 0 {
-            pr_err!("inc_ref_done called when no active inc_refs");
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "inc_ref_done called when no active inc_refs"
+            );
             return None;
         }
 
@@ -818,6 +821,10 @@ pub(crate) fn get_count(&self) -> (usize, usize) {
 
     pub(crate) fn clone(&self, strong: bool) -> Result<NodeRef> {
         if strong && self.strong_count == 0 {
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "tried to use weak ref as strong ref"
+            );
             return Err(EINVAL);
         }
         Ok(self
@@ -858,9 +865,10 @@ pub(crate) fn update(&mut self, inc: bool, strong: bool) -> bool {
             *count += 1;
         } else {
             if *count == 0 {
-                pr_warn!(
-                    "pid {} performed invalid decrement on ref\n",
-                    kernel::current!().pid()
+                binder_debug!(
+                    crate::debug::BINDER_DEBUG_USER_ERROR,
+                    "performed invalid decrement on ref (strong: {})",
+                    strong
                 );
                 return false;
             }
diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs
index c13a04a3afcb..db929cc35585 100644
--- a/drivers/android/binder/process.rs
+++ b/drivers/android/binder/process.rs
@@ -898,10 +898,23 @@ pub(crate) fn insert_or_update_handle(
     }
 
     pub(crate) fn get_transaction_node(&self, handle: u32) -> BinderResult<NodeRef> {
-        if handle == 0 {
-            Ok(self.ctx.get_manager_node(true)?)
+        // When handle is zero, try to get the context manager.
+        let res = if handle == 0 {
+            self.ctx.get_manager_node(true)
         } else {
-            Ok(self.get_node_from_handle(handle, true)?)
+            self.get_node_from_handle(handle, true).map_err(Into::into)
+        };
+
+        match res {
+            Ok(node_ref) => Ok(node_ref),
+            Err(err) => {
+                binder_debug!(
+                    crate::debug::BINDER_DEBUG_USER_ERROR,
+                    "got transaction to invalid handle {}",
+                    handle
+                );
+                Err(err)
+            }
         }
     }
 
@@ -969,10 +982,13 @@ pub(crate) fn update_ref(
                     }
                 }
             }
-        } else {
             // All refs are cleared in process exit, so this warning is expected in that case.
             if !self.inner.lock().is_dead {
-                pr_warn!("{}: no such ref {handle}\n", self.pid_in_current_ns());
+                binder_debug!(
+                    crate::debug::BINDER_DEBUG_USER_ERROR,
+                    "no such ref {}",
+                    handle
+                );
             }
         }
         Ok(())
@@ -1225,13 +1241,20 @@ pub(crate) fn request_death(
         })?;
         let mut refs = self.node_refs.lock();
         let Some(info) = refs.by_handle.get_mut(&handle) else {
-            pr_warn!("BC_REQUEST_DEATH_NOTIFICATION invalid ref {handle}\n");
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "BC_REQUEST_DEATH_NOTIFICATION invalid ref {}",
+                handle
+            );
             return Ok(());
         };
 
         // Nothing to do if there is already a death notification request for this handle.
         if info.death().is_some() {
-            pr_warn!("BC_REQUEST_DEATH_NOTIFICATION death notification already set\n");
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "BC_REQUEST_DEATH_NOTIFICATION death notification already set"
+            );
             return Ok(());
         }
 
@@ -1268,17 +1291,27 @@ pub(crate) fn clear_death(&self, reader: &mut UserSliceReader, thread: &Thread)
 
         let mut refs = self.node_refs.lock();
         let Some(info) = refs.by_handle.get_mut(&handle) else {
-            pr_warn!("BC_CLEAR_DEATH_NOTIFICATION invalid ref {handle}\n");
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "BC_CLEAR_DEATH_NOTIFICATION invalid ref {}",
+                handle
+            );
             return Ok(());
         };
 
         let Some(death) = info.death().take() else {
-            pr_warn!("BC_CLEAR_DEATH_NOTIFICATION death notification not active\n");
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "BC_CLEAR_DEATH_NOTIFICATION death notification not active"
+            );
             return Ok(());
         };
         if death.cookie != cookie {
             *info.death() = Some(death);
-            pr_warn!("BC_CLEAR_DEATH_NOTIFICATION death notification cookie mismatch\n");
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "BC_CLEAR_DEATH_NOTIFICATION death notification cookie mismatch"
+            );
             return Ok(());
         }
 

-- 
2.55.0.rc0.799.gd6f94ed593-goog



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/7] rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for transaction parsing and protocol validation failures
  2026-07-03 15:29 [PATCH 0/7] rust_binder : Implement dynamic debug logging mask Jahnavi MN via B4 Relay
                   ` (2 preceding siblings ...)
  2026-07-03 15:29 ` [PATCH 3/7] rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for reference counting and death notification operations Jahnavi MN via B4 Relay
@ 2026-07-03 15:29 ` Jahnavi MN via B4 Relay
  2026-07-03 15:29 ` [PATCH 5/7] rust_binder: Implement the BINDER_DEBUG_FAILED_TRANSACTION logging mask for transaction parsing and routing failures Jahnavi MN via B4 Relay
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Jahnavi MN via B4 Relay @ 2026-07-03 15:29 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
	Christian Brauner, Carlos Llamas, Alice Ryhl, Miguel Ojeda,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Trevor Gross, Danilo Krummrich, Daniel Almeida,
	Tamir Duberstein, Alexandre Courbot, Onur Özkan
  Cc: linux-kernel, rust-for-linux, Jahnavi MN

From: Jahnavi MN <jahnavimn@google.com>

This adds dynamic debug logs in `thread.rs` for:
- File descriptor array (FDA) parent offset and parent buffer address
  alignment misalignments.
- Memory copy, write, and translation failures during transaction
  serialization (including out-of-bounds pointer fixups).
- Incoming transactions or replies that do not match the expected
  thread calling stack (such as out-of-order replies).

Signed-off-by: Jahnavi MN <jahnavimn@google.com>
---
 drivers/android/binder/thread.rs | 88 +++++++++++++++++++++++++++++++++-------
 1 file changed, 73 insertions(+), 15 deletions(-)

diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs
index c908dde5796a..ecf05cebcb3e 100644
--- a/drivers/android/binder/thread.rs
+++ b/drivers/android/binder/thread.rs
@@ -721,11 +721,12 @@ fn translate_object(
                 let alloc_offset = match sg_state.unused_buffer_space.claim_next(obj_length) {
                     Ok(alloc_offset) => alloc_offset,
                     Err(err) => {
-                        pr_warn!(
-                            "Failed to claim space for a BINDER_TYPE_PTR. (offset: {}, limit: {}, size: {})",
+                        binder_debug!(
+                            crate::debug::BINDER_DEBUG_USER_ERROR,
+                            "failed to claim space for a BINDER_TYPE_PTR (offset: {}, limit: {}, size: {})",
                             sg_state.unused_buffer_space.offset,
                             sg_state.unused_buffer_space.limit,
-                            obj_length,
+                            obj_length
                         );
                         return Err(err.into());
                     }
@@ -804,6 +805,10 @@ fn translate_object(
                 let fds_len = num_fds.checked_mul(size_of::<u32>()).ok_or(EINVAL)?;
 
                 if !is_aligned(parent_offset, size_of::<u32>()) {
+                    binder_debug!(
+                        crate::debug::BINDER_DEBUG_USER_ERROR,
+                        "FDA parent offset not aligned correctly"
+                    );
                     return Err(EINVAL.into());
                 }
 
@@ -822,6 +827,10 @@ fn translate_object(
                 };
 
                 if !is_aligned(parent_entry.sender_uaddr, size_of::<u32>()) {
+                    binder_debug!(
+                        crate::debug::BINDER_DEBUG_USER_ERROR,
+                        "FDA parent buffer not aligned correctly"
+                    );
                     return Err(EINVAL.into());
                 }
 
@@ -905,8 +914,9 @@ fn apply_sg(&self, alloc: &mut Allocation, sg_state: &mut ScatterGatherState) ->
 
                 let target_offset_end = fixup_offset.checked_add(fixup_len).ok_or(EINVAL)?;
                 if fixup_offset < end_of_previous_fixup || offset_end < target_offset_end {
-                    pr_warn!(
-                        "Fixups oob {} {} {} {}",
+                    binder_debug!(
+                        crate::debug::BINDER_DEBUG_USER_ERROR,
+                        "fixups oob {} {} {} {}",
                         fixup_offset,
                         end_of_previous_fixup,
                         offset_end,
@@ -918,18 +928,31 @@ fn apply_sg(&self, alloc: &mut Allocation, sg_state: &mut ScatterGatherState) ->
                 let copy_off = end_of_previous_fixup;
                 let copy_len = fixup_offset - end_of_previous_fixup;
                 if let Err(err) = alloc.copy_into(&mut reader, copy_off, copy_len) {
-                    pr_warn!("Failed copying into alloc: {:?}", err);
+                    binder_debug!(
+                        crate::debug::BINDER_DEBUG_USER_ERROR,
+                        "failed copying into alloc: {:?}",
+                        err
+                    );
                     return Err(err.into());
                 }
                 if let PointerFixupEntry::Fixup { pointer_value, .. } = fixup {
                     let res = alloc.write::<u64>(fixup_offset, pointer_value);
                     if let Err(err) = res {
-                        pr_warn!("Failed copying ptr into alloc: {:?}", err);
+                        binder_debug!(
+                            crate::debug::BINDER_DEBUG_USER_ERROR,
+                            "failed copying ptr into alloc: {:?}",
+                            err
+                        );
                         return Err(err.into());
                     }
                 }
                 if let Err(err) = reader.skip(fixup_len) {
-                    pr_warn!("Failed skipping {} from reader: {:?}", fixup_len, err);
+                    binder_debug!(
+                        crate::debug::BINDER_DEBUG_USER_ERROR,
+                        "failed skipping {} from reader: {:?}",
+                        fixup_len,
+                        err
+                    );
                     return Err(err.into());
                 }
                 end_of_previous_fixup = target_offset_end;
@@ -937,7 +960,11 @@ fn apply_sg(&self, alloc: &mut Allocation, sg_state: &mut ScatterGatherState) ->
             let copy_off = end_of_previous_fixup;
             let copy_len = offset_end - end_of_previous_fixup;
             if let Err(err) = alloc.copy_into(&mut reader, copy_off, copy_len) {
-                pr_warn!("Failed copying remainder into alloc: {:?}", err);
+                binder_debug!(
+                    crate::debug::BINDER_DEBUG_USER_ERROR,
+                    "failed copying remainder into alloc: {:?}",
+                    err
+                );
                 return Err(err.into());
             }
         }
@@ -1041,7 +1068,10 @@ pub(crate) fn copy_transaction_data(
                 let offset: usize = offset.try_into().map_err(|_| EINVAL)?;
 
                 if offset < end_of_previous_object || !is_aligned(offset, size_of::<u32>()) {
-                    pr_warn!("Got transaction with invalid offset.");
+                    binder_debug!(
+                        crate::debug::BINDER_DEBUG_USER_ERROR,
+                        "got transaction with invalid offset"
+                    );
                     return Err(EINVAL.into());
                 }
 
@@ -1066,7 +1096,11 @@ pub(crate) fn copy_transaction_data(
                 ) {
                     Ok(()) => end_of_previous_object = offset + object.size(),
                     Err(err) => {
-                        pr_warn!("Error while translating object.");
+                        binder_debug!(
+                            crate::debug::BINDER_DEBUG_USER_ERROR,
+                            "error while translating object: {:?}",
+                            err
+                        );
                         return Err(err);
                     }
                 }
@@ -1087,14 +1121,22 @@ pub(crate) fn copy_transaction_data(
 
         if let Some(sg_state) = sg_state.as_mut() {
             if let Err(err) = self.apply_sg(&mut alloc, sg_state) {
-                pr_warn!("Failure in apply_sg: {:?}", err);
+                binder_debug!(
+                    crate::debug::BINDER_DEBUG_USER_ERROR,
+                    "failure in apply_sg: {:?}",
+                    err
+                );
                 return Err(err);
             }
         }
 
         if let Some((off_out, secctx)) = secctx.as_mut() {
             if let Err(err) = alloc.write(secctx_off, secctx.as_bytes()) {
-                pr_warn!("Failed to write security context: {:?}", err);
+                binder_debug!(
+                    crate::debug::BINDER_DEBUG_USER_ERROR,
+                    "failed to write security context: {:?}",
+                    err
+                );
                 return Err(err.into());
             }
             **off_out = secctx_off;
@@ -1283,7 +1325,10 @@ fn transaction_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResu
         {
             let mut inner = self.inner.lock();
             if !transaction.is_stacked_on(&inner.current_transaction) {
-                pr_warn!("Transaction stack changed during transaction!");
+                binder_debug!(
+                    crate::debug::BINDER_DEBUG_USER_ERROR,
+                    "got new transaction with bad transaction stack"
+                );
                 return Err(EINVAL.into());
             }
             inner.current_transaction = Some(transaction.clone_arc());
@@ -1306,8 +1351,21 @@ fn transaction_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResu
     }
 
     fn reply_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResult {
-        let orig = self.inner.lock().pop_transaction_to_reply(self)?;
+        let orig = match self.inner.lock().pop_transaction_to_reply(self) {
+            Ok(orig) => orig,
+            Err(err) => {
+                binder_debug!(
+                    crate::debug::BINDER_DEBUG_USER_ERROR,
+                    "got reply transaction with no transaction stack"
+                );
+                return Err(err.into());
+            }
+        };
         if !orig.from.is_current_transaction(&orig) {
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_USER_ERROR,
+                "got reply transaction with bad transaction stack"
+            );
             return Err(EINVAL.into());
         }
 

-- 
2.55.0.rc0.799.gd6f94ed593-goog



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/7] rust_binder: Implement the BINDER_DEBUG_FAILED_TRANSACTION logging mask for transaction parsing and routing failures
  2026-07-03 15:29 [PATCH 0/7] rust_binder : Implement dynamic debug logging mask Jahnavi MN via B4 Relay
                   ` (3 preceding siblings ...)
  2026-07-03 15:29 ` [PATCH 4/7] rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for transaction parsing and protocol validation failures Jahnavi MN via B4 Relay
@ 2026-07-03 15:29 ` Jahnavi MN via B4 Relay
  2026-07-03 15:29 ` [PATCH 6/7] rust_binder: Implement BINDER_DEBUG_FAILED_TRANSACTION logging for death notification allocation failures Jahnavi MN via B4 Relay
  2026-07-03 15:29 ` [PATCH 7/7] rust_binder: Implement the BINDER_DEBUG_DEAD_TRANSACTION logging mask to trace in-flight cancellations during teardown Jahnavi MN via B4 Relay
  6 siblings, 0 replies; 12+ messages in thread
From: Jahnavi MN via B4 Relay @ 2026-07-03 15:29 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
	Christian Brauner, Carlos Llamas, Alice Ryhl, Miguel Ojeda,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Trevor Gross, Danilo Krummrich, Daniel Almeida,
	Tamir Duberstein, Alexandre Courbot, Onur Özkan
  Cc: linux-kernel, rust-for-linux, Jahnavi MN

From: Jahnavi MN <jahnavimn@google.com>

This adds dynamic debug logs for:
- Failed replies, target process deaths, and error code deliveries.
- Detailed transaction failure diagnostics (including sender/receiver
  PIDs, TIDs, transaction IDs, buffer sizes, and error codes).
- File descriptor (FD) array validation and translation errors.

Signed-off-by: Jahnavi MN <jahnavimn@google.com>
---
 drivers/android/binder/thread.rs      | 40 +++++++++++++++++++++++++++++++----
 drivers/android/binder/transaction.rs |  5 +++++
 2 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs
index ecf05cebcb3e..1656e0c70fef 100644
--- a/drivers/android/binder/thread.rs
+++ b/drivers/android/binder/thread.rs
@@ -1191,6 +1191,11 @@ fn deliver_single_reply(
             }
 
             if inner.is_dead {
+                binder_debug!(
+                    crate::debug::BINDER_DEBUG_FAILED_TRANSACTION,
+                    "send failed reply for transaction {}, target dead",
+                    transaction.debug_id
+                );
                 return true;
             }
 
@@ -1198,7 +1203,18 @@ fn deliver_single_reply(
                 Ok(work) => {
                     inner.push_work(work);
                 }
-                Err(code) => inner.push_reply_work(code),
+                Err(code) => {
+                    if code == BR_FAILED_REPLY || code == BR_DEAD_REPLY {
+                        binder_debug!(
+                            crate::debug::BINDER_DEBUG_FAILED_TRANSACTION,
+                            "send failed reply for transaction {} to {}:{}",
+                            transaction.debug_id,
+                            self.process.task.pid(),
+                            self.task.pid()
+                        );
+                    }
+                    inner.push_reply_work(code)
+                }
             }
         }
 
@@ -1297,11 +1313,27 @@ fn transaction(self: &Arc<Self>, cmd: u32, reader: &mut UserSliceReader) -> Resu
                     ee.param = source.to_errno();
                 }
 
-                pr_warn!(
-                    "{}:{} transaction to {} failed: {source:?}",
+                binder_debug!(
+                    crate::debug::BINDER_DEBUG_FAILED_TRANSACTION,
+                    "{}:{} transaction {} to {}:{} failed {}/{}/{}, code {} size {}-{} line {}",
                     info.from_pid,
                     info.from_tid,
-                    info.to_pid
+                    if info.is_reply {
+                        "reply"
+                    } else if info.is_oneway() {
+                        "async"
+                    } else {
+                        "call"
+                    },
+                    info.to_pid,
+                    info.to_tid,
+                    info.debug_id,
+                    err.reply,
+                    info.errno,
+                    info.code,
+                    info.data_size,
+                    info.offsets_size,
+                    line!()
                 );
             }
         }
diff --git a/drivers/android/binder/transaction.rs b/drivers/android/binder/transaction.rs
index f9285eb93fc0..f8756c5dfba4 100644
--- a/drivers/android/binder/transaction.rs
+++ b/drivers/android/binder/transaction.rs
@@ -405,6 +405,11 @@ fn do_work(
         } else {
             // On failure to process the list, we send a reply back to the sender and ignore the
             // transaction on the recipient.
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_FAILED_TRANSACTION,
+                "transaction {} fd fixups failed",
+                self.debug_id
+            );
             return Ok(true);
         };
 

-- 
2.55.0.rc0.799.gd6f94ed593-goog



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 6/7] rust_binder: Implement BINDER_DEBUG_FAILED_TRANSACTION logging for death notification allocation failures
  2026-07-03 15:29 [PATCH 0/7] rust_binder : Implement dynamic debug logging mask Jahnavi MN via B4 Relay
                   ` (4 preceding siblings ...)
  2026-07-03 15:29 ` [PATCH 5/7] rust_binder: Implement the BINDER_DEBUG_FAILED_TRANSACTION logging mask for transaction parsing and routing failures Jahnavi MN via B4 Relay
@ 2026-07-03 15:29 ` Jahnavi MN via B4 Relay
  2026-07-04 21:17   ` Alice Ryhl
  2026-07-03 15:29 ` [PATCH 7/7] rust_binder: Implement the BINDER_DEBUG_DEAD_TRANSACTION logging mask to trace in-flight cancellations during teardown Jahnavi MN via B4 Relay
  6 siblings, 1 reply; 12+ messages in thread
From: Jahnavi MN via B4 Relay @ 2026-07-03 15:29 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
	Christian Brauner, Carlos Llamas, Alice Ryhl, Miguel Ojeda,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Trevor Gross, Danilo Krummrich, Daniel Almeida,
	Tamir Duberstein, Alexandre Courbot, Onur Özkan
  Cc: linux-kernel, rust-for-linux, Jahnavi MN

From: Jahnavi MN <jahnavimn@google.com>

This adds dynamic debug logs for:
- Memory allocation failures when registering process death
  notifications due to out-of-memory (OOM) conditions.

Signed-off-by: Jahnavi MN <jahnavimn@google.com>
---
 drivers/android/binder/process.rs | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs
index db929cc35585..4c200d3d5604 100644
--- a/drivers/android/binder/process.rs
+++ b/drivers/android/binder/process.rs
@@ -1238,6 +1238,11 @@ pub(crate) fn request_death(
         // Queue BR_ERROR if we can't allocate memory for the death notification.
         let death = UniqueArc::new_uninit(GFP_KERNEL).inspect_err(|_| {
             thread.push_return_work(BR_ERROR);
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_FAILED_TRANSACTION,
+                "process {} BC_REQUEST_DEATH_NOTIFICATION failed",
+                self.pid_in_current_ns()
+            );
         })?;
         let mut refs = self.node_refs.lock();
         let Some(info) = refs.by_handle.get_mut(&handle) else {

-- 
2.55.0.rc0.799.gd6f94ed593-goog



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 7/7] rust_binder: Implement the BINDER_DEBUG_DEAD_TRANSACTION logging mask to trace in-flight cancellations during teardown
  2026-07-03 15:29 [PATCH 0/7] rust_binder : Implement dynamic debug logging mask Jahnavi MN via B4 Relay
                   ` (5 preceding siblings ...)
  2026-07-03 15:29 ` [PATCH 6/7] rust_binder: Implement BINDER_DEBUG_FAILED_TRANSACTION logging for death notification allocation failures Jahnavi MN via B4 Relay
@ 2026-07-03 15:29 ` Jahnavi MN via B4 Relay
  6 siblings, 0 replies; 12+ messages in thread
From: Jahnavi MN via B4 Relay @ 2026-07-03 15:29 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
	Christian Brauner, Carlos Llamas, Alice Ryhl, Miguel Ojeda,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Trevor Gross, Danilo Krummrich, Daniel Almeida,
	Tamir Duberstein, Alexandre Courbot, Onur Özkan
  Cc: linux-kernel, rust-for-linux, Jahnavi MN

From: Jahnavi MN <jahnavimn@google.com>

This adds dynamic debug logs for:
- Releasing active transactions during thread stack unwinding.
- Discarded transaction error codes when a thread exits.
- Undelivered transaction acknowledgments (TRANSACTION_COMPLETE)
  upon thread exit.
- Undelivered process death and freeze notifications when processes
  exit or die.
- Undelivered transactions canceled due to target process death.

Signed-off-by: Jahnavi MN <jahnavimn@google.com>
---
 drivers/android/binder/freeze.rs           |  8 +++++++-
 drivers/android/binder/node.rs             |  8 +++++++-
 drivers/android/binder/rust_binder_main.rs |  9 ++++++++-
 drivers/android/binder/thread.rs           | 18 +++++++++++++++++-
 drivers/android/binder/transaction.rs      |  6 ++++++
 5 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/android/binder/freeze.rs b/drivers/android/binder/freeze.rs
index d0559ed308ef..b60fbad0f2f3 100644
--- a/drivers/android/binder/freeze.rs
+++ b/drivers/android/binder/freeze.rs
@@ -140,7 +140,13 @@ fn do_work(
         }
     }
 
-    fn cancel(self: DArc<Self>) {}
+    fn cancel(self: DArc<Self>) {
+        binder_debug!(
+            crate::debug::BINDER_DEBUG_DEAD_TRANSACTION,
+            "undelivered freeze notification, {:016x}",
+            self.cookie.0
+        );
+    }
 
     fn should_sync_wakeup(&self) -> bool {
         false
diff --git a/drivers/android/binder/node.rs b/drivers/android/binder/node.rs
index d71f55739772..1d6d623072df 100644
--- a/drivers/android/binder/node.rs
+++ b/drivers/android/binder/node.rs
@@ -1120,7 +1120,13 @@ fn do_work(
         Ok(cmd != BR_DEAD_BINDER)
     }
 
-    fn cancel(self: DArc<Self>) {}
+    fn cancel(self: DArc<Self>) {
+        binder_debug!(
+            crate::debug::BINDER_DEBUG_DEAD_TRANSACTION,
+            "undelivered death notification, {:016x}",
+            self.cookie
+        );
+    }
 
     fn should_sync_wakeup(&self) -> bool {
         false
diff --git a/drivers/android/binder/rust_binder_main.rs b/drivers/android/binder/rust_binder_main.rs
index bf15021524a4..8b8992411cd7 100644
--- a/drivers/android/binder/rust_binder_main.rs
+++ b/drivers/android/binder/rust_binder_main.rs
@@ -262,7 +262,14 @@ fn do_work(
         Ok(true)
     }
 
-    fn cancel(self: DArc<Self>) {}
+    fn cancel(self: DArc<Self>) {
+        if !self.skip.load(Relaxed) {
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_DEAD_TRANSACTION,
+                "undelivered TRANSACTION_COMPLETE"
+            );
+        }
+    }
 
     fn should_sync_wakeup(&self) -> bool {
         false
diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs
index 1656e0c70fef..43bc146505cc 100644
--- a/drivers/android/binder/thread.rs
+++ b/drivers/android/binder/thread.rs
@@ -1150,6 +1150,13 @@ fn unwind_transaction_stack(self: &Arc<Self>) {
             let mut inner = thread.inner.lock();
             inner.pop_transaction_to_reply(thread.as_ref())
         } {
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_DEAD_TRANSACTION,
+                "release process {} transaction {} in, still active",
+                self.process.task.pid(),
+                transaction.debug_id
+            );
+
             let reply = Err(BR_DEAD_REPLY);
             if !transaction.from.deliver_single_reply(reply, &transaction) {
                 break;
@@ -1728,7 +1735,16 @@ fn do_work(
         Ok(true)
     }
 
-    fn cancel(self: DArc<Self>) {}
+    fn cancel(self: DArc<Self>) {
+        let code = self.error_code.load(Relaxed);
+        if code != BR_OK {
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_DEAD_TRANSACTION,
+                "undelivered TRANSACTION_ERROR: {}",
+                code
+            );
+        }
+    }
 
     fn should_sync_wakeup(&self) -> bool {
         false
diff --git a/drivers/android/binder/transaction.rs b/drivers/android/binder/transaction.rs
index f8756c5dfba4..3cb0cb9694de 100644
--- a/drivers/android/binder/transaction.rs
+++ b/drivers/android/binder/transaction.rs
@@ -485,6 +485,12 @@ fn cancel(self: DArc<Self>) {
         if self.target_node.is_some() && self.flags & TF_ONE_WAY == 0 {
             let reply = Err(BR_DEAD_REPLY);
             self.from.deliver_reply(reply, &self);
+        } else {
+            binder_debug!(
+                crate::debug::BINDER_DEBUG_DEAD_TRANSACTION,
+                "undelivered transaction {}, process died",
+                self.debug_id
+            );
         }
 
         self.drop_outstanding_txn();

-- 
2.55.0.rc0.799.gd6f94ed593-goog



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/7] rust_binder: Add dynamic debug logging mask
  2026-07-03 15:29 ` [PATCH 1/7] rust_binder: Add " Jahnavi MN via B4 Relay
@ 2026-07-03 16:23   ` Gary Guo
  2026-07-04 21:03   ` Alice Ryhl
  1 sibling, 0 replies; 12+ messages in thread
From: Gary Guo @ 2026-07-03 16:23 UTC (permalink / raw)
  To: jahnavimn, Greg Kroah-Hartman, Arve Hjønnevåg,
	Todd Kjos, Christian Brauner, Carlos Llamas, Alice Ryhl,
	Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich,
	Daniel Almeida, Tamir Duberstein, Alexandre Courbot,
	Onur Özkan
  Cc: linux-kernel, rust-for-linux

On Fri Jul 3, 2026 at 4:29 PM BST, Jahnavi MN via B4 Relay wrote:
> From: Jahnavi MN <jahnavimn@google.com>
>
> Implement a dynamic debug logging mask (`debug_mask`) for the
> `rust_binder` module to allow dynamic runtime configuration of log
> levels. This enables parity with the legacy C driver's debug mask.
>
> Since the Rust `module!` macro in the current kernel build does not yet
> support declaring module parameters directly in Rust, we define the
> `debug_mask` variable in a C companion file to expose it to the kernel
> runtime and import it using FFI with volatile reads.
>
> To verify the setup, instrument process lifecycle events (open, flush,
> and release) in `process.rs` under the new `BINDER_DEBUG_OPEN_CLOSE`
> logging mask. These entry-point events are chosen for initial validation
> because they represent the start of the Binder lifecycle and occur
> at low frequency, allowing simple runtime verification of the dynamic
> toggle without log noise.
>
> Signed-off-by: Jahnavi MN <jahnavimn@google.com>
> ---
>  drivers/android/binder/debug.rs            | 49 ++++++++++++++++++++++++++++++
>  drivers/android/binder/process.rs          | 15 +++++++--
>  drivers/android/binder/rust_binder_main.rs |  2 ++
>  drivers/android/binder/rust_binderfs.c     |  3 ++
>  drivers/android/binder/thread.rs           |  1 +
>  drivers/android/binder/transaction.rs      |  5 +--
>  6 files changed, 71 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/android/binder/debug.rs b/drivers/android/binder/debug.rs
> new file mode 100644
> index 000000000000..5e4daa823377
> --- /dev/null
> +++ b/drivers/android/binder/debug.rs
> @@ -0,0 +1,49 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +// Copyright (C) 2026 Google LLC.
> +
> +//! Binder debugging helpers.
> +
> +#![allow(dead_code)]
> +
> +pub(crate) const BINDER_DEBUG_USER_ERROR: u32 = 1 << 0;
> +pub(crate) const BINDER_DEBUG_FAILED_TRANSACTION: u32 = 1 << 1;
> +pub(crate) const BINDER_DEBUG_DEAD_TRANSACTION: u32 = 1 << 2;
> +pub(crate) const BINDER_DEBUG_OPEN_CLOSE: u32 = 1 << 3;
> +pub(crate) const BINDER_DEBUG_DEAD_BINDER: u32 = 1 << 4;
> +pub(crate) const BINDER_DEBUG_DEATH_NOTIFICATION: u32 = 1 << 5;
> +pub(crate) const BINDER_DEBUG_READ_WRITE: u32 = 1 << 6;
> +pub(crate) const BINDER_DEBUG_USER_REFS: u32 = 1 << 7;
> +pub(crate) const BINDER_DEBUG_THREADS: u32 = 1 << 8;
> +pub(crate) const BINDER_DEBUG_TRANSACTION: u32 = 1 << 9;
> +pub(crate) const BINDER_DEBUG_TRANSACTION_COMPLETE: u32 = 1 << 10;
> +pub(crate) const BINDER_DEBUG_FREE_BUFFER: u32 = 1 << 11;
> +pub(crate) const BINDER_DEBUG_INTERNAL_REFS: u32 = 1 << 12;
> +pub(crate) const BINDER_DEBUG_PRIORITY_CAP: u32 = 1 << 13;
> +pub(crate) const BINDER_DEBUG_SPINLOCKS: u32 = 1 << 14;

This should be defined as bitflags:
https://rust.docs.kernel.org/next/kernel/macro.impl_flags.html

> +
> +extern "C" {
> +    static rust_binder_debug_mask: u32;

It's UB for this to be mutated. This should either be `static mut` or
`Atomic<u32>`.

> +}
> +
> +/// Checks if the given debug logging category is enabled in the mask.
> +pub(crate) fn debug_mask_enabled(mask: u32) -> bool {
> +    let ptr = &raw const rust_binder_debug_mask;
> +    // SAFETY: `rust_binder_debug_mask` is defined in the companion C code linked in the module.
> +    let current_mask = unsafe { core::ptr::read_volatile(ptr) };
> +    (current_mask & mask) != 0
> +}
> +
> +/// Prints a debug log if the specified mask category is enabled.
> +#[macro_export]
> +macro_rules! binder_debug {
> +    ($mask:expr, $fmt:literal $(, $($arg:tt)*)?) => {
> +        if $crate::debug::debug_mask_enabled($mask) {

The mask should probably just be an identifier and then the macro builds the
full mask, so crate::debug::... is not needed.

Best,
Gary

> +            kernel::pr_info!(
> +                "{}: {}\n",
> +                kernel::current!().pid(),
> +                format_args!($fmt $(, $($arg)*)?)
> +            );
> +        }
> +    };
> +}


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/7] rust_binder: Add dynamic debug logging mask
  2026-07-03 15:29 ` [PATCH 1/7] rust_binder: Add " Jahnavi MN via B4 Relay
  2026-07-03 16:23   ` Gary Guo
@ 2026-07-04 21:03   ` Alice Ryhl
  1 sibling, 0 replies; 12+ messages in thread
From: Alice Ryhl @ 2026-07-04 21:03 UTC (permalink / raw)
  To: Jahnavi MN
  Cc: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
	Christian Brauner, Carlos Llamas, Miguel Ojeda, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, linux-kernel, rust-for-linux

On Fri, Jul 03, 2026 at 03:29:22PM +0000, Jahnavi MN wrote:
> Implement a dynamic debug logging mask (`debug_mask`) for the
> `rust_binder` module to allow dynamic runtime configuration of log
> levels. This enables parity with the legacy C driver's debug mask.
> 
> Since the Rust `module!` macro in the current kernel build does not yet
> support declaring module parameters directly in Rust, we define the
> `debug_mask` variable in a C companion file to expose it to the kernel
> runtime and import it using FFI with volatile reads.
> 
> To verify the setup, instrument process lifecycle events (open, flush,
> and release) in `process.rs` under the new `BINDER_DEBUG_OPEN_CLOSE`
> logging mask. These entry-point events are chosen for initial validation
> because they represent the start of the Binder lifecycle and occur
> at low frequency, allowing simple runtime verification of the dynamic
> toggle without log noise.
> 
> Signed-off-by: Jahnavi MN <jahnavimn@google.com>

> diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs
> index 96b8440ceac6..c13a04a3afcb 100644
> --- a/drivers/android/binder/process.rs
> +++ b/drivers/android/binder/process.rs
> @@ -898,7 +898,6 @@ pub(crate) fn insert_or_update_handle(
>      }
>  
>      pub(crate) fn get_transaction_node(&self, handle: u32) -> BinderResult<NodeRef> {
> -        // When handle is zero, try to get the context manager.
>          if handle == 0 {
>              Ok(self.ctx.get_manager_node(true)?)
>          } else {

Removing this comment appears to be a spurious change.

> @@ -1314,6 +1313,11 @@ pub(crate) fn lock_with_nodes(&self) -> WithNodes<'_> {
>      }
>  
>      fn deferred_flush(&self) {
> +        binder_debug!(
> +            crate::debug::BINDER_DEBUG_OPEN_CLOSE,
> +            "binder_flush: process {}",
> +            self.pid_in_current_ns()
> +        );
>          let inner = self.inner.lock();
>          for thread in inner.threads.values() {
>              thread.exit_looper();
> @@ -1321,6 +1325,11 @@ fn deferred_flush(&self) {
>      }
>  
>      fn deferred_release(self: Arc<Self>) {
> +        binder_debug!(
> +            crate::debug::BINDER_DEBUG_OPEN_CLOSE,
> +            "binder_deferred_release: process {}",
> +            self.pid_in_current_ns()
> +        );

Since you included the pid in the binder_debug! macro itself, you can
remove it from these two println statements.

Also, I think it'd be nicer to word these as "flushing process" and
"releasing process".

> diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs
> index 97d5f31e8fe3..c908dde5796a 100644
> --- a/drivers/android/binder/thread.rs
> +++ b/drivers/android/binder/thread.rs
> @@ -1222,6 +1222,7 @@ fn read_transaction_info(
>          info.buffers_size = td.buffers_size as usize;
>          // SAFETY: Above `read` call initializes all bytes, so this union read is ok.
>          info.target_handle = unsafe { td.transaction_data.target.handle };
> +        info.debug_id = super::next_debug_id();
>          Ok(())
>      }
>  
> diff --git a/drivers/android/binder/transaction.rs b/drivers/android/binder/transaction.rs
> index 1d9b66920a21..f9285eb93fc0 100644
> --- a/drivers/android/binder/transaction.rs
> +++ b/drivers/android/binder/transaction.rs
> @@ -42,6 +42,7 @@ pub(crate) struct TransactionInfo {
>      pub(crate) reply: u32,
>      pub(crate) oneway_spam_suspect: bool,
>      pub(crate) is_reply: bool,
> +    pub(crate) debug_id: usize,
>  }
>  
>  impl TransactionInfo {
> @@ -93,7 +94,7 @@ pub(crate) fn new(
>          from: &Arc<Thread>,
>          info: &mut TransactionInfo,
>      ) -> BinderResult<DLArc<Self>> {
> -        let debug_id = super::next_debug_id();
> +        let debug_id = info.debug_id;
>          let allow_fds = node_ref.node.flags & FLAT_BINDER_FLAG_ACCEPTS_FDS != 0;
>          let txn_security_ctx = node_ref.node.flags & FLAT_BINDER_FLAG_TXN_SECURITY_CTX != 0;
>          let mut txn_security_ctx_off = if txn_security_ctx { Some(0) } else { None };
> @@ -152,7 +153,7 @@ pub(crate) fn new_reply(
>          info: &mut TransactionInfo,
>          allow_fds: bool,
>      ) -> BinderResult<DLArc<Self>> {
> -        let debug_id = super::next_debug_id();
> +        let debug_id = info.debug_id;

It looks like this change to move debug_id so that it's present in
TransactionInfo is happening in the wrong patch. Ideally this change
would be part of the patch that actually needs to read debug_id from
TransactionInfo.

Alice

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/7] rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for reference counting and death notification operations
  2026-07-03 15:29 ` [PATCH 3/7] rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for reference counting and death notification operations Jahnavi MN via B4 Relay
@ 2026-07-04 21:14   ` Alice Ryhl
  0 siblings, 0 replies; 12+ messages in thread
From: Alice Ryhl @ 2026-07-04 21:14 UTC (permalink / raw)
  To: Jahnavi MN
  Cc: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
	Christian Brauner, Carlos Llamas, Miguel Ojeda, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, linux-kernel, rust-for-linux

On Fri, Jul 03, 2026 at 03:29:24PM +0000, Jahnavi MN wrote:
> This adds dynamic debug logs for:
> - Decrementing handle reference counts that are already zero.
> - Mismatched reference states (calling inc_ref_done with no active
>   inc_refs, or using a weak reference as a strong reference).
> - Requesting or clearing death notifications on invalid references,
>   already active notifications, or with mismatched cookies.
> 
> Signed-off-by: Jahnavi MN <jahnavimn@google.com>

The commit title is pretty long. Could we shorten it? For example:

rust_binder: use BINDER_DEBUG_USER_ERROR mask for refcount errors

>              *count += 1;
>          } else {
>              if *count == 0 {
> -                pr_warn!(
> -                    "pid {} performed invalid decrement on ref\n",
> -                    kernel::current!().pid()
> +                binder_debug!(
> +                    crate::debug::BINDER_DEBUG_USER_ERROR,
> +                    "performed invalid decrement on ref (strong: {})",
> +                    strong

Instead of printing (strong: true) or (strong: false), I think it would
be nicer to print strong or weak directly in the text:

	binder_debug!(
	    crate::debug::BINDER_DEBUG_USER_ERROR,
	    "performed invalid {} decrement on ref",
	    if strong { "strong" } else { "weak" }

>      pub(crate) fn get_transaction_node(&self, handle: u32) -> BinderResult<NodeRef> {
> -        if handle == 0 {
> -            Ok(self.ctx.get_manager_node(true)?)
> +        // When handle is zero, try to get the context manager.
> +        let res = if handle == 0 {
> +            self.ctx.get_manager_node(true)
>          } else {
> -            Ok(self.get_node_from_handle(handle, true)?)
> +            self.get_node_from_handle(handle, true).map_err(Into::into)
> +        };
> +
> +        match res {
> +            Ok(node_ref) => Ok(node_ref),
> +            Err(err) => {
> +                binder_debug!(
> +                    crate::debug::BINDER_DEBUG_USER_ERROR,
> +                    "got transaction to invalid handle {}",
> +                    handle
> +                );
> +                Err(err)
> +            }

This is probably only a user error if `handle != 0`. The application has
no way of knowing the context manager is dead, so that case isn't a bug
in the application.

So I think we can move this println inside the else {} block.

> @@ -1268,17 +1291,27 @@ pub(crate) fn clear_death(&self, reader: &mut UserSliceReader, thread: &Thread)
>  
>          let mut refs = self.node_refs.lock();
>          let Some(info) = refs.by_handle.get_mut(&handle) else {
> -            pr_warn!("BC_CLEAR_DEATH_NOTIFICATION invalid ref {handle}\n");
> +            binder_debug!(
> +                crate::debug::BINDER_DEBUG_USER_ERROR,
> +                "BC_CLEAR_DEATH_NOTIFICATION invalid ref {}",
> +                handle
> +            );

Does the {handle} syntax that the println is currently using work here?
If not, then I think we should try to get it working.

Alice

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 6/7] rust_binder: Implement BINDER_DEBUG_FAILED_TRANSACTION logging for death notification allocation failures
  2026-07-03 15:29 ` [PATCH 6/7] rust_binder: Implement BINDER_DEBUG_FAILED_TRANSACTION logging for death notification allocation failures Jahnavi MN via B4 Relay
@ 2026-07-04 21:17   ` Alice Ryhl
  0 siblings, 0 replies; 12+ messages in thread
From: Alice Ryhl @ 2026-07-04 21:17 UTC (permalink / raw)
  To: Jahnavi MN
  Cc: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
	Christian Brauner, Carlos Llamas, Miguel Ojeda, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, linux-kernel, rust-for-linux

On Fri, Jul 03, 2026 at 03:29:27PM +0000, Jahnavi MN wrote:
> This adds dynamic debug logs for:
> - Memory allocation failures when registering process death
>   notifications due to out-of-memory (OOM) conditions.
> 
> Signed-off-by: Jahnavi MN <jahnavimn@google.com>
> ---
>  drivers/android/binder/process.rs | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs
> index db929cc35585..4c200d3d5604 100644
> --- a/drivers/android/binder/process.rs
> +++ b/drivers/android/binder/process.rs
> @@ -1238,6 +1238,11 @@ pub(crate) fn request_death(
>          // Queue BR_ERROR if we can't allocate memory for the death notification.
>          let death = UniqueArc::new_uninit(GFP_KERNEL).inspect_err(|_| {
>              thread.push_return_work(BR_ERROR);
> +            binder_debug!(
> +                crate::debug::BINDER_DEBUG_FAILED_TRANSACTION,
> +                "process {} BC_REQUEST_DEATH_NOTIFICATION failed",
> +                self.pid_in_current_ns()
> +            );

I think the error code BINDER_DEBUG_FAILED_TRANSACTION is a bit weird
here. Shouldn't it be BINDER_DEBUG_DEATH_NOTIFICATION?

Also, since you changed binder_debug! to already include the pid, you
can take it out here.

Alice

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2026-07-04 21:17 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-03 15:29 [PATCH 0/7] rust_binder : Implement dynamic debug logging mask Jahnavi MN via B4 Relay
2026-07-03 15:29 ` [PATCH 1/7] rust_binder: Add " Jahnavi MN via B4 Relay
2026-07-03 16:23   ` Gary Guo
2026-07-04 21:03   ` Alice Ryhl
2026-07-03 15:29 ` [PATCH 2/7] rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for freezer-related operation Jahnavi MN via B4 Relay
2026-07-03 15:29 ` [PATCH 3/7] rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for reference counting and death notification operations Jahnavi MN via B4 Relay
2026-07-04 21:14   ` Alice Ryhl
2026-07-03 15:29 ` [PATCH 4/7] rust_binder: Implement the BINDER_DEBUG_USER_ERROR logging mask for transaction parsing and protocol validation failures Jahnavi MN via B4 Relay
2026-07-03 15:29 ` [PATCH 5/7] rust_binder: Implement the BINDER_DEBUG_FAILED_TRANSACTION logging mask for transaction parsing and routing failures Jahnavi MN via B4 Relay
2026-07-03 15:29 ` [PATCH 6/7] rust_binder: Implement BINDER_DEBUG_FAILED_TRANSACTION logging for death notification allocation failures Jahnavi MN via B4 Relay
2026-07-04 21:17   ` Alice Ryhl
2026-07-03 15:29 ` [PATCH 7/7] rust_binder: Implement the BINDER_DEBUG_DEAD_TRANSACTION logging mask to trace in-flight cancellations during teardown Jahnavi MN via B4 Relay

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox