about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-04-16 13:29:52 +0000
committerbors <bors@rust-lang.org>2015-04-16 13:29:52 +0000
commit5576b0558c7f46faa5331be72113238c677979b6 (patch)
tree4f99eb29429b44cbbf458b6350f8e71641efcfe1
parentac2b6f6066adeb79629604a92ecb871c642d045d (diff)
parent3e57c6c3ba0d7bfb6ad85915052406be1f218dbc (diff)
downloadrust-5576b0558c7f46faa5331be72113238c677979b6.tar.gz
rust-5576b0558c7f46faa5331be72113238c677979b6.zip
Auto merge of #24448 - alexcrichton:issue-24445, r=huonw
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
-rw-r--r--src/libstd/thread/local.rs2
-rw-r--r--src/test/run-make/issue-24445/Makefile12
-rw-r--r--src/test/run-make/issue-24445/foo.c16
-rw-r--r--src/test/run-make/issue-24445/foo.rs25
4 files changed, 54 insertions, 1 deletions
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index cc4031cc180..6d8f1cba709 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -373,7 +373,7 @@ mod imp {
                                       arg: *mut u8,
                                       dso_handle: *mut u8) -> libc::c_int;
             mem::transmute::<*const (), F>(__cxa_thread_atexit_impl)
-            (dtor, t, __dso_handle);
+            (dtor, t, &__dso_handle as *const _ as *mut _);
             return
         }
 
diff --git a/src/test/run-make/issue-24445/Makefile b/src/test/run-make/issue-24445/Makefile
new file mode 100644
index 00000000000..7a0cbfcf517
--- /dev/null
+++ b/src/test/run-make/issue-24445/Makefile
@@ -0,0 +1,12 @@
+-include ../tools.mk
+
+ifeq ($(UNAME),Linux)
+all:
+	$(RUSTC) foo.rs
+	$(CC) foo.c -lfoo -L $(TMPDIR) -Wl,--gc-sections -lpthread -o $(TMPDIR)/foo
+	$(call RUN,foo)
+	$(CC) foo.c -lfoo -L $(TMPDIR) -Wl,--gc-sections -lpthread -pie -fPIC -o $(TMPDIR)/foo
+	$(call RUN,foo)
+else
+all:
+endif
diff --git a/src/test/run-make/issue-24445/foo.c b/src/test/run-make/issue-24445/foo.c
new file mode 100644
index 00000000000..775e151f236
--- /dev/null
+++ b/src/test/run-make/issue-24445/foo.c
@@ -0,0 +1,16 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+void foo();
+
+int main() {
+    foo();
+    return 0;
+}
diff --git a/src/test/run-make/issue-24445/foo.rs b/src/test/run-make/issue-24445/foo.rs
new file mode 100644
index 00000000000..65e505df5ef
--- /dev/null
+++ b/src/test/run-make/issue-24445/foo.rs
@@ -0,0 +1,25 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "staticlib"]
+
+struct Destroy;
+impl Drop for Destroy {
+    fn drop(&mut self) { println!("drop"); }
+}
+
+thread_local! {
+    static X: Destroy = Destroy
+}
+
+#[no_mangle]
+pub extern "C" fn foo() {
+    X.with(|_| ());
+}