tsan_stack_test.cc revision 1.1.1.1
1//===-- tsan_stack_test.cc ------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is a part of ThreadSanitizer (TSan), a race detector.
11//
12//===----------------------------------------------------------------------===//
13#include "tsan_sync.h"
14#include "tsan_rtl.h"
15#include "gtest/gtest.h"
16#include <string.h>
17
18namespace __tsan {
19
20template <typename StackTraceTy>
21static void TestStackTrace(StackTraceTy *trace) {
22  ThreadState thr(0, 0, 0, 0, 0, 0, 0, 0, 0);
23  uptr stack[128];
24  thr.shadow_stack = &stack[0];
25  thr.shadow_stack_pos = &stack[0];
26  thr.shadow_stack_end = &stack[128];
27
28  ObtainCurrentStack(&thr, 0, trace);
29  EXPECT_EQ(0U, trace->size);
30
31  ObtainCurrentStack(&thr, 42, trace);
32  EXPECT_EQ(1U, trace->size);
33  EXPECT_EQ(42U, trace->trace[0]);
34
35  *thr.shadow_stack_pos++ = 100;
36  *thr.shadow_stack_pos++ = 101;
37  ObtainCurrentStack(&thr, 0, trace);
38  EXPECT_EQ(2U, trace->size);
39  EXPECT_EQ(100U, trace->trace[0]);
40  EXPECT_EQ(101U, trace->trace[1]);
41
42  ObtainCurrentStack(&thr, 42, trace);
43  EXPECT_EQ(3U, trace->size);
44  EXPECT_EQ(100U, trace->trace[0]);
45  EXPECT_EQ(101U, trace->trace[1]);
46  EXPECT_EQ(42U, trace->trace[2]);
47}
48
49template<typename StackTraceTy>
50static void TestTrim(StackTraceTy *trace) {
51  ThreadState thr(0, 0, 0, 0, 0, 0, 0, 0, 0);
52  const uptr kShadowStackSize = 2 * kStackTraceMax;
53  uptr stack[kShadowStackSize];
54  thr.shadow_stack = &stack[0];
55  thr.shadow_stack_pos = &stack[0];
56  thr.shadow_stack_end = &stack[kShadowStackSize];
57
58  for (uptr i = 0; i < kShadowStackSize; ++i)
59    *thr.shadow_stack_pos++ = 100 + i;
60
61  ObtainCurrentStack(&thr, 0, trace);
62  EXPECT_EQ(kStackTraceMax, trace->size);
63  for (uptr i = 0; i < kStackTraceMax; i++) {
64    EXPECT_EQ(100 + kStackTraceMax + i, trace->trace[i]);
65  }
66
67  ObtainCurrentStack(&thr, 42, trace);
68  EXPECT_EQ(kStackTraceMax, trace->size);
69  for (uptr i = 0; i < kStackTraceMax - 1; i++) {
70    EXPECT_EQ(101 + kStackTraceMax + i, trace->trace[i]);
71  }
72  EXPECT_EQ(42U, trace->trace[kStackTraceMax - 1]);
73}
74
75TEST(StackTrace, BasicVarSize) {
76  VarSizeStackTrace trace;
77  TestStackTrace(&trace);
78}
79
80TEST(StackTrace, BasicBuffered) {
81  BufferedStackTrace trace;
82  TestStackTrace(&trace);
83}
84
85TEST(StackTrace, TrimVarSize) {
86  VarSizeStackTrace trace;
87  TestTrim(&trace);
88}
89
90TEST(StackTrace, TrimBuffered) {
91  BufferedStackTrace trace;
92  TestTrim(&trace);
93}
94
95}  // namespace __tsan
96