Capture stack traces from Tokio tasks at their yield points.
This crate provides utilities for collecting instruction-pointer-level stack
traces from async tasks while they are suspended. It hooks into Tokio's
taskdump infrastructure to walk the stack of a task when it yields,
producing a list of frame addresses that can be symbolicated with tools like
addr2line or the backtrace crate.
Add the dependency to your Cargo.toml:
[dependencies]
tokio-taskdump = "0.1"
tokio = { version = "1", features = ["rt", "taskdump"] }use std::future::Future;
use std::task::Poll;
use tokio::runtime::dump::{Trace, trace_with};
use tokio_taskdump::{capture_trace, TaskTrace};
#[tokio::main]
async fn main() {
let mut fut = std::pin::pin!(async {
tokio::task::yield_now().await;
});
let mut traces = Vec::new();
Trace::root(std::future::poll_fn(|cx| {
trace_with(
|| { let _ = fut.as_mut().poll(cx); },
|meta| { capture_trace(meta, &mut traces); },
);
Poll::Ready(())
}))
.await;
for trace in &traces {
println!("captured {} frames", trace.frames().len());
for (i, addr) in trace.frames().iter().enumerate() {
println!(" frame {i}: {addr:#x}");
}
}
}See the examples/ directory for a more complete demonstration.
- You wrap your future in
Trace::rootso Tokio knows where the task's stack begins. - Inside a poll, you call
trace_withwhich invokes your closure and, if the task yields, calls your callback with aTraceMetacontaining the root and leaf addresses. capture_traceperforms a stack unwind (via_Unwind_Backtrace) and appends a newTaskTracecontaining the collected instruction pointer addresses to the providedVec<TaskTrace>. If the task has multiple yield points (e.g., branches of atokio::select!), the callback is invoked once per yield point, producing multiple traces in a single poll.
The resulting frame addresses span from the unwind origin up through the task's call stack. You can then resolve them to symbols offline or at runtime.
- Tokio 1.52.3+ with the
taskdumpfeature enabled - Linux (stack unwinding uses platform-specific APIs)
This project is licensed under the MIT license.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Tokio by you shall be licensed as MIT, without any additional terms or conditions.