summaryrefslogtreecommitdiff
path: root/AK
diff options
context:
space:
mode:
authorAndrew Kaster <andrewdkaster@gmail.com>2020-12-30 01:44:05 -0700
committerAndreas Kling <kling@serenityos.org>2020-12-30 11:28:50 +0100
commit06b6f838d65499beaca6272267a905a245e21b61 (patch)
treeb20edaf951054187d0ccc379043b55613d68f330 /AK
parentbc0658ce27833f990ca2c4c83088a6cd57ac2e17 (diff)
downloadserenity-06b6f838d65499beaca6272267a905a245e21b61.zip
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.
Diffstat (limited to 'AK')
-rw-r--r--AK/StackInfo.cpp21
1 files 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