sanitizer_stacktrace_test.cc revision 7907f1d0bd86e83677f8ae3bea7dc484546042cd
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 (uptr 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(6U, 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(4U, 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