We currently detect the address of the stack guard page and even try to create one if it’s not created by the operating system. However, it has been almost impossible to get things right because stack guards can exist or not exist depending on OS, kernel version, build configuration and the methods differs between different implementation of pthread library.
The main purpose of the stack guard is to ensure and allow us to detect stack overflow. Here I propose an alternative approach that solely relies on what a signal handler provides.
In short, the idea is to determine both the fault address and the stack pointer when the memory access violation occur. Then we can compare them, check if they’re in single page (assuming stack probe is supported) and we can now detect stack overflow.
From sigaction(3p):
If SA_SIGINFO is set and the signal is caught, the signal-catching function shall be entered as:
void func(int signo, siginfo_t *info, void *context);
where two additional arguments are passed to the signal-catching function. The second argument shall point to an object of type sig‐
info_t explaining the reason why the signal was generated; the third argument can be cast to a pointer to an object of type ucon‐
text_t to refer to the receiving thread's context that was interrupted when the signal was delivered.
While the type of context is opaque for the POSIX spec, we can expect it to be properly defined in kernel headers for each platform, unlike stack guard which is merely a security feature of the OS.