Fix __pthread_get_minstack()

This is the function that should take into account TLS block, and 1MB is
too high, since it will be used for sigaltstack() on SIGSEGV

v0: copy-paste glibc __pthread_get_minstack()
v2: return static 16K instead of 1MB
This commit is contained in:
Azat Khuzhin 2021-06-19 17:34:28 +03:00
parent 57960746e2
commit 0286673f8f

View File

@ -9,14 +9,36 @@ extern "C" {
#endif #endif
#include <pthread.h> #include <pthread.h>
#include <unistd.h>
#include <limits.h>
#include <assert.h>
/// glibc __pthread_get_minstack() will take TLS into account for the minimal
/// stack size (since you cannot use stack less then TLS block size, otherwise
/// some variables may be overwritten)
///
/// So glibc implementation is:
///
/// sysconf(_SC_PAGESIZE) + __static_tls_size + PTHREAD_STACK_MIN;
///
/// But this helper cannot do this since:
/// - __pthread_get_minstack() is hidden in libc (note that rust tried to do
/// this but revert it to retry loop, for compatibility, while we cannot
/// use retry loop since this function is used for sigaltstack())
/// - __static_tls_size is not exported in glibc
/// - it is not used anywhere except for clickhouse itself (for sigaltstack(),
/// to handle SIGSEGV only) and using PTHREAD_STACK_MIN (16k) is enough right
/// now.
///
/// Also we cannot use getStackSize() (pthread_attr_getstack()) since it will
/// return 8MB, and this is too huge for signal stack.
size_t __pthread_get_minstack(const pthread_attr_t * attr) size_t __pthread_get_minstack(const pthread_attr_t * attr)
{ {
return 1048576; /// This is a guess. Don't sure it is correct. _Static_assert(PTHREAD_STACK_MIN == 16<<10, "Too small return value of __pthread_get_minstack()");
return PTHREAD_STACK_MIN;
} }
#include <signal.h> #include <signal.h>
#include <unistd.h>
#include <string.h> #include <string.h>
#include <sys/syscall.h> #include <sys/syscall.h>