Skip to content

Commit b317cda

Browse files
authored
Rollup merge of #122847 - workingjubilee:suggest-rust-min-stack-workaround-on-overflow, r=TaKO8Ki
Suggest `RUST_MIN_STACK` workaround on overflow For some Rust crates, like p384, we can't do a whole lot about it even if the stack overflow is reported like in #122357 because the problem may be inside LLVM or another codegen backend. We can, however, suggest people set a new `RUST_MIN_STACK` value while handling the SIGSEGV, as that stack-setting will carry forward into the dylib. As a bonus, this also leads to cleaning up the stack-setting code a bit.
2 parents 7481c0e + 5425338 commit b317cda

File tree

2 files changed

+23
-16
lines changed

2 files changed

+23
-16
lines changed

Diff for: compiler/rustc_driver_impl/src/signal_handler.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Signal handler for rustc
22
//! Primarily used to extract a backtrace from stack overflow
33
4+
use rustc_interface::util::{DEFAULT_STACK_SIZE, STACK_SIZE};
45
use std::alloc::{alloc, Layout};
56
use std::{fmt, mem, ptr};
67

@@ -100,7 +101,10 @@ extern "C" fn print_stack_trace(_: libc::c_int) {
100101
written += 1;
101102
}
102103
raw_errln!("note: we would appreciate a report at https://github.com/rust-lang/rust");
103-
written += 1;
104+
// get the current stack size WITHOUT blocking and double it
105+
let new_size = STACK_SIZE.get().copied().unwrap_or(DEFAULT_STACK_SIZE) * 2;
106+
raw_errln!("help: you can increase rustc's stack size by setting RUST_MIN_STACK={new_size}");
107+
written += 2;
104108
if written > 24 {
105109
// We probably just scrolled the earlier "we got SIGSEGV" message off the terminal
106110
raw_errln!("note: backtrace dumped due to SIGSEGV! resuming signal");

Diff for: compiler/rustc_interface/src/util.rs

+18-15
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,20 @@ pub fn add_configuration(cfg: &mut Cfg, sess: &mut Session, codegen_backend: &dy
4848
}
4949
}
5050

51-
const STACK_SIZE: usize = 8 * 1024 * 1024;
52-
53-
fn get_stack_size() -> Option<usize> {
54-
// FIXME: Hacks on hacks. If the env is trying to override the stack size
55-
// then *don't* set it explicitly.
56-
env::var_os("RUST_MIN_STACK").is_none().then_some(STACK_SIZE)
51+
pub static STACK_SIZE: OnceLock<usize> = OnceLock::new();
52+
pub const DEFAULT_STACK_SIZE: usize = 8 * 1024 * 1024;
53+
54+
fn init_stack_size() -> usize {
55+
// Obey the environment setting or default
56+
*STACK_SIZE.get_or_init(|| {
57+
env::var_os("RUST_MIN_STACK")
58+
.map(|os_str| os_str.to_string_lossy().into_owned())
59+
// ignore if it is set to nothing
60+
.filter(|s| s.trim() != "")
61+
.map(|s| s.trim().parse::<usize>().unwrap())
62+
// otherwise pick a consistent default
63+
.unwrap_or(DEFAULT_STACK_SIZE)
64+
})
5765
}
5866

5967
pub(crate) fn run_in_thread_with_globals<F: FnOnce() -> R + Send, R: Send>(
@@ -66,10 +74,7 @@ pub(crate) fn run_in_thread_with_globals<F: FnOnce() -> R + Send, R: Send>(
6674
// the parallel compiler, in particular to ensure there is no accidental
6775
// sharing of data between the main thread and the compilation thread
6876
// (which might cause problems for the parallel compiler).
69-
let mut builder = thread::Builder::new().name("rustc".to_string());
70-
if let Some(size) = get_stack_size() {
71-
builder = builder.stack_size(size);
72-
}
77+
let builder = thread::Builder::new().name("rustc".to_string()).stack_size(init_stack_size());
7378

7479
// We build the session globals and run `f` on the spawned thread, because
7580
// `SessionGlobals` does not impl `Send` in the non-parallel compiler.
@@ -120,7 +125,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
120125
});
121126
}
122127

123-
let mut builder = rayon::ThreadPoolBuilder::new()
128+
let builder = rayon::ThreadPoolBuilder::new()
124129
.thread_name(|_| "rustc".to_string())
125130
.acquire_thread_handler(jobserver::acquire_thread)
126131
.release_thread_handler(jobserver::release_thread)
@@ -144,10 +149,8 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
144149
on_panic.disable();
145150
})
146151
.unwrap();
147-
});
148-
if let Some(size) = get_stack_size() {
149-
builder = builder.stack_size(size);
150-
}
152+
})
153+
.stack_size(init_stack_size());
151154

152155
// We create the session globals on the main thread, then create the thread
153156
// pool. Upon creation, each worker thread created gets a copy of the

0 commit comments

Comments
 (0)