[compiler-rt] r182853 - [sanitizer] Change the way GetThreadStackAndTls() obtains the thread descriptor address.

David Blaikie dblaikie at gmail.com
Wed May 29 11:52:18 PDT 2013


On Wed, May 29, 2013 at 11:06 AM, Sergey Matveev <earthdok at google.com>wrote:

> It seems to me that you're linking with an outdated RTSanitizerCommon.
>

I just did a clean (ninja -t clean && ninja check-all) build & still
received these linker errors. Have you verified this builds for you with
CMake?


>
>
> On Wed, May 29, 2013 at 9:45 PM, David Blaikie <dblaikie at gmail.com> wrote:
>
>>
>>
>>
>> On Wed, May 29, 2013 at 6:07 AM, Sergey Matveev <earthdok at google.com>wrote:
>>
>>> Author: smatveev
>>> Date: Wed May 29 08:07:42 2013
>>> New Revision: 182853
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=182853&view=rev
>>> Log:
>>> [sanitizer] Change the way GetThreadStackAndTls() obtains the thread
>>> descriptor address.
>>>
>>> Instead of using arch_prctl(ARCH_GET_FS), read the address from the
>>> tread descriptor itself. This lets us avoid sandboxing issues. Also,
>>> GetThreadStackAndTls() can now be implemented on i386.
>>>
>>
>> This seems like it might've broken the compiler_rt cmake (& Ninja,
>> specifically) build:
>>
>> FAILED: cd
>> /usr/local/google/home/blaikie/dev/llvm/build/clang/debug/projects/compiler-rt/lib/sanitizer_common/tests
>> && /usr/local/google/home/blaikie/dev/llvm/build/clang/debug/bin/clang
>> sanitizer_allocator_test.cc.i386.o sanitizer_atomic_test.cc.i386.o
>> sanitizer_common_test.cc.i386.o sanitizer_flags_test.cc.i386.o
>> sanitizer_libc_test.cc.i386.o sanitizer_linux_test.cc.i386.o
>> sanitizer_list_test.cc.i386.o sanitizer_mutex_test.cc.i386.o
>> sanitizer_nolibc_test.cc.i386.o sanitizer_printf_test.cc.i386.o
>> sanitizer_scanf_interceptor_test.cc.i386.o
>> sanitizer_stackdepot_test.cc.i386.o sanitizer_stacktrace_test.cc.i386.o
>> sanitizer_stoptheworld_test.cc.i386.o sanitizer_test_main.cc.i386.o
>> sanitizer_thread_registry_test.cc.i386.o gtest-all.cc.i386.o
>> libRTSanitizerCommon.test.i386.a -o
>> /usr/local/google/home/blaikie/dev/llvm/build/clang/debug/projects/compiler-rt/lib/sanitizer_common/tests/Sanitizer-i386-Test
>> -lstdc++ -ldl -lpthread -m32
>> sanitizer_linux_test.cc.i386.o: In function
>> `__sanitizer::thread_self_offset_test_func(void*)':
>> /usr/local/google/home/blaikie/dev/llvm/src/projects/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc:201:
>> undefined reference to `__sanitizer::ThreadSelf()'
>> /usr/local/google/home/blaikie/dev/llvm/src/projects/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc:201:
>> undefined reference to `__sanitizer::ThreadSelfOffset()'
>> /usr/local/google/home/blaikie/dev/llvm/src/projects/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc:201:
>> undefined reference to `__sanitizer::ThreadSelf()'
>> /usr/local/google/home/blaikie/dev/llvm/src/projects/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc:201:
>> undefined reference to `__sanitizer::ThreadSelf()'
>> /usr/local/google/home/blaikie/dev/llvm/src/projects/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc:201:
>> undefined reference to `__sanitizer::ThreadSelfOffset()'
>> /usr/local/google/home/blaikie/dev/llvm/src/projects/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc:201:
>> undefined reference to `__sanitizer::ThreadSelf()'
>> sanitizer_linux_test.cc.i386.o: In function
>> `__sanitizer::thread_descriptor_size_test_func(void*)':
>> /usr/local/google/home/blaikie/dev/llvm/src/projects/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc:216:
>> undefined reference to `__sanitizer::ThreadSelf()'
>> sanitizer_linux_test.cc.i386.o: In function
>> `__sanitizer::SanitizerLinux_ThreadDescriptorSize_Test::TestBody()':
>> /usr/local/google/home/blaikie/dev/llvm/src/projects/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc:230:
>> undefined reference to `__sanitizer::ThreadDescriptorSize()'
>> clang-3.3: error: linker command failed with exit code 1 (use -v to see
>> invocation)
>>
>>
>>
>>>
>>> Modified:
>>>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h
>>>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc
>>>     compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_linux_test.cc
>>>
>>> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h?rev=182853&r1=182852&r2=182853&view=diff
>>>
>>> ==============================================================================
>>> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h (original)
>>> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h Wed May 29
>>> 08:07:42 2013
>>> @@ -55,6 +55,8 @@ void AdjustStackSizeLinux(void *attr, in
>>>
>>>  // Exposed for testing.
>>>  uptr ThreadDescriptorSize();
>>> +uptr ThreadSelf();
>>> +uptr ThreadSelfOffset();
>>>
>>>  // Matches a library's file name against a base name (stripping path
>>> and version
>>>  // information).
>>>
>>> Modified:
>>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc?rev=182853&r1=182852&r2=182853&view=diff
>>>
>>> ==============================================================================
>>> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc
>>> (original)
>>> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc
>>> Wed May 29 08:07:42 2013
>>> @@ -19,19 +19,12 @@
>>>  #include "sanitizer_procmaps.h"
>>>  #include "sanitizer_stacktrace.h"
>>>
>>> -#ifdef __x86_64__
>>> -#include <asm/prctl.h>
>>> -#endif
>>>  #include <dlfcn.h>
>>>  #include <pthread.h>
>>>  #include <sys/prctl.h>
>>>  #include <sys/resource.h>
>>>  #include <unwind.h>
>>>
>>> -#ifdef __x86_64__
>>> -extern "C" int arch_prctl(int code, __sanitizer::uptr *addr);
>>> -#endif
>>> -
>>>  namespace __sanitizer {
>>>
>>>  void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
>>> @@ -200,20 +193,37 @@ uptr GetTlsSize() {
>>>    return g_tls_size;
>>>  }
>>>
>>> +#if defined(__x86_64__) || defined(i386)
>>>  // sizeof(struct thread) from glibc.
>>> -#ifdef __x86_64__
>>> -const uptr kThreadDescriptorSize = 2304;
>>> +const uptr kThreadDescriptorSize = FIRST_32_SECOND_64(1216, 2304);
>>>
>>>  uptr ThreadDescriptorSize() {
>>>    return kThreadDescriptorSize;
>>>  }
>>> +
>>> +// The offset at which pointer to self is located in the thread
>>> descriptor.
>>> +const uptr kThreadSelfOffset = FIRST_32_SECOND_64(8, 16);
>>> +
>>> +uptr ThreadSelfOffset() {
>>> +  return kThreadSelfOffset;
>>> +}
>>> +
>>> +uptr ThreadSelf() {
>>> +  uptr descr_addr;
>>> +#ifdef __i386__
>>> +  asm("mov %%gs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset));
>>> +#else
>>> +  asm("mov %%fs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset));
>>>  #endif
>>> +  return descr_addr;
>>> +}
>>> +#endif  // defined(__x86_64__) || defined(i386)
>>>
>>>  void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
>>>                            uptr *tls_addr, uptr *tls_size) {
>>>  #ifndef SANITIZER_GO
>>> -#ifdef __x86_64__
>>> -  arch_prctl(ARCH_GET_FS, tls_addr);
>>> +#if defined(__x86_64__) || defined(i386)
>>> +  *tls_addr = ThreadSelf();
>>>    *tls_size = GetTlsSize();
>>>    *tls_addr -= *tls_size;
>>>    *tls_addr += kThreadDescriptorSize;
>>>
>>> Modified:
>>> compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_linux_test.cc
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_linux_test.cc?rev=182853&r1=182852&r2=182853&view=diff
>>>
>>> ==============================================================================
>>> --- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_linux_test.cc
>>> (original)
>>> +++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_linux_test.cc
>>> Wed May 29 08:07:42 2013
>>> @@ -19,9 +19,6 @@
>>>  #include "sanitizer_common/sanitizer_common.h"
>>>  #include "gtest/gtest.h"
>>>
>>> -#ifdef __x86_64__
>>> -#include <asm/prctl.h>
>>> -#endif
>>>  #include <pthread.h>
>>>  #include <sched.h>
>>>  #include <stdlib.h>
>>> @@ -29,10 +26,6 @@
>>>  #include <algorithm>
>>>  #include <vector>
>>>
>>> -#ifdef __x86_64__
>>> -extern "C" int arch_prctl(int code, __sanitizer::uptr *addr);
>>> -#endif
>>> -
>>>  namespace __sanitizer {
>>>
>>>  struct TidReporterArgument {
>>> @@ -202,23 +195,37 @@ TEST(SanitizerCommon, SetEnvTest) {
>>>    EXPECT_EQ(0, getenv(kEnvName));
>>>  }
>>>
>>> -#ifdef __x86_64__
>>> -// libpthread puts the thread descriptor (%fs:0x0) at the end of stack
>>> space.
>>> -void *thread_descriptor_test_func(void *arg) {
>>> -  uptr fs;
>>> -  arch_prctl(ARCH_GET_FS, &fs);
>>> +#if defined(__x86_64__) || defined(i386)
>>> +void *thread_self_offset_test_func(void *arg) {
>>> +  bool result =
>>> +      *(uptr *)((char *)ThreadSelf() + ThreadSelfOffset()) ==
>>> ThreadSelf();
>>> +  return (void *)result;
>>> +}
>>> +
>>> +TEST(SanitizerLinux, ThreadSelfOffset) {
>>> +  EXPECT_TRUE((bool)thread_self_offset_test_func(0));
>>> +  pthread_t tid;
>>> +  void *result;
>>> +  ASSERT_EQ(0, pthread_create(&tid, 0, thread_self_offset_test_func,
>>> 0));
>>> +  ASSERT_EQ(0, pthread_join(tid, &result));
>>> +  EXPECT_TRUE((bool)result);
>>> +}
>>> +
>>> +// libpthread puts the thread descriptor at the end of stack space.
>>> +void *thread_descriptor_size_test_func(void *arg) {
>>> +  uptr descr_addr = ThreadSelf();
>>>    pthread_attr_t attr;
>>>    pthread_getattr_np(pthread_self(), &attr);
>>>    void *stackaddr;
>>> -  uptr stacksize;
>>> +  size_t stacksize;
>>>    pthread_attr_getstack(&attr, &stackaddr, &stacksize);
>>> -  return (void *)((uptr)stackaddr + stacksize - fs);
>>> +  return (void *)((uptr)stackaddr + stacksize - descr_addr);
>>>  }
>>>
>>>  TEST(SanitizerLinux, ThreadDescriptorSize) {
>>>    pthread_t tid;
>>>    void *result;
>>> -  pthread_create(&tid, 0, thread_descriptor_test_func, 0);
>>> +  ASSERT_EQ(0, pthread_create(&tid, 0,
>>> thread_descriptor_size_test_func, 0));
>>>    ASSERT_EQ(0, pthread_join(tid, &result));
>>>    EXPECT_EQ((uptr)result, ThreadDescriptorSize());
>>>  }
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130529/ca578436/attachment.html>


More information about the llvm-commits mailing list