From 6e59675459bc6f396b586da4acccd60a94f9ba5a Mon Sep 17 00:00:00 2001 From: Marcus Calhoun-Lopez Date: Mon, 6 May 2024 06:10:47 -0700 Subject: [PATCH] provide workaround for pthread_get_stacksize_np see https://github.com/rust-lang/rust/issues/43347 fixes https://trac.macports.org/ticket/68015 --- README.md | 5 +++ include/MacportsLegacySupport.h | 7 ++++ src/add_symbols.c | 7 ++++ src/pthread_get_stacksize_np.c | 70 +++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+) create mode 100644 src/pthread_get_stacksize_np.c diff --git a/README.md b/README.md index 9551e8b..4d509ca 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,11 @@ Wrapped headers and replaced functions are: Adds _fstatat$INODE64 library symbol OSX10.9 + + - + Provides a workaround for bug in pthread_get_stacksize_np + OSX10.4, OSX10.5, OSX10.9, OSX10.10 + For information on building this library outside MacPorts, see BUILDING.txt. diff --git a/include/MacportsLegacySupport.h b/include/MacportsLegacySupport.h index f1bc4cc..5867647 100644 --- a/include/MacportsLegacySupport.h +++ b/include/MacportsLegacySupport.h @@ -201,4 +201,11 @@ /* library symbol _dirfd */ #define __MP_LEGACY_SUPPORT_SYMBOL__dirfd__ (__APPLE__ && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1080) +/* fix bug in pthread_get_stacksize_np */ +/* see https://github.com/rust-lang/rust/issues/43347 */ +#define __MP_LEGACY_SUPPORT_PTHREAD_GET_STACKSIZE_NP_FIX__ (__APPLE__ && ( \ + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ == 101000 || \ + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ == 1090 || \ + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1060 )) + #endif /* _MACPORTS_LEGACYSUPPORTDEFS_H_ */ diff --git a/src/add_symbols.c b/src/add_symbols.c index 76aa34a..58aadd2 100644 --- a/src/add_symbols.c +++ b/src/add_symbols.c @@ -81,3 +81,10 @@ extern const char fstatat$INODE64_tmp7 __asm("$ld$add$os10.7$_fstatat$INODE64"); extern const char fstatat$INODE64_tmp8 __asm("$ld$add$os10.8$_fstatat$INODE64"); __attribute__((visibility("default"))) const char fstatat$INODE64_tmp8 = 0; extern const char fstatat$INODE64_tmp9 __asm("$ld$add$os10.9$_fstatat$INODE64"); __attribute__((visibility("default"))) const char fstatat$INODE64_tmp9 = 0; #endif + +#if !(__MP_LEGACY_SUPPORT_PTHREAD_GET_STACKSIZE_NP_FIX__) +extern const char pthread_get_stacksize_np_tmp4 __asm("$ld$add$os10.4$_pthread_get_stacksize_np"); __attribute__((visibility("default"))) const char pthread_get_stacksize_np_tmp4 = 0; +extern const char pthread_get_stacksize_np_tmp5 __asm("$ld$add$os10.5$_pthread_get_stacksize_np"); __attribute__((visibility("default"))) const char pthread_get_stacksize_np_tmp5 = 0; +extern const char pthread_get_stacksize_np_tmp9 __asm("$ld$add$os10.9$_pthread_get_stacksize_np"); __attribute__((visibility("default"))) const char pthread_get_stacksize_np_tmp9 = 0; +extern const char pthread_get_stacksize_np_tmp10 __asm("$ld$add$os10.10$_pthread_get_stacksize_np"); __attribute__((visibility("default"))) const char pthread_get_stacksize_np_tmp10 = 0; +#endif diff --git a/src/pthread_get_stacksize_np.c b/src/pthread_get_stacksize_np.c new file mode 100644 index 0000000..6c2051b --- /dev/null +++ b/src/pthread_get_stacksize_np.c @@ -0,0 +1,70 @@ +/* MP support header */ +#include "MacportsLegacySupport.h" +#if __MP_LEGACY_SUPPORT_PTHREAD_GET_STACKSIZE_NP_FIX__ + +#include +#include +#include +#include + +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1090 +/* private system call available on OS X Mavericks (version 10.9) and later */ +/* see https://github.com/apple-oss-distributions/libpthread/blob/ba8e1488a0e6848b710c5daad2e226f66cfed656/private/pthread/private.h#L34 */ +pthread_t pthread_main_thread_np(void); +#endif + +#define kMaxThreadStackSize 0x40000000 /* from LLVM: 1 << 30 or 1Gb */ + +size_t pthread_get_stacksize_np(pthread_t t) { +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1090 + int is_main_thread = pthread_equal(t, pthread_main_thread_np()); +#else + /* taken from Apple Libc */ + /* see https://github.com/apple-oss-distributions/Libc/blob/224a8105d573730ae33f474ae5b63b113123aee4/pthreads/pthread.c#L1167 */ + /* for _PTHREAD_CREATE_PARENT, see https://github.com/apple-oss-distributions/Libc/blob/224a8105d573730ae33f474ae5b63b113123aee4/pthreads/pthread_internals.h#L647C9-L647C31 */ + /* for pthread_t, see https://github.com/apple-oss-distributions/Libc/blob/224a8105d573730ae33f474ae5b63b113123aee4/pthreads/pthread_internals.h#L107 */ + /* for pthread_lock_t, see https://github.com/apple-oss-distributions/Libc/blob/224a8105d573730ae33f474ae5b63b113123aee4/pthreads/pthread_machdep.h#L214C13-L214C27 */ + struct + { + long sig; + struct __darwin_pthread_handler_rec *cleanup_stack; + int lock; + __int32_t detached:8, + inherit:8, + policy:8, + freeStackOnExit:1, + newstyle:1, + kernalloc:1, + schedset:1, + wqthread:1, + pad:3; + char opaque[__PTHREAD_SIZE__-sizeof(int)-sizeof(__int32_t)]; + } *thread = (void*) t; + int is_main_thread = ((thread->detached & 4) == 4); +#endif + if ( is_main_thread ) { + /* use LLVM workaround */ + /* see https://github.com/llvm/llvm-project/blob/617a15a9eac96088ae5e9134248d8236e34b91b1/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp#L414 */ + /* OpenJDK also has a workaround */ + /* see https://github.com/openjdk/jdk/blob/e833bfc8ac6104522d037e7eb300f5aa112688bb/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp#L715 */ + struct rlimit limit; + if( getrlimit(RLIMIT_STACK, &limit) ) { + exit(EXIT_FAILURE); + } + if( limit.rlim_cur < kMaxThreadStackSize ) { + return limit.rlim_cur; + } else { + return kMaxThreadStackSize; + } + } else { + /* bug only affects main thread */ + size_t (*real_pthread_get_stacksize_np)(pthread_t); + real_pthread_get_stacksize_np = dlsym(RTLD_NEXT, "pthread_get_stacksize_np"); + if (real_pthread_get_stacksize_np == NULL) { + exit(EXIT_FAILURE); + } + return real_pthread_get_stacksize_np(t); + } +} + +#endif /* __MP_LEGACY_SUPPORT_PTHREAD_GET_STACKSIZE_NP_FIX__ */