Skip to content
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

thread_local!s with destructors segfault in non-PIE executables #24445

Closed
huonw opened this issue Apr 15, 2015 · 0 comments · Fixed by #24448
Closed

thread_local!s with destructors segfault in non-PIE executables #24445

huonw opened this issue Apr 15, 2015 · 0 comments · Fixed by #24448

Comments

@huonw
Copy link
Member

huonw commented Apr 15, 2015

void foo();
int main()
{
    foo();
    return 0;
}
#![crate_type = "staticlib"]

struct Destroy;
impl Drop for Destroy { fn drop(&mut self) {} }

thread_local! {
    static X: Destroy = Destroy
}

#[no_mangle]
pub extern "C" fn foo() {
    X.with(|_| ());
}
rustc staticlib2.rs
gcc staticlib2.c libstaticlib2.a -ldl -lpthread -lrt -lgcc_s -lpthread -lc -lm -o staticlib2
gcc staticlib2.c -pie libstaticlib2.a -ldl -lpthread -lrt -lgcc_s -lpthread -lc -lm -o staticlib2-pie

staticlib2 segfaults, staticlib2-pie doesn't.

This is possibly/probably the expected behaviour, but it would be quite nice to not cause a segfault or at least find some way to help the user get it right. (cc http://stackoverflow.com/q/29632715/1256624)

alexcrichton added a commit to alexcrichton/rust that referenced this issue Apr 15, 2015
One of the parameters to the magical "register a thread-local destructor"
function is called `__dso_handle` and largely just passed along (this seems to
be what other implementations do). Currently we pass the *value* of this symbol,
but apparently the correct piece of information to pass is the *address* of the
symbol.

In a PIE binary the symbol actually contains an address to itself which is why
we've gotten away with what we're doing as long as we have. In a non-PIE binary
the symbol contains the address `NULL`, causing a segfault in the runtime
library if it keeps going.

Closes rust-lang#24445
Manishearth added a commit to Manishearth/rust that referenced this issue Apr 15, 2015
One of the parameters to the magical "register a thread-local destructor"
function is called `__dso_handle` and largely just passed along (this seems to
be what other implementations do). Currently we pass the *value* of this symbol,
but apparently the correct piece of information to pass is the *address* of the
symbol.

In a PIE binary the symbol actually contains an address to itself which is why
we've gotten away with what we're doing as long as we have. In a non-PIE binary
the symbol contains the address `NULL`, causing a segfault in the runtime
library if it keeps going.

Closes rust-lang#24445
alexcrichton added a commit to alexcrichton/rust that referenced this issue Apr 15, 2015
One of the parameters to the magical "register a thread-local destructor"
function is called `__dso_handle` and largely just passed along (this seems to
be what other implementations do). Currently we pass the *value* of this symbol,
but apparently the correct piece of information to pass is the *address* of the
symbol.

In a PIE binary the symbol actually contains an address to itself which is why
we've gotten away with what we're doing as long as we have. In a non-PIE binary
the symbol contains the address `NULL`, causing a segfault in the runtime
library if it keeps going.

Closes rust-lang#24445
bors added a commit that referenced this issue Apr 16, 2015
One of the parameters to the magical "register a thread-local destructor"
function is called `__dso_handle` and largely just passed along (this seems to
be what other implementations do). Currently we pass the *value* of this symbol,
but apparently the correct piece of information to pass is the *address* of the
symbol.

In a PIE binary the symbol actually contains an address to itself which is why
we've gotten away with what we're doing as long as we have. In a non-PIE binary
the symbol contains the address `NULL`, causing a segfault in the runtime
library if it keeps going.

Closes #24445
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant