From 06b6f838d65499beaca6272267a905a245e21b61 Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Wed, 30 Dec 2020 01:44:05 -0700 Subject: [PATCH] AK: Use MacOS pthread_get_stacksize_np to get stack size for StackInfo Seems Rust and OpenJDK both had issues with getting accurate stack size for the main thread with MacOS Maverick and above. Apply a variant of their workarounds. We could probably assume 8MB in all cases just to be safe, as the only user of AK::StackInfo right now is lib JS's heap for determining possible pointer candidates. But, this approach should work if userspace apps start trying to add custom guard pages, as well. --- AK/StackInfo.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/AK/StackInfo.cpp b/AK/StackInfo.cpp index fb66f199dc..abf786a810 100644 --- a/AK/StackInfo.cpp +++ b/AK/StackInfo.cpp @@ -55,13 +55,22 @@ StackInfo::StackInfo() } pthread_attr_destroy(&attr); #elif __APPLE__ - m_base = (FlatPtr)pthread_get_stackaddr_np(pthread_self()); - pthread_attr_t attr = {}; - if (int rc = pthread_attr_getstacksize(&attr, &m_size) != 0) { - fprintf(stderr, "pthread_attr_getstacksize: %s\n", strerror(-rc)); - ASSERT_NOT_REACHED(); + // NOTE: !! On MacOS, pthread_get_stackaddr_np gives the TOP of the stack, not the bottom! + FlatPtr top_of_stack = (FlatPtr)pthread_get_stackaddr_np(pthread_self()); + m_size = (size_t)pthread_get_stacksize_np(pthread_self()); + // https://github.com/rust-lang/rust/issues/43347#issuecomment-316783599 + // https://developer.apple.com/library/archive/qa/qa1419/_index.html + // + // MacOS seems inconsistent on what stack size is given for the main thread. + // According to the Apple docs, default for main thread is 8MB, and default for + // other threads is 512KB + constexpr size_t eight_megabytes = 0x800000; + if (pthread_main_np() == 1 && m_size < eight_megabytes) { + // Assume no one messed with stack size linker options for the main thread, + // and just set it to 8MB. + m_size = eight_megabytes; } - pthread_attr_destroy(&attr); + m_base = top_of_stack - m_size; #else ASSERT_NOT_REACHED(); #endif