From 63c88001000a2bf0729bf79df7ced276732babe1 Mon Sep 17 00:00:00 2001 From: Will Dietz Date: Thu, 31 Mar 2022 12:37:52 -0500 Subject: [PATCH] Help Clang find bottom of stacks for safety, use desired stack size noteBottomOfStack: Without this, checks against stack space within Clang don't work as Clang doesn't know where the stack begins. Needed per-thread, as early as possible. (on threads using Clang) Using Clang's desired stack size: Additionally increase stack size of pthreads to Clang's desired size. This is presently 8MB, and is used by Clang's stack management mechanisms to check* if close to stack exhaustion when determining if there's sufficient space (and warn or run on a new thread with more). (see runWithSufficientStackSpace) The constant is available in LLVM 7 onwards. * (abs(cur - bottom) > DesiredStackSize - threshold) --- src/main.cc | 7 ++++++- src/platform_posix.cc | 20 ++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/main.cc b/src/main.cc index eb18d26c..dbd21302 100644 --- a/src/main.cc +++ b/src/main.cc @@ -8,6 +8,7 @@ #include "test.hh" #include "working_files.hh" +#include #include #include #include @@ -78,8 +79,12 @@ int main(int argc, char **argv) { pipeline::init(); const char *env = getenv("CCLS_CRASH_RECOVERY"); - if (!env || strcmp(env, "0") != 0) + if (!env || strcmp(env, "0") != 0) { CrashRecoveryContext::Enable(); +#if LLVM_VERSION_MAJOR >= 10 // rL369940 + clang::noteBottomOfStack(); // per-thread, needed to avoid stack exhaustion +#endif + } bool language_server = true; diff --git a/src/platform_posix.cc b/src/platform_posix.cc index 885e9557..33719573 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -27,6 +27,8 @@ #include #endif +#include + #include #include @@ -61,18 +63,32 @@ void traceMe() { raise(traceme[0] == 's' ? SIGSTOP : SIGTSTP); } +struct ThreadInfo { + void *(*fn)(void *); + void *arg; +}; + +void *threadWrapper(void *arg) { + ThreadInfo ti = *(ThreadInfo *)arg; + delete (ThreadInfo *)arg; +#if LLVM_VERSION_MAJOR >= 10 // rL369940 + clang::noteBottomOfStack(); // per-thread, needed to avoid stack exhaustion +#endif + return ti.fn(ti.arg); +} + void spawnThread(void *(*fn)(void *), void *arg) { pthread_t thd; pthread_attr_t attr; struct rlimit rlim; - size_t stack_size = 4 * 1024 * 1024; + size_t stack_size = clang::DesiredStackSize; if (getrlimit(RLIMIT_STACK, &rlim) == 0 && rlim.rlim_cur != RLIM_INFINITY) stack_size = rlim.rlim_cur; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_attr_setstacksize(&attr, stack_size); pipeline::threadEnter(); - pthread_create(&thd, &attr, fn, arg); + pthread_create(&thd, &attr, threadWrapper, new ThreadInfo{fn, arg}); pthread_attr_destroy(&attr); } } // namespace ccls