fix: make the stack handling more robust to sanitizers and -O3 (#6143)
This PR should make lean better-behaved around sanitizers, per https://github.com/google/sanitizers/issues/1688. As far as I can tell, https://github.com/google/sanitizers/wiki/AddressSanitizerUseAfterReturn#algorithm replaces local variables with heap allocations, and so taking the address of a local is not effective at producing a monotonic measure of stack usage. The approach used here is the same as the one used by clang.
This commit is contained in:
parent
1126407d9b
commit
5adcd520fa
1 changed files with 20 additions and 6 deletions
|
|
@ -73,6 +73,23 @@ size_t get_stack_size(bool main) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) 0 /* for non-clang compilers */
|
||||
#endif
|
||||
|
||||
// taken from https://github.com/llvm/llvm-project/blob/llvmorg-10.0.0-rc1/clang/lib/Basic/Stack.cpp#L24
|
||||
static void *get_stack_pointer() {
|
||||
#if __GNUC__ || __has_builtin(__builtin_frame_address)
|
||||
return __builtin_frame_address(0);
|
||||
#elif defined(_MSC_VER)
|
||||
return _AddressOfReturnAddress();
|
||||
#else
|
||||
char x = 0;
|
||||
char *volatile ptr = &x;
|
||||
return ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
LEAN_THREAD_VALUE(bool, g_stack_info_init, false);
|
||||
LEAN_THREAD_VALUE(size_t, g_stack_size, 0);
|
||||
LEAN_THREAD_VALUE(size_t, g_stack_base, 0);
|
||||
|
|
@ -81,8 +98,7 @@ LEAN_THREAD_VALUE(size_t, g_stack_threshold, 0);
|
|||
void save_stack_info(bool main) {
|
||||
g_stack_info_init = true;
|
||||
g_stack_size = get_stack_size(main);
|
||||
char x;
|
||||
g_stack_base = reinterpret_cast<size_t>(&x);
|
||||
g_stack_base = reinterpret_cast<size_t>(get_stack_pointer());
|
||||
/* g_stack_threshold is a redundant value used to optimize check_stack */
|
||||
g_stack_threshold = g_stack_base + LEAN_STACK_BUFFER_SPACE - g_stack_size;
|
||||
if (g_stack_threshold > g_stack_base + LEAN_STACK_BUFFER_SPACE) {
|
||||
|
|
@ -92,8 +108,7 @@ void save_stack_info(bool main) {
|
|||
}
|
||||
|
||||
size_t get_used_stack_size() {
|
||||
char y;
|
||||
size_t curr_stack = reinterpret_cast<size_t>(&y);
|
||||
size_t curr_stack = reinterpret_cast<size_t>(get_stack_pointer());
|
||||
return g_stack_base - curr_stack;
|
||||
}
|
||||
|
||||
|
|
@ -113,8 +128,7 @@ void throw_stack_space_exception(char const * component_name) {
|
|||
void check_stack(char const * component_name) {
|
||||
if (!g_stack_info_init)
|
||||
save_stack_info(false);
|
||||
char y;
|
||||
size_t curr_stack = reinterpret_cast<size_t>(&y);
|
||||
size_t curr_stack = reinterpret_cast<size_t>(get_stack_pointer());
|
||||
if (curr_stack < g_stack_threshold)
|
||||
throw_stack_space_exception(component_name);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue