From 09c2f5714c28941944a4c338e6581828140e9185 Mon Sep 17 00:00:00 2001 From: Aeneas Tews Date: Sun, 20 Sep 2026 12:01:56 +0200 Subject: [PATCH] Fix macOS embedded Python worker stack size --- CHANGELOG.md | 9 +++++++++ src/serious_python_run.c | 28 +++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6015a3..c931318 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## Unreleased + +### macOS: give the embedded Python worker an 8 MiB stack + +The asynchronous worker now uses pthread attributes to request at least 8 MiB +on macOS. The default secondary-thread stack could be exhausted while loading +native scientific packages such as NumPy. Other platforms and synchronous runs +are unchanged. + ## 1.9.0 ### New export: `serious_python_hard_exit(int exit_code)` diff --git a/src/serious_python_run.c b/src/serious_python_run.c index 9045127..0648c1d 100644 --- a/src/serious_python_run.c +++ b/src/serious_python_run.c @@ -136,6 +136,9 @@ static int sp_getenv_present(const char* k) { #else #include #include +#if defined(__APPLE__) +#include +#endif // `used` is mainly for Darwin/Mach-O: dart_bridge is statically linked into // the host app, and some public entry points are discovered later via dlsym // / Dart FFI. Mark exported functions as used so the host linker's dead-strip @@ -667,7 +670,30 @@ EXPORT int serious_python_run(const sp_run_config_t* cfg) { CloseHandle((HANDLE)h); #else pthread_t thread; - if (pthread_create(&thread, NULL, sp_worker, st) != 0) { +#if defined(__APPLE__) && TARGET_OS_OSX + // The default macOS secondary-thread stack is too small for some Python + // native extensions (notably NumPy/OpenBLAS). Keep larger OS defaults. + pthread_attr_t attr; + if (pthread_attr_init(&attr) != 0) { + sp_state_free(st); + return -1; + } + size_t stack_size; + int attr_rc = pthread_attr_getstacksize(&attr, &stack_size); + if (attr_rc == 0 && stack_size < 8 * 1024 * 1024) { + attr_rc = pthread_attr_setstacksize(&attr, 8 * 1024 * 1024); + } + if (attr_rc != 0) { + pthread_attr_destroy(&attr); + sp_state_free(st); + return -1; + } + int create_rc = pthread_create(&thread, &attr, sp_worker, st); + pthread_attr_destroy(&attr); +#else + int create_rc = pthread_create(&thread, NULL, sp_worker, st); +#endif + if (create_rc != 0) { sp_state_free(st); return -1; }