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
20static void TestStackTrace(StackTrace *trace) {
21  ThreadState thr(0, 0, 0, 0, 0, 0, 0, 0);
22
23  trace->ObtainCurrent(&thr, 0);
24  EXPECT_EQ(trace->Size(), (uptr)0);
25
26  trace->ObtainCurrent(&thr, 42);
27  EXPECT_EQ(trace->Size(), (uptr)1);
28  EXPECT_EQ(trace->Get(0), (uptr)42);
29
30  *thr.shadow_stack_pos++ = 100;
31  *thr.shadow_stack_pos++ = 101;
32  trace->ObtainCurrent(&thr, 0);
33  EXPECT_EQ(trace->Size(), (uptr)2);
34  EXPECT_EQ(trace->Get(0), (uptr)100);
35  EXPECT_EQ(trace->Get(1), (uptr)101);
36
37  trace->ObtainCurrent(&thr, 42);
38  EXPECT_EQ(trace->Size(), (uptr)3);
39  EXPECT_EQ(trace->Get(0), (uptr)100);
40  EXPECT_EQ(trace->Get(1), (uptr)101);
41  EXPECT_EQ(trace->Get(2), (uptr)42);
42}
43
44TEST(StackTrace, Basic) {
45  ScopedInRtl in_rtl;
46  StackTrace trace;
47  TestStackTrace(&trace);
48}
49
50TEST(StackTrace, StaticBasic) {
51  ScopedInRtl in_rtl;
52  uptr buf[10];
53  StackTrace trace1(buf, 10);
54  TestStackTrace(&trace1);
55  StackTrace trace2(buf, 3);
56  TestStackTrace(&trace2);
57}
58
59TEST(StackTrace, StaticTrim) {
60  ScopedInRtl in_rtl;
61  uptr buf[2];
62  StackTrace trace(buf, 2);
63  ThreadState thr(0, 0, 0, 0, 0, 0, 0, 0);
64
65  *thr.shadow_stack_pos++ = 100;
66  *thr.shadow_stack_pos++ = 101;
67  *thr.shadow_stack_pos++ = 102;
68  trace.ObtainCurrent(&thr, 0);
69  EXPECT_EQ(trace.Size(), (uptr)2);
70  EXPECT_EQ(trace.Get(0), (uptr)101);
71  EXPECT_EQ(trace.Get(1), (uptr)102);
72
73  trace.ObtainCurrent(&thr, 42);
74  EXPECT_EQ(trace.Size(), (uptr)2);
75  EXPECT_EQ(trace.Get(0), (uptr)102);
76  EXPECT_EQ(trace.Get(1), (uptr)42);
77}
78
79
80}  // namespace __tsan
81