-
Notifications
You must be signed in to change notification settings - Fork 0
8040: Allow impl FnMut() in taskdumps instead of just fn() #94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,7 +34,8 @@ pub(crate) struct Context { | |
| /// The function that is invoked at each leaf future inside of Tokio | ||
| /// | ||
| /// For example, within tokio::time:sleep, sockets. etc. | ||
| trace_leaf_fn: Cell<Option<fn(&TraceMeta)>>, | ||
| #[allow(clippy::type_complexity)] | ||
| trace_leaf_fn: Cell<Option<NonNull<dyn FnMut(&TraceMeta)>>>, | ||
| } | ||
|
|
||
| /// A [`Frame`] in an intrusive, doubly-linked tree of [`Frame`]s. | ||
|
|
@@ -114,19 +115,38 @@ impl Context { | |
| } | ||
| } | ||
|
|
||
| /// Calls the provided closure if we are being traced. | ||
| fn try_with_current_trace_leaf_fn<F, R>(f: F) -> Option<R> | ||
| where | ||
| F: FnOnce(&Cell<Option<fn(&TraceMeta)>>) -> R, | ||
| F: for<'a> FnOnce(&'a mut dyn FnMut(&TraceMeta)) -> R, | ||
| { | ||
| let mut ret = None; | ||
|
|
||
| let inner = |context: &Context| { | ||
| if let Some(mut trace_leaf_fn) = context.trace_leaf_fn.get() { | ||
| context.trace_leaf_fn.set(None); | ||
| let _restore = defer(move || { | ||
| context.trace_leaf_fn.set(Some(trace_leaf_fn)); | ||
| }); | ||
|
|
||
| // SAFETY: The trace leaf fn is valid for the duration in which it's stored in the | ||
| // context. Furthermore, re-entrant calls are not possible since we store `None` for | ||
| // the duration in which we hold a mutable reference, so access is exclusive for that | ||
| // duration. | ||
| ret = Some(f(unsafe { trace_leaf_fn.as_mut() })); | ||
| } | ||
| }; | ||
|
|
||
| // SAFETY: This call can only access the trace_leaf_fn field, so it cannot | ||
| // break the trace frame linked list. | ||
| unsafe { Self::try_with_current(|context| f(&context.trace_leaf_fn)) } | ||
| unsafe { Self::try_with_current(inner) }; | ||
|
|
||
| ret | ||
| } | ||
|
|
||
| /// Produces `true` if the current task is being traced; otherwise false. | ||
| pub(crate) fn is_tracing() -> bool { | ||
| Self::try_with_current_trace_leaf_fn(|maybe_trace_leaf| maybe_trace_leaf.get().is_some()) | ||
| .unwrap_or(false) | ||
| Self::try_with_current_trace_leaf_fn(|_| ()).is_some() | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -189,20 +209,46 @@ pub struct TraceMeta { | |
| /// assert!(count > 0); | ||
| /// # } | ||
| /// ``` | ||
| pub fn trace_with<F, R>(f: F, trace_leaf: fn(&TraceMeta)) -> R | ||
| pub fn trace_with<FN, FT, R>(f: FN, mut trace_leaf: FT) -> R | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The documentation and example for
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. value:useful; category:documentation; feedback: The Gemini AI reviewer is correct! The way the function works has changed - it no more needs the two extra thread locals and its signature changed a bit. Its documentation should be updated to show how to use it now. Prevents confusion in the readers about its usage There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The doc comment above Severity: low 🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. value:useful; category:documentation; feedback: The Augment AI reviewer is correct! The way the function works has changed - it no more needs the two extra thread locals and its signature changed a bit. Its documentation should be updated to show how to use it now. Prevents confusion in the readers about its usage |
||
| where | ||
| F: FnOnce() -> R, | ||
| FN: FnOnce() -> R, | ||
| FT: FnMut(&TraceMeta), | ||
|
Comment on lines
+212
to
+215
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update the rustdoc for the new callback model. The docs above 🤖 Prompt for AI Agents
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. value:useful; category:documentation; feedback: The CodeRabbit AI reviewer is correct! The way the function works has changed - it no more needs the two extra thread locals and its signature changed a bit. Its documentation should be updated to show how to use it now. Prevents confusion in the readers about its usage |
||
| { | ||
| // store our new trace_leaf function | ||
| let previous = | ||
| Context::try_with_current_trace_leaf_fn(|current| current.replace(Some(trace_leaf))); | ||
| let trace_leaf_dyn = (&mut trace_leaf) as &mut (dyn FnMut(&TraceMeta) + '_); | ||
| // SAFETY: The raw pointer is removed from the thread local before `trace_leaf` is dropped, so | ||
| // this transmute cannot lead to the violation of any lifetime requirements. | ||
| let trace_leaf_dyn = unsafe { | ||
| std::mem::transmute::< | ||
| *mut (dyn FnMut(&TraceMeta) + '_), | ||
| *mut (dyn FnMut(&TraceMeta) + 'static), | ||
| >(trace_leaf_dyn) | ||
| }; | ||
| // SAFETY: Pointer comes from reference, so not null. | ||
| let trace_leaf_dyn = unsafe { NonNull::new_unchecked(trace_leaf_dyn) }; | ||
|
|
||
| let mut old_trace_leaf_fn = None; | ||
|
|
||
| // Even if this access fails, that's okay. In that case, we still call the closure without | ||
| // actually performing any tracing. | ||
| // | ||
| // SAFETY: This call can only access the trace_leaf_fn field, so it cannot | ||
| // break the trace frame linked list. | ||
| unsafe { | ||
| Context::try_with_current(|ctx| { | ||
| old_trace_leaf_fn = ctx.trace_leaf_fn.replace(Some(trace_leaf_dyn)); | ||
| }) | ||
| }; | ||
|
|
||
| // restore previous on drop. This is ensures state remains consistent | ||
| // even if the trace_leaf function panics | ||
| let _restore = defer(move || { | ||
| if let Some(previous) = previous { | ||
| Context::try_with_current_trace_leaf_fn(|current| current.set(previous)); | ||
| } | ||
| // This ensures that `trace_leaf_fn` cannot be accessed after this call returns. | ||
| // | ||
| // SAFETY: This call can only access the trace_leaf_fn field, so it cannot | ||
| // break the trace frame linked list. | ||
| unsafe { | ||
| Context::try_with_current(|ctx| { | ||
| ctx.trace_leaf_fn.set(old_trace_leaf_fn); | ||
| }) | ||
| }; | ||
| }); | ||
|
|
||
| f() | ||
|
|
@@ -249,13 +295,14 @@ impl Trace { | |
| // internal implementation details of this crate). | ||
| #[inline(never)] | ||
| pub(crate) fn trace_leaf(cx: &mut task::Context<'_>) -> Poll<()> { | ||
| let trace_leaf_fn = Context::try_with_current_trace_leaf_fn(|cell| cell.get()).flatten(); | ||
| if let Some(trace_leaf_fn) = trace_leaf_fn { | ||
| let root_addr = Context::current_frame_addr(); | ||
|
|
||
| let ret = Context::try_with_current_trace_leaf_fn(|leaf_fn| { | ||
| let meta = TraceMeta { | ||
| root_addr: Context::current_frame_addr(), | ||
| root_addr, | ||
| trace_leaf_addr: trace_leaf as *const c_void, | ||
| }; | ||
| trace_leaf_fn(&meta); | ||
| leaf_fn(&meta); | ||
|
|
||
| // Use the same logic that `yield_now` uses to send out wakeups after | ||
| // the task yields. | ||
|
|
@@ -268,10 +315,11 @@ pub(crate) fn trace_leaf(cx: &mut task::Context<'_>) -> Poll<()> { | |
| } | ||
| } | ||
| }); | ||
| }); | ||
|
|
||
| Poll::Pending | ||
| } else { | ||
| Poll::Ready(()) | ||
| match ret { | ||
| Some(()) => Poll::Pending, | ||
| None => Poll::Ready(()), | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,73 +2,42 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //! | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //! This implementation may eventually be extracted into a separate `tokio-taskdump` crate. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use std::{cell::Cell, ptr}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use std::ptr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::runtime::task::trace::{trace_with, Trace, TraceMeta}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use super::defer; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Thread local state used to communicate between calling the trace and the interior `trace_leaf` function | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| struct TraceContext { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| collector: Cell<Option<Trace>>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| thread_local! { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| static TRACE_CONTEXT: TraceContext = const { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TraceContext { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| collector: Cell::new(None), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Capture using the default `backtrace::trace`-based implementation. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #[inline(never)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub(super) fn capture<F, R>(f: F) -> (R, Trace) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| where | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| F: FnOnce() -> R, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let collector = Trace::empty(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let previous = TRACE_CONTEXT.with(|state| state.collector.replace(Some(collector))); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut trace = Trace::empty(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // restore previous collector on drop even if the callback panics | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let _restore = defer(move || { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TRACE_CONTEXT.with(|state| state.collector.set(previous)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let result = trace_with(f, |meta| trace_leaf(meta, &mut trace)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let result = trace_with(f, trace_leaf); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // take the collector before _restore runs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let collector = TRACE_CONTEXT.with(|state| state.collector.take()).unwrap(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (result, collector) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (result, trace) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Capture a backtrace via `backtrace::trace` and collect it into `STATE` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #[inline(never)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub(crate) fn trace_leaf(meta: &TraceMeta) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TRACE_CONTEXT.with(|state| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if let Some(mut collector) = state.collector.take() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut frames: Vec<backtrace::BacktraceFrame> = vec![]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut above_leaf = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if let Some(root_addr) = meta.root_addr { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| backtrace::trace(|frame| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let below_root = !ptr::eq(frame.symbol_address(), root_addr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Capture a backtrace via `backtrace::trace` and collect it into `trace`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub(crate) fn trace_leaf(meta: &TraceMeta, trace: &mut Trace) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut frames: Vec<backtrace::BacktraceFrame> = vec![]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut above_leaf = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if above_leaf && below_root { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| frames.push(frame.to_owned().into()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if let Some(root_addr) = meta.root_addr { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| backtrace::trace(|frame| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let below_root = !ptr::eq(frame.symbol_address(), root_addr); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ptr::eq(frame.symbol_address(), meta.trace_leaf_addr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| above_leaf = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if above_leaf && below_root { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| frames.push(frame.to_owned().into()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| below_root | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ptr::eq(frame.symbol_address(), meta.trace_leaf_addr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| above_leaf = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| collector.push_backtrace(frames); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| state.collector.set(Some(collector)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| below_root | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| trace.push_backtrace(frames); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+27
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Skip recording a trace when
Proposed fix pub(crate) fn trace_leaf(meta: &TraceMeta, trace: &mut Trace) {
let mut frames: Vec<backtrace::BacktraceFrame> = vec![];
let mut above_leaf = false;
if let Some(root_addr) = meta.root_addr {
backtrace::trace(|frame| {
let below_root = !ptr::eq(frame.symbol_address(), root_addr);
if above_leaf && below_root {
frames.push(frame.to_owned().into());
}
if ptr::eq(frame.symbol_address(), meta.trace_leaf_addr) {
above_leaf = true;
}
below_root
});
+
+ trace.push_backtrace(frames);
}
- trace.push_backtrace(frames);
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. value:useful; category:bug; feedback: The CodeRabbit AI reviewer is correct! There is no need to push the empty frames if there is no root_addr. Prevents useless allocation of the |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: martin-augment/tokio
Length of output: 468
🏁 Script executed:
Repository: martin-augment/tokio
Length of output: 125
🏁 Script executed:
Repository: martin-augment/tokio
Length of output: 362
🏁 Script executed:
Repository: martin-augment/tokio
Length of output: 1409
🏁 Script executed:
Repository: martin-augment/tokio
Length of output: 835
🏁 Script executed:
Repository: martin-augment/tokio
Length of output: 1799
Audit
Context::is_tracing()behavior with active callbacks.The slot-clearing in
try_with_current_trace_leaf_fnmeansis_tracing()now returnsfalsewhen called from within an active leaf callback. The test attokio/tests/dump.rs:116(complete_during_trace()) relies onHandle::is_tracing()returningtrueduring tracing to avoid deadlocks; this test will now fail to detect active tracing and futures will remain pending instead of completing as designed.🤖 Prompt for AI Agents