Skip to content

Commit a667d97

Browse files
BerrysoftDeepSeek
andcommitted
fix(executor): leak if panicking
Co-authored-by: DeepSeek <service@deepseek.com>
1 parent f519eba commit a667d97

1 file changed

Lines changed: 24 additions & 0 deletions

File tree

  • compio-executor/src/task

compio-executor/src/task/mod.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,13 @@ impl<F: Future + 'static> TaskAlloc<F> {
133133
}
134134

135135
unsafe fn drop_future(header: NonNull<Header>, has_result: bool) {
136+
// The future/result types are unwind-unsafe (ManuallyDrop, union).
137+
// Dropping them during an existing panic could trigger a second panic,
138+
// which would be UB. Instead, leak the contents during unwinding.
139+
if ::std::thread::panicking() {
140+
return;
141+
}
142+
136143
let future_cell = Self::future_cell(header);
137144

138145
future_cell.with_mut(|fut_ptr| {
@@ -298,6 +305,13 @@ impl Task {
298305

299306
header.shared.store(ptr::null_mut(), Release);
300307

308+
// Dropping the future/result and waker during unwinding on unwind-unsafe
309+
// types could trigger a second panic. Skip content drops if already panicking.
310+
if ::std::thread::panicking() {
311+
trace!("Skipping content drops during panic");
312+
return;
313+
}
314+
301315
if !state.is_completed() {
302316
trace!("Dropping future");
303317
// The task has not completed yet, drop future
@@ -361,6 +375,16 @@ impl Drop for Task {
361375
return;
362376
};
363377

378+
// The future/result and waker types are unwind-unsafe (ManuallyDrop in
379+
// union, MaybeUninit). Dropping them during an existing panic could
380+
// trigger a second panic, which would be UB. Skip content drops but
381+
// still deallocate the memory since dealloc does not run destructors
382+
// on the inner types.
383+
if ::std::thread::panicking() {
384+
unsafe { (header.vtable.dealloc)(self.0) }
385+
return;
386+
}
387+
364388
crate::panic_guard!();
365389

366390
debug_assert!(state.is_completed() | state.is_cancelled());

0 commit comments

Comments
 (0)