-
Notifications
You must be signed in to change notification settings - Fork 13k
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
std: detect stack overflows in TLS destructors on UNIX #131282
base: master
Are you sure you want to change the base?
Conversation
☔ The latest upstream changes (presumably #135540) made this pull request unmergeable. Please resolve the merge conflicts. |
f46b255
to
83152c6
Compare
This comment has been minimized.
This comment has been minimized.
Fixes rust-lang#111272. With rust-lang#127912 merged, we now have all the infrastructure in place to support stack overflow detection in TLS destructors. This was not possible before because the signal stack was freed in the thread main function, thus a SIGSEGV afterwards would immediately crash. And on platforms without native TLS, the guard page address was stored in an allocation freed in a TLS destructor, so would not be available. rust-lang#127912 introduced the `local_pointer` macro which allows storing a pointer-sized TLS variable without allocation and the `thread_cleanup` runtime function which is called after all other code managed by the Rust runtime. This PR simply moves the signal stack cleanup to the end of `thread_cleanup` and uses `local_pointer` to store every necessary variable. And so, everything run under the Rust runtime is now properly protected against stack overflows.
83152c6
to
6620e2b
Compare
The logic was a little hard to follow in the code, but after looking at it for a bit it makes sense. @bors r+ |
…, r=Amanieu std: detect stack overflows in TLS destructors on UNIX Fixes rust-lang#111272. With rust-lang#127912 merged, we now have all the infrastructure in place to support stack overflow detection in TLS destructors. This was not possible before because the signal stack was freed in the thread main function, thus a SIGSEGV afterwards would immediately crash. And on platforms without native TLS, the guard page address was stored in an allocation freed in a TLS destructor, so would not be available. rust-lang#127912 introduced the `local_pointer` macro which allows storing a pointer-sized TLS variable without allocation and the `thread_cleanup` runtime function which is called after all other code managed by the Rust runtime. This PR simply moves the signal stack cleanup to the end of `thread_cleanup` and uses `local_pointer` to store every necessary variable. And so, everything run under the Rust runtime is now properly protected against stack overflows.
…iaskrgr Rollup of 8 pull requests Successful merges: - rust-lang#131282 (std: detect stack overflows in TLS destructors on UNIX) - rust-lang#134746 (Don't ICE in coerce when autoderef fails to structurally normalize non-WF type in new solver) - rust-lang#135790 (Update windows-gnu targets to set `DebuginfoKind::DWARF`) - rust-lang#135878 (ci: use 8 core arm runner for dist-aarch64-linux) - rust-lang#135879 (fix outdated file path ref in llvm) - rust-lang#135883 (Remove erroneous `unsafe` in `BTreeSet::upper_bound_mut`) - rust-lang#135884 (remove implied end of slice) - rust-lang#135898 (rustdoc-json-types: Finalize dyn compatibility renaming) r? `@ghost` `@rustbot` modify labels: rollup
I think this failed in rollup: #135906 (comment)
@bors r- |
I'm completely lost as to why this would fail. The stack overflow clearly gets detected properly (the correct message is printed), but the program still reports a success. Do stack overflows in TLS callback functions not lead to an abort? @ChrisDenton you know a lot more about Windows than I do, have you got any ideas? |
Hmm.. the stack overflow is happening while the thread is already exiting? I'm pretty sure in that case the exiting thread just returns the original exit code rather than changing it. If that's indeed the case (I'll double check when I have a moment) then I don't think there's anything we can reasonably do about it. |
Oh right, now that I'm more awake I think I can explain what's going on. Thread locals drops are run via a TLS callback function. When running the callback, any exceptions thrown (such as the stack overflow exception) will be essential caught and discarded. The callback function will end and further TLS callback functions won't run but neither will the normal exception behaviour. However, I'm finding it hard to find any official docs about exceptions in TLS callbacks. We do add a Vectored Exception Handler to print the stack overflow message. This should still happen because the handler is called before unwinding, etc. |
Mmmh. I guess this was always the case and should be fine... I'll just skip the test. |
Fixes #111272.
With #127912 merged, we now have all the infrastructure in place to support stack overflow detection in TLS destructors. This was not possible before because the signal stack was freed in the thread main function, thus a SIGSEGV afterwards would immediately crash. And on platforms without native TLS, the guard page address was stored in an allocation freed in a TLS destructor, so would not be available. #127912 introduced the
local_pointer
macro which allows storing a pointer-sized TLS variable without allocation and thethread_cleanup
runtime function which is called after all other code managed by the Rust runtime. This PR simply moves the signal stack cleanup to the end ofthread_cleanup
and useslocal_pointer
to store every necessary variable. And so, everything run under the Rust runtime is now properly protected against stack overflows.