-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Tasks spawned via spawn_local have useless location information #5030
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
Comments
I hadn't thought of this before, but for all the cases where the only closure that a call stack passes through is to access a #[track_caller]
pub(super) fn spawn_local_inner<F>(future: F, name: Option<&str>) -> JoinHandle<F::Output>
where F: Future + 'static,
F::Output: 'static
{
CURRENT.with(|maybe_cx| {
maybe_cx.get().map(|cx| cx.spawn(future, name))
})
.expect("`spawn_local` called from outside of a `task::LocalSet`")
} This brings the panic (in the form of an except, we could use a |
@hds this would fix the panic location, but it doesn't fix the incorrect spawn location for #[track_caller]
pub(super) fn spawn_local_inner<F>(future: F, name: Option<&str>) -> JoinHandle<F::Output>
where F: Future + 'static,
F::Output: 'static
{
let location = std::panic::Location::caller();
CURRENT.with(move |maybe_cx| {
maybe_cx.get().map(|cx| cx.spawn(future, name, location))
})
.expect("`spawn_local` called from outside of a `task::LocalSet`")
} We probably need to do a check of other spawning functions that access a thread local similarly. |
Another simpler solution is to just clone the let maybe_cx = CURRENT.with(|maybe_cx| maybe_cx.get()); |
And here I was thinking that we needed to keep that context inside the closure for some reason... So this should solve both issues: #[track_caller]
pub(super) fn spawn_local_inner<F>(future: F, name: Option<&str>) -> JoinHandle<F::Output>
where F: Future + 'static,
F::Output: 'static
{
match CURRENT.with(|maybe_cx| maybe_cx.get()) {
None => panic!("`spawn_local` called from outside of a `task::LocalSet`"),
Some(cx) => cx.spawn(future, name)
}
} |
Uh oh!
There was an error while loading. Please reload this page.
Version
1.21.1
Platform
Description
Tracing is not implemented properly for local tasks. Consider the following complete example:
(Buildable project: tokio-spawn-local-repro.zip, run with

RUSTFLAGS="--cfg tokio_unstable" cargo run
)tokio-console
produces the following output:From my investigation it appears that the problem stems from a lacking application of
#[track_caller]
intokio/src/task/local.rs
:Notice that the closure has no
#[track_caller]
attribute, hence breaking the chain leading up to the call ofLocation::caller
inContex::spawn
, meaning all locations will refer to thespawn_local_inner
function body.#[track_caller]
attribute cannot be currently applied to closures (it's an unstable feature), so another approach is necessary.The text was updated successfully, but these errors were encountered: