mirror of
https://github.com/fish-shell/fish-shell
synced 2024-11-10 07:04:29 +00:00
Add workaround for targets with too small a main stack size
pthread_get_stacksize_np() is buggy on legacy OS X; make sure you are building fish with a rust toolchain that correctly patches these functions. See https://github.com/macports/macports-legacy-support/pull/86
This commit is contained in:
parent
46f6aa8024
commit
57f558578b
2 changed files with 39 additions and 1 deletions
31
build.rs
31
build.rs
|
@ -73,6 +73,7 @@ fn detect_cfgs(target: &mut Target) {
|
|||
),
|
||||
("bsd", &detect_bsd),
|
||||
("gettext", &have_gettext),
|
||||
("small_main_stack", &has_small_stack),
|
||||
// See if libc supports the thread-safe localeconv_l(3) alternative to localeconv(3).
|
||||
("localeconv_l", &|target| {
|
||||
Ok(target.has_symbol("localeconv_l"))
|
||||
|
@ -169,6 +170,36 @@ fn have_gettext(target: &Target) -> Result<bool, Box<dyn Error>> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Rust sets the stack size of newly created threads to a sane value, but is at at the mercy of the
|
||||
/// OS when it comes to the size of the main stack. Some platforms we support default to a tiny
|
||||
/// 0.5 MiB main stack, which is insufficient for fish's MAX_EVAL_DEPTH/MAX_STACK_DEPTH values.
|
||||
///
|
||||
/// 0.5 MiB is small enough that we'd have to drastically reduce MAX_STACK_DEPTH to less than 10, so
|
||||
/// we instead use a workaround to increase the main thread size.
|
||||
fn has_small_stack(_: &Target) -> Result<bool, Box<dyn Error>> {
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
return Ok(false);
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
use core::ffi;
|
||||
|
||||
extern "C" {
|
||||
fn pthread_get_stacksize_np(thread: *const ffi::c_void) -> usize;
|
||||
fn pthread_self() -> *const ffi::c_void;
|
||||
}
|
||||
|
||||
// build.rs is executed on the main thread, so we are getting the main thread's stack size.
|
||||
// Modern macOS versions default to an 8 MiB main stack but legacy OS X have a 0.5 MiB one.
|
||||
let stack_size = unsafe { pthread_get_stacksize_np(pthread_self()) };
|
||||
const TWO_MIB: usize = 2 * 1024 * 1024;
|
||||
match stack_size {
|
||||
0..TWO_MIB => Ok(true),
|
||||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_paths() {
|
||||
fn get_path(name: &str, default: &str, onvar: PathBuf) -> PathBuf {
|
||||
let mut var = PathBuf::from(env::var(name).unwrap_or(default.to_string()));
|
||||
|
|
|
@ -461,7 +461,14 @@ fn cstr_from_osstr(s: &OsStr) -> CString {
|
|||
|
||||
fn main() {
|
||||
PROGRAM_NAME.set(L!("fish")).unwrap();
|
||||
panic_handler(throwing_main)
|
||||
if !cfg!(small_main_stack) {
|
||||
panic_handler(throwing_main);
|
||||
} else {
|
||||
// Create a new thread with a decent stack size to be our main thread
|
||||
std::thread::scope(|scope| {
|
||||
scope.spawn(|| panic_handler(throwing_main));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn throwing_main() -> i32 {
|
||||
|
|
Loading…
Reference in a new issue