Improve stack overflow recovery

It's now possible to use sigaltstack() to recover from stack overflows
on Windows. Several bugs in sigaltstack() have been fixed, for all our
supported platforms. There's a newer better example showing how to use
this, along with three independent unit tests just to further showcase
the various techniques.
This commit is contained in:
Justine Tunney 2023-10-04 07:07:43 -07:00
parent 1694edf85c
commit 4631d34d0d
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
24 changed files with 590 additions and 274 deletions

View file

@ -31,6 +31,7 @@
#include "libc/intrin/bsr.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/dll.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/log/internal.h"
@ -38,6 +39,9 @@
#include "libc/mem/alloca.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/crc32.h"
#include "libc/nt/enum/memflags.h"
#include "libc/nt/enum/pageflags.h"
#include "libc/nt/memory.h"
#include "libc/nt/runtime.h"
#include "libc/nt/synchronization.h"
#include "libc/runtime/runtime.h"
@ -210,9 +214,19 @@ static errno_t pthread_create_impl(pthread_t *thread,
-1, 0, 0) != pt->attr.__stackaddr) {
notpossible;
}
if (pt->attr.__guardsize && !IsWindows() &&
mprotect(pt->attr.__stackaddr, pt->attr.__guardsize, PROT_NONE)) {
notpossible;
if (pt->attr.__guardsize) {
if (!IsWindows()) {
if (mprotect(pt->attr.__stackaddr, pt->attr.__guardsize,
PROT_NONE)) {
notpossible;
}
} else {
uint32_t oldattr;
if (!VirtualProtect(pt->attr.__stackaddr, pt->attr.__guardsize,
kNtPageReadwrite | kNtPageGuard, &oldattr)) {
notpossible;
}
}
}
}
}
@ -227,7 +241,7 @@ static errno_t pthread_create_impl(pthread_t *thread,
}
}
pt->pt_flags |= PT_OWNSTACK;
if (IsAsan() && pt->attr.__guardsize) {
if (IsAsan() && !IsWindows() && pt->attr.__guardsize) {
__asan_poison(pt->attr.__stackaddr, pt->attr.__guardsize,
kAsanStackOverflow);
}