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.
This commit is contained in:
Andrew Kaster 2020-12-30 01:44:05 -07:00 committed by Andreas Kling
parent bc0658ce27
commit 06b6f838d6

View file

@ -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