From 1397ad534355c417185a435e76c06730fb61ae0c Mon Sep 17 00:00:00 2001 From: Praneet Kalluri Date: Thu, 28 Aug 2025 16:27:32 -0700 Subject: [PATCH] fix: deadlock in std_log_impl macro on write failure The std_log_impl macro, deadlocks when a write operation fails. This occurs because the stream lock is still held when fallback_on_error attempts to write the error message. The fix modifies the macro to properly scope the stream lock: - Ensure lock is released after write attempts by using explicit scope - Handle lock release before error propagation via result? - Maintain same behavior for both meta-logging and standard logging paths Before: write!(self.stream.lock(), "{}", msg)?; // Lock held during error propagation After: let result = { let mut writer = self.stream.lock(); write!(writer, "{}", msg) }; // Lock released here result?; // Error propagation after lock release This prevents the deadlock by ensuring the stream lock is always released before any error handling occurs through fallback_on_error. --- src/log_impl.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/log_impl.rs b/src/log_impl.rs index edc1e1b..62b482e 100644 --- a/src/log_impl.rs +++ b/src/log_impl.rs @@ -567,9 +567,19 @@ macro_rules! std_log_impl { // logging things too. let msg = format!("{}{}", record.args(), self.line_sep); - write!(self.stream.lock(), "{}", msg)?; + let result = { + let mut writer = self.stream.lock(); + write!(writer, "{}", msg) + }; + + result?; } else { - write!(self.stream.lock(), "{}{}", record.args(), self.line_sep)?; + let result = { + let mut writer = self.stream.lock(); + write!(writer, "{}{}", record.args(), self.line_sep) + }; + + result?; } Ok(())