re PR sanitizer/60038 (AddressSanitizer CHECK failed ... "((*tls_addr + *tls_size)) <= ((*stk_addr + *stk_size))" on CentOS 5.10)
PR sanitizer/60038 * sanitizer_common/sanitizer_linux_libcdep.cc: Include sanitizer_atomic.h and unistd.h. (kThreadDescriptorSize): Made static, remove initializer and const, change type to atomic_uintptr_t. (ThreadDescriptorSize): Use confstr(_CS_GNU_LIBC_VERSION, ...) to query glibc version, compute kThreadDescriptorSize depending on glibc version minor number. (GetThreadStackAndTls): Use ThreadDescriptorSize() instead of kThreadDescriptorSize directly. From-SVN: r207452
This commit is contained in:
parent
39960d1cfa
commit
5ab39ec3b0
2 changed files with 49 additions and 9 deletions
|
@ -1,3 +1,16 @@
|
|||
2014-02-04 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR sanitizer/60038
|
||||
* sanitizer_common/sanitizer_linux_libcdep.cc: Include
|
||||
sanitizer_atomic.h and unistd.h.
|
||||
(kThreadDescriptorSize): Made static, remove initializer and const,
|
||||
change type to atomic_uintptr_t.
|
||||
(ThreadDescriptorSize): Use confstr(_CS_GNU_LIBC_VERSION, ...) to
|
||||
query glibc version, compute kThreadDescriptorSize depending on
|
||||
glibc version minor number.
|
||||
(GetThreadStackAndTls): Use ThreadDescriptorSize() instead of
|
||||
kThreadDescriptorSize directly.
|
||||
|
||||
2014-01-23 Yury Gribov <y.gribov@samsung.com>
|
||||
Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "sanitizer_placement_new.h"
|
||||
#include "sanitizer_procmaps.h"
|
||||
#include "sanitizer_stacktrace.h"
|
||||
#include "sanitizer_atomic.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <pthread.h>
|
||||
|
@ -29,6 +30,7 @@
|
|||
#if !SANITIZER_ANDROID
|
||||
#include <elf.h>
|
||||
#include <link.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
// This function is defined elsewhere if we intercepted pthread_attr_getstack.
|
||||
|
@ -205,16 +207,41 @@ uptr GetTlsSize() {
|
|||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
// sizeof(struct thread) from glibc.
|
||||
// There has been a report of this being different on glibc 2.11 and 2.13. We
|
||||
// don't know when this change happened, so 2.14 is a conservative estimate.
|
||||
#if __GLIBC_PREREQ(2, 14)
|
||||
const uptr kThreadDescriptorSize = FIRST_32_SECOND_64(1216, 2304);
|
||||
#else
|
||||
const uptr kThreadDescriptorSize = FIRST_32_SECOND_64(1168, 2304);
|
||||
#endif
|
||||
static atomic_uintptr_t kThreadDescriptorSize;
|
||||
|
||||
uptr ThreadDescriptorSize() {
|
||||
return kThreadDescriptorSize;
|
||||
char buf[64];
|
||||
uptr val = atomic_load(&kThreadDescriptorSize, memory_order_relaxed);
|
||||
if (val)
|
||||
return val;
|
||||
#ifdef _CS_GNU_LIBC_VERSION
|
||||
uptr len = confstr(_CS_GNU_LIBC_VERSION, buf, sizeof(buf));
|
||||
if (len < sizeof(buf) && internal_strncmp(buf, "glibc 2.", 8) == 0) {
|
||||
char *end;
|
||||
int minor = internal_simple_strtoll(buf + 8, &end, 10);
|
||||
if (end != buf + 8 && (*end == '\0' || *end == '.')) {
|
||||
/* sizeof(struct thread) values from various glibc versions. */
|
||||
if (minor <= 3)
|
||||
val = FIRST_32_SECOND_64(1104, 1696);
|
||||
else if (minor == 4)
|
||||
val = FIRST_32_SECOND_64(1120, 1728);
|
||||
else if (minor == 5)
|
||||
val = FIRST_32_SECOND_64(1136, 1728);
|
||||
else if (minor <= 9)
|
||||
val = FIRST_32_SECOND_64(1136, 1712);
|
||||
else if (minor == 10)
|
||||
val = FIRST_32_SECOND_64(1168, 1776);
|
||||
else if (minor <= 12)
|
||||
val = FIRST_32_SECOND_64(1168, 2288);
|
||||
else
|
||||
val = FIRST_32_SECOND_64(1216, 2304);
|
||||
}
|
||||
if (val)
|
||||
atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed);
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The offset at which pointer to self is located in the thread descriptor.
|
||||
|
@ -242,7 +269,7 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
|
|||
*tls_addr = ThreadSelf();
|
||||
*tls_size = GetTlsSize();
|
||||
*tls_addr -= *tls_size;
|
||||
*tls_addr += kThreadDescriptorSize;
|
||||
*tls_addr += ThreadDescriptorSize();
|
||||
#else
|
||||
*tls_addr = 0;
|
||||
*tls_size = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue