<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Oct 16, 2013 at 7:35 PM, Dmitry Vyukov <span dir="ltr"><<a href="mailto:dvyukov@google.com" target="_blank">dvyukov@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dvyukov<br>
Date: Wed Oct 16 10:35:12 2013<br>
New Revision: 192797<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=192797&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=192797&view=rev</a><br>
Log:<br>
tsan: move shadow stack from thread descriptors to fixed addresses<br>
<br>
This allows to increase max shadow stack size to 64K,<br>
and reliably catch shadow stack overflows instead of silently<br>
corrupting memory.<br>
<br>
<br>
Added:<br>
compiler-rt/trunk/lib/tsan/lit_tests/deep_stack0.cc<br>
compiler-rt/trunk/lib/tsan/lit_tests/deep_stack1.cc<br>
Modified:<br>
compiler-rt/trunk/lib/tsan/lit_tests/global_race.cc<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h<br>
compiler-rt/trunk/lib/tsan/tests/unit/tsan_stack_test.cc<br>
<br>
Added: compiler-rt/trunk/lib/tsan/lit_tests/deep_stack0.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/deep_stack0.cc?rev=192797&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/deep_stack0.cc?rev=192797&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/lit_tests/deep_stack0.cc (added)<br></blockquote><div><br></div><div>Instead of having two different files that differ by one sleep(), I suggest to have a single file, </div><div>where the sleep is under if statement and the test is run twice.</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+++ compiler-rt/trunk/lib/tsan/lit_tests/deep_stack0.cc Wed Oct 16 10:35:12 2013<br>
@@ -0,0 +1,38 @@<br>
+// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s<br>
+#include <pthread.h><br>
+#include <stdio.h><br>
+#include <unistd.h><br>
+<br>
+volatile int X;<br>
+volatile int N;<br>
+void (*volatile F)();<br>
+<br>
+static void foo() {<br>
+ if (--N == 0)<br>
+ X = 42;<br>
+ else<br>
+ F();<br>
+}<br>
+<br>
+void *Thread(void *p) {<br>
+ sleep(1);<br>
+ F();<br>
+ return 0;<br>
+}<br>
+<br>
+int main() {<br>
+ N = 50000;<br>
+ F = foo;<br>
+ pthread_t t;<br>
+ pthread_attr_t a;<br>
+ pthread_attr_init(&a);<br>
+ pthread_attr_setstacksize(&a, N * 256 + (1 << 20));<br>
+ pthread_create(&t, &a, Thread, 0);<br>
+ X = 43;<br>
+ pthread_join(t, 0);<br>
+}<br>
+<br>
+// CHECK: WARNING: ThreadSanitizer: data race<br>
+// CHECK: #100 foo<br>
+// We must output suffucuently large stack (at least 100 frames)<br>
+<br>
<br>
Added: compiler-rt/trunk/lib/tsan/lit_tests/deep_stack1.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/deep_stack1.cc?rev=192797&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/deep_stack1.cc?rev=192797&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/lit_tests/deep_stack1.cc (added)<br>
+++ compiler-rt/trunk/lib/tsan/lit_tests/deep_stack1.cc Wed Oct 16 10:35:12 2013<br>
@@ -0,0 +1,38 @@<br>
+// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s<br>
+#include <pthread.h><br>
+#include <stdio.h><br>
+#include <unistd.h><br>
+<br>
+volatile int X;<br>
+volatile int N;<br>
+void (*volatile F)();<br>
+<br>
+static void foo() {<br>
+ if (--N == 0)<br>
+ X = 42;<br>
+ else<br>
+ F();<br>
+}<br>
+<br>
+void *Thread(void *p) {<br>
+ F();<br>
+ return 0;<br>
+}<br>
+<br>
+int main() {<br>
+ N = 50000;<br>
+ F = foo;<br>
+ pthread_t t;<br>
+ pthread_attr_t a;<br>
+ pthread_attr_init(&a);<br>
+ pthread_attr_setstacksize(&a, N * 256 + (1 << 20));<br>
+ pthread_create(&t, &a, Thread, 0);<br>
+ sleep(1);<br>
+ X = 43;<br>
+ pthread_join(t, 0);<br>
+}<br>
+<br>
+// CHECK: WARNING: ThreadSanitizer: data race<br>
+// CHECK: #100 foo<br>
+// We must output suffucuently large stack (at least 100 frames)<br>
+<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/lit_tests/global_race.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/global_race.cc?rev=192797&r1=192796&r2=192797&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/global_race.cc?rev=192797&r1=192796&r2=192797&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/lit_tests/global_race.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/lit_tests/global_race.cc Wed Oct 16 10:35:12 2013<br>
@@ -4,7 +4,7 @@<br>
#include <stddef.h><br>
<br>
int GlobalData[10];<br>
-int y;<br>
+int qwerty;<br>
namespace XXX {<br>
struct YYY {<br>
static int ZZZ[10];<br>
@@ -14,19 +14,19 @@ namespace XXX {<br>
<br>
void *Thread(void *a) {<br>
GlobalData[2] = 42;<br>
- y = 1;<br>
+ qwerty = 1;<br>
XXX::YYY::ZZZ[0] = 1;<br>
return 0;<br>
}<br>
<br>
int main() {<br>
fprintf(stderr, "addr=%p\n", GlobalData);<br>
- fprintf(stderr, "addr2=%p\n", &y);<br>
+ fprintf(stderr, "addr2=%p\n", &qwerty);<br>
fprintf(stderr, "addr3=%p\n", XXX::YYY::ZZZ);<br>
pthread_t t;<br>
pthread_create(&t, 0, Thread, 0);<br>
GlobalData[2] = 43;<br>
- y = 0;<br>
+ qwerty = 0;<br>
XXX::YYY::ZZZ[0] = 0;<br>
pthread_join(t, 0);<br>
}<br>
@@ -37,6 +37,6 @@ int main() {<br>
// CHECK: WARNING: ThreadSanitizer: data race<br>
// CHECK: Location is global 'GlobalData' of size 40 at [[ADDR]] ({{.*}}+0x{{[0-9,a-f]+}})<br>
// CHECK: WARNING: ThreadSanitizer: data race<br>
-// CHECK: Location is global 'y' of size 4 at [[ADDR2]] ({{.*}}+0x{{[0-9,a-f]+}})<br>
+// CHECK: Location is global 'qwerty' of size 4 at [[ADDR2]] ({{.*}}+0x{{[0-9,a-f]+}})<br>
// CHECK: WARNING: ThreadSanitizer: data race<br>
// CHECK: Location is global 'XXX::YYY::ZZZ' of size 40 at [[ADDR3]] ({{.*}}+0x{{[0-9,a-f]+}})<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h?rev=192797&r1=192796&r2=192797&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h?rev=192797&r1=192796&r2=192797&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h Wed Oct 16 10:35:12 2013<br>
@@ -41,10 +41,8 @@ const int kTidBits = 13;<br>
const unsigned kMaxTid = 1 << kTidBits;<br>
const unsigned kMaxTidInClock = kMaxTid * 2; // This includes msb 'freed' bit.<br>
const int kClkBits = 42;<br>
-#ifndef TSAN_GO<br>
-const int kShadowStackSize = 4 * 1024;<br>
-const int kTraceStackSize = 256;<br>
-#endif<br>
+const uptr kShadowStackSize = 64 * 1024;<br>
+const uptr kTraceStackSize = 256;<br>
<br>
#ifdef TSAN_SHADOW_COUNT<br>
# if TSAN_SHADOW_COUNT == 2 \<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h?rev=192797&r1=192796&r2=192797&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h?rev=192797&r1=192796&r2=192797&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h Wed Oct 16 10:35:12 2013<br>
@@ -138,14 +138,20 @@ uptr GetRSS();<br>
<br>
const char *InitializePlatform();<br>
void FinalizePlatform();<br>
+<br>
+// The additional page is to catch shadow stack overflow as paging fault.<br>
+const uptr kTotalTraceSize = (kTraceSize * sizeof(Event) + sizeof(Trace) + 4096<br>
+ + 4095) & ~4095;<br>
+<br>
uptr ALWAYS_INLINE GetThreadTrace(int tid) {<br>
- uptr p = kTraceMemBegin + (uptr)(tid * 2) * kTraceSize * sizeof(Event);<br>
+ uptr p = kTraceMemBegin + (uptr)tid * kTotalTraceSize;<br>
DCHECK_LT(p, kTraceMemBegin + kTraceMemSize);<br>
return p;<br>
}<br>
<br>
uptr ALWAYS_INLINE GetThreadTraceHeader(int tid) {<br>
- uptr p = kTraceMemBegin + (uptr)(tid * 2 + 1) * kTraceSize * sizeof(Event);<br>
+ uptr p = kTraceMemBegin + (uptr)tid * kTotalTraceSize<br>
+ + kTraceSize * sizeof(Event);<br>
DCHECK_LT(p, kTraceMemBegin + kTraceMemSize);<br>
return p;<br>
}<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc?rev=192797&r1=192796&r2=192797&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc?rev=192797&r1=192796&r2=192797&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Wed Oct 16 10:35:12 2013<br>
@@ -90,7 +90,6 @@ ThreadState::ThreadState(Context *ctx, i<br>
// they may be accessed before the ctor.<br>
// , ignore_reads_and_writes()<br>
// , in_rtl()<br>
- , shadow_stack_pos(&shadow_stack[0])<br>
#ifndef TSAN_GO<br>
, jmp_bufs(MBlockJmpBuf)<br>
#endif<br>
@@ -201,8 +200,10 @@ void MapThreadTrace(uptr addr, uptr size<br>
DPrintf("#0: Mapping trace at %p-%p(0x%zx)\n", addr, addr + size, size);<br>
CHECK_GE(addr, kTraceMemBegin);<br>
CHECK_LE(addr + size, kTraceMemBegin + kTraceMemSize);<br>
- if (addr != (uptr)MmapFixedNoReserve(addr, size)) {<br>
- Printf("FATAL: ThreadSanitizer can not mmap thread trace\n");<br>
+ uptr addr1 = (uptr)MmapFixedNoReserve(addr, size);<br>
+ if (addr1 != addr) {<br>
+ Printf("FATAL: ThreadSanitizer can not mmap thread trace (%p/%p->%p)\n",<br>
+ addr, size, addr1);<br>
Die();<br>
}<br>
}<br>
@@ -660,9 +661,9 @@ void FuncEntry(ThreadState *thr, uptr pc<br>
<br>
// Shadow stack maintenance can be replaced with<br>
// stack unwinding during trace switch (which presumably must be faster).<br>
- DCHECK_GE(thr->shadow_stack_pos, &thr->shadow_stack[0]);<br>
+ DCHECK_GE(thr->shadow_stack_pos, thr->shadow_stack);<br>
#ifndef TSAN_GO<br>
- DCHECK_LT(thr->shadow_stack_pos, &thr->shadow_stack[kShadowStackSize]);<br>
+ DCHECK_LT(thr->shadow_stack_pos, thr->shadow_stack_end);<br>
#else<br>
if (thr->shadow_stack_pos == thr->shadow_stack_end) {<br>
const int sz = thr->shadow_stack_end - thr->shadow_stack;<br>
@@ -688,9 +689,9 @@ void FuncExit(ThreadState *thr) {<br>
thr->fast_state.IncrementEpoch();<br>
TraceAddEvent(thr, thr->fast_state, EventTypeFuncExit, 0);<br>
<br>
- DCHECK_GT(thr->shadow_stack_pos, &thr->shadow_stack[0]);<br>
+ DCHECK_GT(thr->shadow_stack_pos, thr->shadow_stack);<br>
#ifndef TSAN_GO<br>
- DCHECK_LT(thr->shadow_stack_pos, &thr->shadow_stack[kShadowStackSize]);<br>
+ DCHECK_LT(thr->shadow_stack_pos, thr->shadow_stack_end);<br>
#endif<br>
thr->shadow_stack_pos--;<br>
}<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=192797&r1=192796&r2=192797&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=192797&r1=192796&r2=192797&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Wed Oct 16 10:35:12 2013<br>
@@ -413,17 +413,13 @@ struct ThreadState {<br>
// for better performance.<br>
int ignore_reads_and_writes;<br>
int ignore_sync;<br>
+ // C/C++ uses fixed size shadow stack embed into Trace.<br>
+ // Go uses malloc-allocated shadow stack with dynamic size.<br>
+ uptr *shadow_stack;<br>
+ uptr *shadow_stack_end;<br>
uptr *shadow_stack_pos;<br>
u64 *racy_shadow_addr;<br>
u64 racy_state[2];<br>
-#ifndef TSAN_GO<br>
- // C/C++ uses embed shadow stack of fixed size.<br>
- uptr shadow_stack[kShadowStackSize];<br>
-#else<br>
- // Go uses satellite shadow stack with dynamic size.<br>
- uptr *shadow_stack;<br>
- uptr *shadow_stack_end;<br>
-#endif<br>
MutexSet mset;<br>
ThreadClock clock;<br>
#ifndef TSAN_GO<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc?rev=192797&r1=192796&r2=192797&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc?rev=192797&r1=192796&r2=192797&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc Wed Oct 16 10:35:12 2013<br>
@@ -410,7 +410,7 @@ void RestoreStack(int tid, const u64 epo<br>
const u64 ebegin = RoundDown(eend, kTracePartSize);<br>
DPrintf("#%d: RestoreStack epoch=%zu ebegin=%zu eend=%zu partidx=%d\n",<br>
tid, (uptr)epoch, (uptr)ebegin, (uptr)eend, partidx);<br>
- InternalScopedBuffer<uptr> stack(1024); // FIXME: de-hardcode 1024<br>
+ InternalScopedBuffer<uptr> stack(kShadowStackSize);<br>
for (uptr i = 0; i < hdr->stack0.Size(); i++) {<br>
stack[i] = hdr->stack0.Get(i);<br>
DPrintf2(" #%02lu: pc=%zx\n", i, stack[i]);<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc?rev=192797&r1=192796&r2=192797&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc?rev=192797&r1=192796&r2=192797&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc Wed Oct 16 10:35:12 2013<br>
@@ -91,18 +91,21 @@ void ThreadContext::OnStarted(void *arg)<br>
epoch1 = (u64)-1;<br>
new(thr) ThreadState(CTX(), tid, unique_id,<br>
epoch0, args->stk_addr, args->stk_size, args->tls_addr, args->tls_size);<br>
-#ifdef TSAN_GO<br>
+#ifndef TSAN_GO<br>
+ thr->shadow_stack = &ThreadTrace(thr->tid)->shadow_stack[0];<br>
+ thr->shadow_stack_pos = thr->shadow_stack;<br>
+ thr->shadow_stack_end = thr->shadow_stack + kShadowStackSize;<br>
+#else<br>
// Setup dynamic shadow stack.<br>
const int kInitStackSize = 8;<br>
- args->thr->shadow_stack = (uptr*)internal_alloc(MBlockShadowStack,<br>
+ thr->shadow_stack = (uptr*)internal_alloc(MBlockShadowStack,<br>
kInitStackSize * sizeof(uptr));<br>
- args->thr->shadow_stack_pos = thr->shadow_stack;<br>
- args->thr->shadow_stack_end = thr->shadow_stack + kInitStackSize;<br>
+ thr->shadow_stack_pos = thr->shadow_stack;<br>
+ thr->shadow_stack_end = thr->shadow_stack + kInitStackSize;<br>
#endif<br>
#ifndef TSAN_GO<br>
- AllocatorThreadStart(args->thr);<br>
+ AllocatorThreadStart(thr);<br>
#endif<br>
- thr = args->thr;<br>
thr->fast_synch_epoch = epoch0;<br>
AcquireImpl(thr, 0, &sync);<br>
thr->fast_state.SetHistorySize(flags()->history_size);<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc?rev=192797&r1=192796&r2=192797&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc?rev=192797&r1=192796&r2=192797&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc Wed Oct 16 10:35:12 2013<br>
@@ -265,6 +265,11 @@ void StackTrace::ObtainCurrent(ThreadSta<br>
n_ = c_ - !!toppc;<br>
}<br>
} else {<br>
+ // Cap potentially huge stacks.<br>
+ if (n_ + !!toppc > kTraceStackSize) {<br>
+ start = n_ - kTraceStackSize + !!toppc;<br>
+ n_ = kTraceStackSize - !!toppc;<br>
+ }<br>
s_ = (uptr*)internal_alloc(MBlockStackTrace,<br>
(n_ + !!toppc) * sizeof(s_[0]));<br>
}<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h?rev=192797&r1=192796&r2=192797&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h?rev=192797&r1=192796&r2=192797&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h Wed Oct 16 10:35:12 2013<br>
@@ -62,6 +62,11 @@ struct TraceHeader {<br>
struct Trace {<br>
TraceHeader headers[kTraceParts];<br>
Mutex mtx;<br>
+#ifndef TSAN_GO<br>
+ // Must be last to catch overflow as paging fault.<br>
+ // Go shadow stack is dynamically allocated.<br>
+ uptr shadow_stack[kShadowStackSize];<br>
+#endif<br>
<br>
Trace()<br>
: mtx(MutexTypeTrace, StatMtxTrace) {<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/tests/unit/tsan_stack_test.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/unit/tsan_stack_test.cc?rev=192797&r1=192796&r2=192797&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/unit/tsan_stack_test.cc?rev=192797&r1=192796&r2=192797&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/tests/unit/tsan_stack_test.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/tests/unit/tsan_stack_test.cc Wed Oct 16 10:35:12 2013<br>
@@ -19,6 +19,10 @@ namespace __tsan {<br>
<br>
static void TestStackTrace(StackTrace *trace) {<br>
ThreadState thr(0, 0, 0, 0, 0, 0, 0, 0);<br>
+ uptr stack[128];<br>
+ thr.shadow_stack = &stack[0];<br>
+ thr.shadow_stack_pos = &stack[0];<br>
+ thr.shadow_stack_end = &stack[128];<br>
<br>
trace->ObtainCurrent(&thr, 0);<br>
EXPECT_EQ(trace->Size(), (uptr)0);<br>
@@ -60,7 +64,12 @@ TEST(StackTrace, StaticTrim) {<br>
ScopedInRtl in_rtl;<br>
uptr buf[2];<br>
StackTrace trace(buf, 2);<br>
+<br>
ThreadState thr(0, 0, 0, 0, 0, 0, 0, 0);<br>
+ uptr stack[128];<br>
+ thr.shadow_stack = &stack[0];<br>
+ thr.shadow_stack_pos = &stack[0];<br>
+ thr.shadow_stack_end = &stack[128];<br>
<br>
*thr.shadow_stack_pos++ = 100;<br>
*thr.shadow_stack_pos++ = 101;<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>