1 //===-- sanitizer_stackdepot_test.cpp -------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file is a part of ThreadSanitizer/AddressSanitizer runtime. 10 // 11 //===----------------------------------------------------------------------===// 12 #include "sanitizer_common/sanitizer_stackdepot.h" 13 14 #include "gtest/gtest.h" 15 #include "sanitizer_common/sanitizer_internal_defs.h" 16 #include "sanitizer_common/sanitizer_libc.h" 17 18 namespace __sanitizer { 19 20 TEST(SanitizerCommon, StackDepotBasic) { 21 uptr array[] = {1, 2, 3, 4, 5}; 22 StackTrace s1(array, ARRAY_SIZE(array)); 23 u32 i1 = StackDepotPut(s1); 24 StackTrace stack = StackDepotGet(i1); 25 EXPECT_NE(stack.trace, (uptr*)0); 26 EXPECT_EQ(ARRAY_SIZE(array), stack.size); 27 EXPECT_EQ(0, internal_memcmp(stack.trace, array, sizeof(array))); 28 } 29 30 TEST(SanitizerCommon, StackDepotAbsent) { 31 StackTrace stack = StackDepotGet((1 << 30) - 1); 32 EXPECT_EQ((uptr*)0, stack.trace); 33 } 34 35 TEST(SanitizerCommon, StackDepotEmptyStack) { 36 u32 i1 = StackDepotPut(StackTrace()); 37 StackTrace stack = StackDepotGet(i1); 38 EXPECT_EQ((uptr*)0, stack.trace); 39 } 40 41 TEST(SanitizerCommon, StackDepotZeroId) { 42 StackTrace stack = StackDepotGet(0); 43 EXPECT_EQ((uptr*)0, stack.trace); 44 } 45 46 TEST(SanitizerCommon, StackDepotSame) { 47 uptr array[] = {1, 2, 3, 4, 6}; 48 StackTrace s1(array, ARRAY_SIZE(array)); 49 u32 i1 = StackDepotPut(s1); 50 u32 i2 = StackDepotPut(s1); 51 EXPECT_EQ(i1, i2); 52 StackTrace stack = StackDepotGet(i1); 53 EXPECT_NE(stack.trace, (uptr*)0); 54 EXPECT_EQ(ARRAY_SIZE(array), stack.size); 55 EXPECT_EQ(0, internal_memcmp(stack.trace, array, sizeof(array))); 56 } 57 58 TEST(SanitizerCommon, StackDepotSeveral) { 59 uptr array1[] = {1, 2, 3, 4, 7}; 60 StackTrace s1(array1, ARRAY_SIZE(array1)); 61 u32 i1 = StackDepotPut(s1); 62 uptr array2[] = {1, 2, 3, 4, 8, 9}; 63 StackTrace s2(array2, ARRAY_SIZE(array2)); 64 u32 i2 = StackDepotPut(s2); 65 EXPECT_NE(i1, i2); 66 } 67 68 #if SANITIZER_WINDOWS 69 // CaptureStderr does not work on Windows. 70 #define Maybe_StackDepotPrint DISABLED_StackDepotPrint 71 #else 72 #define Maybe_StackDepotPrint StackDepotPrint 73 #endif 74 TEST(SanitizerCommon, Maybe_StackDepotPrint) { 75 uptr array1[] = {0x111, 0x222, 0x333, 0x444, 0x777}; 76 StackTrace s1(array1, ARRAY_SIZE(array1)); 77 u32 i1 = StackDepotPut(s1); 78 uptr array2[] = {0x1111, 0x2222, 0x3333, 0x4444, 0x8888, 0x9999}; 79 StackTrace s2(array2, ARRAY_SIZE(array2)); 80 u32 i2 = StackDepotPut(s2); 81 EXPECT_NE(i1, i2); 82 EXPECT_EXIT((StackDepotPrintAll(), exit(0)), ::testing::ExitedWithCode(0), 83 "Stack for id .*#0 0x1.*#1 0x2.*#2 0x3.*#3 0x4.*#4 0x7.*"); 84 EXPECT_EXIT( 85 (StackDepotPrintAll(), exit(0)), ::testing::ExitedWithCode(0), 86 "Stack for id .*#0 0x1.*#1 0x2.*#2 0x3.*#3 0x4.*#4 0x8.*#5 0x9.*"); 87 } 88 89 TEST(SanitizerCommon, StackDepotReverseMap) { 90 uptr array1[] = {1, 2, 3, 4, 5}; 91 uptr array2[] = {7, 1, 3, 0}; 92 uptr array3[] = {10, 2, 5, 3}; 93 uptr array4[] = {1, 3, 2, 5}; 94 u32 ids[4] = {0}; 95 StackTrace s1(array1, ARRAY_SIZE(array1)); 96 StackTrace s2(array2, ARRAY_SIZE(array2)); 97 StackTrace s3(array3, ARRAY_SIZE(array3)); 98 StackTrace s4(array4, ARRAY_SIZE(array4)); 99 ids[0] = StackDepotPut(s1); 100 ids[1] = StackDepotPut(s2); 101 ids[2] = StackDepotPut(s3); 102 ids[3] = StackDepotPut(s4); 103 104 StackDepotReverseMap map; 105 106 for (uptr i = 0; i < 4; i++) { 107 StackTrace stack = StackDepotGet(ids[i]); 108 StackTrace from_map = map.Get(ids[i]); 109 EXPECT_EQ(stack.size, from_map.size); 110 EXPECT_EQ(stack.trace, from_map.trace); 111 } 112 } 113 114 } // namespace __sanitizer 115