Skip to content

Invoking TLD on task destruction yields an opaque error message #14807

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

Closed
alexcrichton opened this issue Jun 11, 2014 · 3 comments
Closed

Invoking TLD on task destruction yields an opaque error message #14807

alexcrichton opened this issue Jun 11, 2014 · 3 comments
Labels
A-runtime Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows P-low Low priority

Comments

@alexcrichton
Copy link
Member

local_data_key!(foo: Foo)

struct Foo;

impl Drop for Foo {
    fn drop(&mut self) {
        foo.replace(Some(Foo));
    }
}

fn main() {
    foo.replace(Some(Foo));
}

error:

failed at 'must have a local task to insert into TLD', /Users/rustbuild/src/rust-buildbot/slave/nightly-mac/build/src/librustrt/local_data.rs:159
run with `RUST_BACKTRACE=1` to see a backtrace

You've met with a terrible fate, haven't you?

fatal runtime error: Could not unwind stack, error = 5
zsh: illegal hardware instruction  ./foo

I believe we should take a more principled approach to this:

  1. take() the local task's TLD map.
  2. Drop the TLD map. If this re-invokes TLD, the missing TLD map in the task will be re-initialized.
  3. Repeat steps 1-2 a fixed number of times while the map was re-initialized.
  4. Abort with a nice error message if the map is still initialized. Otherwise continue invoking GC destructors.

Nominating, but I don't believe this blocks 1.0

@pnkfelix
Copy link
Member

Assigning P-low, not blocking 1.0.

@steveklabnik
Copy link
Member

Okay, so this API has changed significantly, but I think this is it:

thread_local!(static foo: Foo = Foo);

struct Foo;

impl Drop for Foo {
    fn drop(&mut self) {
        foo.with(|f| {
        });
    }
}

fn main() {
    let f = Foo;
}

yields

thread '<main>' panicked at 'cannot access a TLS value during or after it is destroyed', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/option.rs:330
fatal runtime error: Could not unwind stack, error = 5
/bin/bash: line 1: 14786 Illegal instruction     ./hello

that error seems much more clear. And its documentation says

This function will panic!() if the key currently has its destructor running,

So I'd consider this closed. What do you think, @alexcrichton

@alexcrichton
Copy link
Member Author

I agree!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-runtime Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows P-low Low priority
Projects
None yet
Development

No branches or pull requests

3 participants