| Age | Commit message (Collapse) | Author | Lines |
|
Skip stack overflow handler for panic=immediate-abort
std installs guard pages and a signal handler to ensure that stackoverflows 1) terminate abruptly and 2) print an nice message. Even for panic=immediate-abort, 1) is desirable, we don't want silent data corruption there. But 2) is completely unnecessary, as users deliberately *don't* want nice messages, they want minimum binary size.
Therefore, skip the entire guard signal handler setup, which saves a lot of bytes.
I tested this with a hello world binary using fat LTO, build-std, panic=immediate-abort, opt-level=s, strip=debuginfo.
`size` reports significant savings:
```
text data bss dec hex filename
15252 1032 104 16388 4004 tiny-before
6881 964 48 7893 1ed5 tiny-after2
```
`nm -U` goes from 71 to 56, getting rid of a bunch of stack overflow related symbols. The disk size goes from `31k` to `24k`.
The impact on the error message is minimal, as the message was already
missing.
before:
```
fish: Job 1, './tiny-so-before' terminated by signal SIGABRT (Abort)
```
after:
```
fish: Job 1, './tiny-so-after' terminated by signal SIGSEGV (Address boundary error)
```
I didn't test the Windows part, but it likely also has savings.
|
|
|
|
std installs guard pages and a signal handler to ensure that stackoverflows 1) terminate abruptly and 2) print an nice message. Even for panic=immediate-abort, 1) is desirable, we don't want silent data corruption there. But 2) is completely unnecessary, as users deliberately *don't* want nice messages, they want minimum binary size.
Therefore, skip the entire guard signal handler setup, which saves a lot of bytes.
I tested this with a hello world binary using fat LTO, build-std, panic=immediate-abort, opt-level=s, strip=debuginfo.
`size` reports significant savings:
```
text data bss dec hex filename
15252 1032 104 16388 4004 tiny-before
6881 964 48 7893 1ed5 tiny-after2
```
`nm -U` goes from 71 to 56, getting rid of a bunch of stack overflow related symbols. The disk size goes from `31k` to `24k`.
The impact on the error message is minimal, as the message was already
missing.
before:
```
fish: Job 1, './tiny-so-before' terminated by signal SIGABRT (Abort)
```
after:
```
fish: Job 1, './tiny-so-after' terminated by signal SIGSEGV (Address boundary error)
```
|
|
I.e. do not mark them as used, or non-speculative loaded, or similar.
Previously they were sometimes finalized during early resolution, causing issues like https://github.com/rust-lang/rust/pull/144793#issuecomment-3168108005.
|
|
|
|
This reverts commit 7ce620dd7c6fc3371290b40a1ea28146f0d37031.
The const-hacks introduces bugs, and they make the code harder to maintain.
Let's wait until we can constify these functions without changing their implementation.
|
|
std: optimize `dlsym!` macro and add a test for it
The `dlsym!` macro always ensures that the name string is nul-terminated, so there is no need to perform the check at runtime. Also, acquire loads are generally faster than a load and a barrier, so use them. This is only false in the case where the symbol is missing, but that shouldn't matter too much.
|
|
`dlsym` doesn't work for finding libc symbols on platforms like linux-musl, so the test will fail.
|
|
|
|
|
|
* Ensure nul-termination of the symbol name at compile-time
* Use an acquire load instead of a relaxed load and acquire fence
* Properly use `unsafe` and add safety comments
* Add tests
|
|
|
|
|
|
Mark pipe2 supported in Android
Android has supported pipe2 since 2010, long before the current min SDK.
|
|
std: haiku: fix `B_FIND_PATH_IMAGE_PATH`
Fixes https://github.com/rust-lang/rust/issues/145952, which was caused by https://github.com/rust-lang/libc/pull/4575
```````@rustbot``````` label T-libs O-haiku
|
|
|
|
|
|
std library: use execinfo library also on NetBSD.
The execinfo library is also available on NetBSD.
|
|
Android has supported pipe2 since 2010, long before the current min SDK.
|
|
|
|
|
|
libstd: init(): dup() subsequent /dev/nulls instead of opening them again
This will be faster, and also it deduplicates the code so win/win
The dup() is actually infallible here. But whatever.
Before:
```
poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 1 ([{fd=2, revents=POLLNVAL}])
openat(AT_FDCWD, "/dev/null", O_RDWR) = 2
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f5749313050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 2 ([{fd=0, revents=POLLNVAL}, {fd=2, revents=POLLNVAL}])
openat(AT_FDCWD, "/dev/null", O_RDWR) = 0
openat(AT_FDCWD, "/dev/null", O_RDWR) = 2
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7efe12006050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 3 ([{fd=0, revents=POLLNVAL}, {fd=1, revents=POLLNVAL}, {fd=2, revents=POLLNVAL}])
openat(AT_FDCWD, "/dev/null", O_RDWR) = 0
openat(AT_FDCWD, "/dev/null", O_RDWR) = 1
openat(AT_FDCWD, "/dev/null", O_RDWR) = 2
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7fc2dc7ca050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
```
After:
```
poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 1 ([{fd=1, revents=POLLNVAL}])
openat(AT_FDCWD, "/dev/null", O_RDWR) = 1
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f488a3fb050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 2 ([{fd=1, revents=POLLNVAL}, {fd=2, revents=POLLNVAL}])
openat(AT_FDCWD, "/dev/null", O_RDWR) = 1
dup(1) = 2
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a8943c050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 3 ([{fd=0, revents=POLLNVAL}, {fd=1, revents=POLLNVAL}, {fd=2, revents=POLLNVAL}])
openat(AT_FDCWD, "/dev/null", O_RDWR) = 0
dup(0) = 1
dup(0) = 2
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f4e3a4c7050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
```
|
|
library: Migrate from `cfg_if` to `cfg_select`
Migrate the standard library from using the external `cfg_if` crate to using the now-built-in `cfg_select` macro.
This does not yet eliminate the dependency from `library/std/Cargo.toml`, because while the standard library itself no longer uses `cfg_if`, it also incorporates the `backtrace` crate, which does.
Migration assisted by the following vim command (after selecting the full `cfg_if!` invocation):
```
'<,'>s/\(cfg_if::\)\?cfg_if/cfg_select/ | '<,'>s/^\( *\)} else {/\1}\r\1_ => {/c | '<,'>s/^\( *\)} else if #\[cfg(\(.*\))\] /\1}\r\1\2 => /e | '<,'>s/if #\[cfg(\(.*\))\] {/\1 => {/e
```
This is imperfect, but substantially accelerated the process. This prompts for confirmation on the `} else {` since that can also appear inside one of the arms. This also requires manual intervention to handle any multi-line conditions.
|
|
Migrate the standard library from using the external `cfg_if` crate to
using the now-built-in `cfg_select` macro.
This does not yet eliminate the dependency from
`library/std/Cargo.toml`, because while the standard library itself no
longer uses `cfg_if`, it also incorporates the `backtrace` crate, which
does.
Migration assisted by the following vim command (after selecting the
full `cfg_if!` invocation):
```
'<,'>s/\(cfg_if::\)\?cfg_if/cfg_select/ | '<,'>s/^\( *\)} else {/\1}\r\1_ => {/c | '<,'>s/^\( *\)} else if #\[cfg(\(.*\))\] /\1}\r\1\2 => /e | '<,'>s/if #\[cfg(\(.*\))\] {/\1 => {/e
```
This is imperfect, but substantially accelerated the process. This
prompts for confirmation on the `} else {` since that can also appear
inside one of the arms. This also requires manual intervention to handle
any multi-line conditions.
|
|
Currently, when setting the thread stack size fails, it would be rounded
up to the nearest multiple of the page size and the code asserts that
the next call to pthread_attr_setstacksize succeeds.
This may be true for glibc, but it isn't true for musl, which not only
enforces a minimum stack size, but also a maximum stack size of
usize::MAX / 4 - PTHREAD_STACK_MIN [1], triggering the assert rather
than erroring gracefully.
There isn't any way to handle this properly other than bailing out and
letting the user know it didn't succeed.
[1]: https://git.musl-libc.org/cgit/musl/tree/src/thread/pthread_attr_setstacksize.c#n5
Signed-off-by: Jens Reidel <adrian@travitia.xyz>
|
|
|
|
`panic!` does not print any identifying information for threads that are
unnamed. However, in many cases, the thread ID can be determined.
This changes the panic message from something like this:
thread '<unnamed>' panicked at src/main.rs:3:5:
explicit panic
To something like this:
thread '<unnamed>' (0xff9bf) panicked at src/main.rs:3:5:
explicit panic
Stack overflow messages are updated as well.
This change applies to both named and unnamed threads. The ID printed is
the OS integer thread ID rather than the Rust thread ID, which should
also be what debuggers print.
|
|
thread name in stack overflow message
Fixes rust-lang/rust#144481, which is caused by the thread name not being initialised yet when setting up the stack overflow information. Unfortunately, the stack overflow UI test did not test for the correct thread name being present, and testing this separately didn't occur to me when writing https://github.com/rust-lang/rust/pull/140628.
This PR contains the smallest possible fix I could think of: passing the thread name explicitly to the platform thread creation function. In the future I'd very much like to explore some possibilities around merging the thread packet and thread handle into one structure and using that in the platform code instead – but that's best left for another PR.
This PR also amends the stack overflow test to check for thread names, so we don't run into this again.
``@rustbot`` label +beta-nominated
|
|
|
|
If `HOME` is empty, use the fallback instead
This is a minor change in the `home_dir` api. An empty path is never (or should never be) valid so if the `HOME` environment variable is empty then let's use the fallback instead.
r? libs-api
|
|
|
|
The clock_nanosleep support is there to allow code using `sleep_until`
to run under Miri. Therefore the implementation is minimal.
- Only the clocks REALTIME and MONOTONIC are supported. The first is supported simply
because it was trivial to add not because it was needed for sleep_until.
- The only supported flag combinations are no flags or TIMER_ABSTIME only.
If an unsupported flag combination or clock is passed in this throws
unsupported.
|
|
Using clock nanosleep leads to more accurate sleep times on platforms
where it is supported.
To enable using clock_nanosleep this makes `sleep_until` platform
specific. That unfortunatly requires identical placeholder
implementations for the other platforms (windows/mac/wasm etc).
we will land platform specific implementations for those later. See the
`sleep_until` tracking issue.
This requires an accessors for the Instant type. As that accessor is only
used on the platforms that have clock_nanosleep it is marked as allow_unused.
32bit time_t targets do not use clock_nanosleep atm, they instead rely
on the same placeholder as the other platforms. We could make them
use clock_nanosleep too in the future using `__clock_nanosleep_time64`.
__clock_nanosleep_time64 is documented at:
https://www.gnu.org/software/libc/manual/html_node/64_002dbit-time-symbol-handling.html
|
|
r=ChrisDenton,tgross35
Implement send_signal for unix child processes
Tracking issue: rust-lang/rust#141975
There are two main differences between my implementation and the Public API section of the tracking issue. ~First, `send_signal` requires a mutable reference, like `Child::kill`.~ Second, `ChildExt` has `Sealed` as a supertrait, bringing it more in line with other extension traits like `CommandExt`.
try-job: `dist-various*`
try-job: `test-various*`
|
|
|
|
|
|
|
|
std: stop using TLS in signal handler
TLS is not async-signal-safe, making its use in the signal handler used to detect stack overflows unsound (c.f. #133698). POSIX however lists two thread-specific identifiers that can be obtained in a signal handler: the current `pthread_t` and the address of `errno`. Since `pthread_equal` is not AS-safe, `pthread_t` should be considered opaque, so for our purposes, `&errno` is the only option. This however works nicely: we can use the address as a key into a map that stores information for each thread. This PR uses a `BTreeMap` protected by a spin lock to hold the guard page address and thread name and thus fixes #133698.
|
|
|
|
VX_TASK_RENAME_LENGTH-1
|
|
TLS is not async-signal-safe, making its use in the signal handler used to detect stack overflows unsound (c.f. #133698). POSIX however lists two thread-specific identifiers that can be obtained in a signal handler: the current `pthread_t` and the address of `errno`. Since `pthread_equal` is not AS-safe, `pthread_t` should be considered opaque, so for our purposes, `&errno` is the only option. This however works nicely: we can use the address as a key into a map that stores information for each thread. This PR uses a `BTreeMap` protected by a spin lock to hold the guard page address and thread name and thus fixes #133698.
|
|
The Fuchsia bindings are currently spread out across multiple modules in `sys/pal/unix` leading to unnecessary duplication. This PR moves all of these definitions into `sys::pal::unix::fuchsia` and additionally:
* deduplicates the definitions
* makes the error names consistent
* marks some extern functions as safe
* removes unused items (there's no need to maintain these bindings if we're not going to use them)
* removes the documentation for the definitions (contributors should always consult the platform documentation, duplicating that here is just an extra maintenance burden)
|
|
std: use the address of `errno` to identify threads in `unique_thread_exit`
Getting the address of `errno` should be just as cheap as `pthread_self()` and avoids having to use the expensive `Mutex` logic because it always results in a pointer.
|
|
in core/alloc/std only for now, and ignoring test files
Co-authored-by: Pavel Grigorenko <GrigorenkoPV@ya.ru>
|
|
Rollup of 8 pull requests
Successful merges:
- #137653 (Deprecate the unstable `concat_idents!`)
- #138957 (Update the index of Option to make the summary more comprehensive)
- #140006 (ensure compiler existance of tools on the dist step)
- #140143 (Move `sys::pal::os::Env` into `sys::env`)
- #140202 (Make #![feature(let_chains)] bootstrap conditional in compiler/)
- #140236 (norm nested aliases before evaluating the parent goal)
- #140257 (Some drive-by housecleaning in `rustc_borrowck`)
- #140278 (Don't use item name to look up associated item from trait item)
r? `@ghost`
`@rustbot` modify labels: rollup
|
|
|
|
Although `Env` (as `Vars`), `Args`, path functions, and OS constants are
publicly exposed via `std::env`, their implementations are each
self-contained. Keep them separate in `std::sys` and make a new module,
`sys::env`, for `Env`.
|
|
Move `pal::env` to `std::sys::env_consts`
Combine the `std::env::consts` platform implementations as a single file. Use the Unix file as the base, since it has 28 entries, and fold the 8 singleton platforms into it. The Unix file was roughly grouped into Linux, Apple, BSD, and everything else, roughly in alphabetical order. Alphabetically order them to make it easier to maintain and discard the Unix-specific groups to generalize it to all platforms.
I'd prefer to have no fallback implementation, as I consider it a bug; however TEEOS, Trusty, and Xous have no definitions here. Since they otherwise have `pal` abstractions, that indicates that there are several platforms without `pal` abstractions which are also missing here. To support unsupported, create a little macro to handle the fallback case and not introduce ordering between the `cfg`s like `cfg_if!`.
I've named the module `std::sys::env_consts`, because they are used in `std::env::consts` and I intend to use the name `std::sys::env` for the combination of `Args` and `Vars`.
cc `@joboet` `@ChrisDenton`
Tracked in #117276.
|
|
|
|
They were roughly grouped into Linux, Apple, BSD, and everything else,
roughly in alphabetical order. Alphabetically order them to make it
easier to maintain and discard the Unix-specific groups to generalize it
to all platforms.
|