sanitizer_stacktrace_test.cc revision 0b487c02ed906e555fa473cea5afcd6363549373
1//===-- sanitizer_stacktrace_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/AddressSanitizer runtime.
11//
12//===----------------------------------------------------------------------===//
13
14#include "sanitizer_common/sanitizer_common.h"
15#include "sanitizer_common/sanitizer_stacktrace.h"
16#include "gtest/gtest.h"
17
18namespace __sanitizer {
19
20class FastUnwindTest : public ::testing::Test {
21 protected:
22  virtual void SetUp();
23
24  uptr fake_stack[10];
25  uptr start_pc;
26  uptr fake_top;
27  uptr fake_bottom;
28  StackTrace trace;
29};
30
31void FastUnwindTest::SetUp() {
32  // Fill an array of pointers with fake fp+retaddr pairs.  Frame pointers have
33  // even indices.
34  for (int i = 0; i+1 < ARRAY_SIZE(fake_stack); i += 2) {
35    fake_stack[i] = (uptr)&fake_stack[i+2];  // fp
36    fake_stack[i+1] = i+1; // retaddr
37  }
38  // Mark the last fp as zero to terminate the stack trace.
39  fake_stack[RoundDownTo(ARRAY_SIZE(fake_stack) - 1, 2)] = 0;
40
41  // Top is two slots past the end because FastUnwindStack subtracts two.
42  fake_top = (uptr)&fake_stack[ARRAY_SIZE(fake_stack) + 2];
43  // Bottom is one slot before the start because FastUnwindStack uses >.
44  fake_bottom = (uptr)&fake_stack[-1];
45  start_pc = 0;
46
47  // This is common setup done by __asan::GetStackTrace().
48  trace.size = 0;
49  trace.max_size = ARRAY_SIZE(fake_stack);
50  trace.trace[0] = start_pc;
51}
52
53TEST_F(FastUnwindTest, Basic) {
54  trace.FastUnwindStack(start_pc, (uptr)&fake_stack[0],
55                        fake_top, fake_bottom);
56  // Should get all on-stack retaddrs and start_pc.
57  EXPECT_EQ(6, trace.size);
58  EXPECT_EQ(start_pc, trace.trace[0]);
59  for (int i = 1; i <= 5; i++) {
60    EXPECT_EQ(i*2 - 1, trace.trace[i]);
61  }
62}
63
64// From: http://code.google.com/p/address-sanitizer/issues/detail?id=162
65TEST_F(FastUnwindTest, FramePointerLoop) {
66  // Make one fp point to itself.
67  fake_stack[4] = (uptr)&fake_stack[4];
68  trace.FastUnwindStack(start_pc, (uptr)&fake_stack[0],
69                        fake_top, fake_bottom);
70  // Should get all on-stack retaddrs up to the 4th slot and start_pc.
71  EXPECT_EQ(4, trace.size);
72  EXPECT_EQ(start_pc, trace.trace[0]);
73  for (int i = 1; i <= 3; i++) {
74    EXPECT_EQ(i*2 - 1, trace.trace[i]);
75  }
76}
77
78}  // namespace __sanitizer
79