namespace_sandbox.inc (1809B)
1 #if defined(LIBC_GLIBC) 2 // The first few fields of glibc's struct pthread. The full 3 // definition is in: 4 // https://sourceware.org/git/?p=glibc.git;a=blob;f=nptl/descr.h;hb=95a73392580761abc62fc9b1386d232cd55878e9#l121 5 struct glibc_pthread { 6 union { 7 #if defined(ARCH_CPU_X86_64) 8 // On x86_64, sizeof(tcbhead_t) > sizeof(void*)*24. 9 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/nptl/tls.h;hb=95a73392580761abc62fc9b1386d232cd55878e9#l65 10 // For all other architectures, sizeof(tcbhead_t) <= sizeof(void*)*24. 11 // https://sourceware.org/git/?p=glibc.git&a=search&h=HEAD&st=grep&s=%7D+tcbhead_t 12 char header[704]; 13 #endif 14 void* padding[24]; 15 } header; 16 void* list[2]; 17 pid_t tid; 18 }; 19 20 pid_t GetGlibcCachedTid() { 21 pthread_mutex_t lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; 22 CHECK_EQ(0, pthread_mutex_lock(&lock)); 23 pid_t tid = lock.__data.__owner; 24 CHECK_EQ(0, pthread_mutex_unlock(&lock)); 25 CHECK_EQ(0, pthread_mutex_destroy(&lock)); 26 return tid; 27 } 28 29 void MaybeUpdateGlibcTidCache() { 30 // After the below CL, glibc does not does not reset the cached 31 // TID/PID on clone(), but pthread depends on it being up-to-date. 32 // This CL was introduced in glibc 2.25, and backported to 2.24 on 33 // at least Debian and Fedora. This is a workaround that updates 34 // the cache manually. 35 // https://sourceware.org/git/?p=glibc.git;a=commit;h=c579f48edba88380635ab98cb612030e3ed8691e 36 pid_t real_tid = sys_gettid(); 37 pid_t cached_tid = GetGlibcCachedTid(); 38 if (cached_tid != real_tid) { 39 pid_t* cached_tid_location = 40 &reinterpret_cast<struct glibc_pthread*>(pthread_self())->tid; 41 CHECK_EQ(cached_tid, *cached_tid_location); 42 *cached_tid_location = real_tid; 43 CHECK_EQ(real_tid, GetGlibcCachedTid()); 44 } 45 } 46 #endif // defined(LIBC_GLIBC)