tasktrace
Logical 'stack' traces of async functions.
This crate gives you the ability to capture a stacktrace of a running async task.
Usage
To use, wrap the future you're interested in (usually the top level one) with
tasktrace::traced
and use the returned handle to request a backtrace at any
time.
async
async
async
async
async
async
async
This example program will print out something along the lines of:
╼ <tasktrace::TracedTask<F> as core::future::future::Future>::poll::{{closure}} at /home/petrosagg/projects/tasktrace/src/lib.rs:116:50
└╼ taskdump::foo::{{closure}} at /home/petrosagg/projects/tasktrace/examples/taskdump.rs:18:11
└╼ taskdump::bar::{{closure}} at /home/petrosagg/projects/tasktrace/examples/taskdump.rs:22:5
└╼ <tokio::future::poll_fn::PollFn<F> as core::future::future::Future>::poll at /home/petrosagg/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.29.1/src/future/poll_fn.rs:58:9
├╼ taskdump::bar::{{closure}}::{{closure}} at /home/petrosagg/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.29.1/src/macros/join.rs:126:24
│ └╼ <tokio::future::maybe_done::MaybeDone<Fut> as core::future::future::Future>::poll at /home/petrosagg/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.29.1/src/future/maybe_done.rs:68:48
│ └╼ taskdump::fiz::{{closure}} at /home/petrosagg/projects/tasktrace/examples/taskdump.rs:26:15
│ └╼ taskdump::pending::{{closure}} at /home/petrosagg/projects/tasktrace/examples/taskdump.rs:14:8
│ └╼ <core::future::poll_fn::PollFn<F> as core::future::future::Future>::poll at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/core/src/future/poll_fn.rs:64:9
│ └╼ taskdump::pending::{{closure}}::{{closure}} at /home/petrosagg/projects/tasktrace/examples/taskdump.rs:12:22
│ └╼ <core::task::wake::Waker as core::clone::Clone>::clone at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/core/src/task/wake.rs:342:29
│ └╼ tasktrace::clone_raw at /home/petrosagg/projects/tasktrace/src/lib.rs:135:5
└╼ taskdump::bar::{{closure}}::{{closure}} at /home/petrosagg/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.29.1/src/macros/join.rs:126:24
└╼ <tokio::future::maybe_done::MaybeDone<Fut> as core::future::future::Future>::poll at /home/petrosagg/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.29.1/src/future/maybe_done.rs:68:48
└╼ taskdump::buz::{{closure}} at /home/petrosagg/projects/tasktrace/examples/taskdump.rs:30:11
└╼ taskdump::baz::{{closure}} at /home/petrosagg/projects/tasktrace/examples/taskdump.rs:34:15
└╼ taskdump::pending::{{closure}} at /home/petrosagg/projects/tasktrace/examples/taskdump.rs:14:8
└╼ <core::future::poll_fn::PollFn<F> as core::future::future::Future>::poll at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/core/src/future/poll_fn.rs:64:9
└╼ taskdump::pending::{{closure}}::{{closure}} at /home/petrosagg/projects/tasktrace/examples/taskdump.rs:12:22
└╼ <core::task::wake::Waker as core::clone::Clone>::clone at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/core/src/task/wake.rs:342:29
└╼ tasktrace::clone_raw at /home/petrosagg/projects/tasktrace/src/lib.rs:135:5
How it works
This crate exploits the fact that all leaf futures must clone the provided context Waker in order to call it at some later time when progress can be made.
When a traced future is requested to capture a callstack it wraps the normal waker into one
whose Waker::clone
method is set up to capture a backtrace. Since only leaf futures ever
interact and clone the waker the stacktraces will necessarily contain the desired callstack.
If multiple futures are being waited on (e.g through select!
) then multiple stacktraces will
be captured for each polled future and their combined stacktrace will be displayed as a tree.