Skip to main content

tokio/runtime/task/trace/
trace_impl.rs

1//! Current `backtrace::trace` + collector based backtrace implementation
2//!
3//! This implementation may eventually be extracted into a separate `tokio-taskdump` crate.
4
5use std::ptr;
6
7use crate::runtime::task::trace::{trace_with, Trace, TraceMeta};
8
9/// Capture using the default `backtrace::trace`-based implementation.
10#[inline(never)]
11pub(super) fn capture<F, R>(f: F) -> (R, Trace)
12where
13    F: FnOnce() -> R,
14{
15    let mut trace = Trace::empty();
16
17    let result = trace_with(f, |meta| trace_leaf(meta, &mut trace));
18
19    (result, trace)
20}
21
22/// Capture a backtrace via `backtrace::trace` and collect it into `trace`.
23pub(crate) fn trace_leaf(meta: &TraceMeta, trace: &mut Trace) {
24    let mut frames: Vec<backtrace::BacktraceFrame> = vec![];
25    let mut above_leaf = false;
26
27    if let Some(root_addr) = meta.root_addr {
28        backtrace::trace(|frame| {
29            let below_root = !ptr::eq(frame.symbol_address(), root_addr);
30
31            if above_leaf && below_root {
32                frames.push(frame.to_owned().into());
33            }
34
35            if ptr::eq(frame.symbol_address(), meta.trace_leaf_addr) {
36                above_leaf = true;
37            }
38
39            below_root
40        });
41    }
42    trace.push_backtrace(frames);
43}