diff --git a/runtime/src/main/cpp/Porting.cpp b/runtime/src/main/cpp/Porting.cpp index 315700c8925..c6d1571a272 100644 --- a/runtime/src/main/cpp/Porting.cpp +++ b/runtime/src/main/cpp/Porting.cpp @@ -119,7 +119,7 @@ void consolePrintf(const char* format, ...) { #if !KONAN_NO_THREADS pthread_key_t terminationKey; -pthread_once_t terminationKeyOnceControl = PTHREAD_ONCE_INIT; +pthread_once_t terminationKeyOnceControl = PTHREAD_ONCE_INIT; typedef void (*destructor_t)(void*); @@ -140,7 +140,19 @@ static void onThreadExitCallback(void* value) { pthread_setspecific(terminationKey, nullptr); } +#if KONAN_LINUX +static pthread_key_t dummyKey; +#endif static void onThreadExitInit() { +#if KONAN_LINUX + // Due to glibc bug we have to create first key as dummy, to avoid + // conflicts with potentially uninitialized dlfcn error key. + // https://code.woboq.org/userspace/glibc/dlfcn/dlerror.c.html#237 + // As one may see, glibc checks value of the key even if it was not inited (and == 0), + // and so data associated with our legit key (== 0 as being the first one) is used. + // Other libc are not affected, as usually == 0 pthread key is impossible. + pthread_key_create(&dummyKey, nullptr); +#endif pthread_key_create(&terminationKey, onThreadExitCallback); }