[compiler-rt] r182853 - [sanitizer] Change the way GetThreadStackAndTls() obtains the thread descriptor address.
Alexey Samsonov
samsonov at google.com
Thu May 30 02:17:13 PDT 2013
I was able to reproduce the error locally. I think r182918 should fix this.
On Wed, May 29, 2013 at 11:18 PM, Sergey Matveev <earthdok at google.com>wrote:
> 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
>>>>>
>>>>
>>>>
>>>
>>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
--
Alexey Samsonov, MSK
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130530/9cc4c491/attachment.html>
More information about the llvm-commits
mailing list