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

Sergey Matveev earthdok at google.com
Wed May 29 12:18:45 PDT 2013


Yes, I normally build with CMake/ninja (and did a clean build just now). We
also have a bunch of bots running CMake builds.

On Wed, May 29, 2013 at 10:52 PM, David Blaikie <dblaikie at gmail.com> wrote:

>
>
>
> 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/0b23bfc9/attachment.html>


More information about the llvm-commits mailing list