1 //===-- sanitizer_common_printer_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 sanitizer_common test suite. 10 // 11 //===----------------------------------------------------------------------===// 12 #include "sanitizer_common/sanitizer_stacktrace_printer.h" 13 14 #include "gtest/gtest.h" 15 16 namespace __sanitizer { 17 18 TEST(SanitizerStacktracePrinter, RenderSourceLocation) { 19 InternalScopedString str; 20 RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, ""); 21 EXPECT_STREQ("/dir/file.cc:10:5", str.data()); 22 23 str.clear(); 24 RenderSourceLocation(&str, "/dir/file.cc", 11, 0, false, ""); 25 EXPECT_STREQ("/dir/file.cc:11", str.data()); 26 27 str.clear(); 28 RenderSourceLocation(&str, "/dir/file.cc", 0, 0, false, ""); 29 EXPECT_STREQ("/dir/file.cc", str.data()); 30 31 str.clear(); 32 RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "/dir/"); 33 EXPECT_STREQ("file.cc:10:5", str.data()); 34 35 str.clear(); 36 RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, ""); 37 EXPECT_STREQ("/dir/file.cc(10,5)", str.data()); 38 39 str.clear(); 40 RenderSourceLocation(&str, "/dir/file.cc", 11, 0, true, ""); 41 EXPECT_STREQ("/dir/file.cc(11)", str.data()); 42 43 str.clear(); 44 RenderSourceLocation(&str, "/dir/file.cc", 0, 0, true, ""); 45 EXPECT_STREQ("/dir/file.cc", str.data()); 46 47 str.clear(); 48 RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, "/dir/"); 49 EXPECT_STREQ("file.cc(10,5)", str.data()); 50 } 51 52 TEST(SanitizerStacktracePrinter, RenderModuleLocation) { 53 InternalScopedString str; 54 RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, ""); 55 EXPECT_STREQ("(/dir/exe+0x123)", str.data()); 56 57 // Check that we strip file prefix if necessary. 58 str.clear(); 59 RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, "/dir/"); 60 EXPECT_STREQ("(exe+0x123)", str.data()); 61 62 // Check that we render the arch. 63 str.clear(); 64 RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchX86_64H, "/dir/"); 65 EXPECT_STREQ("(exe:x86_64h+0x123)", str.data()); 66 } 67 68 TEST(SanitizerStacktracePrinter, RenderFrame) { 69 int frame_no = 42; 70 AddressInfo info; 71 info.address = 0x400000; 72 info.module = internal_strdup("/path/to/my/module"); 73 info.module_offset = 0x200; 74 info.function = internal_strdup("function_foo"); 75 info.function_offset = 0x100; 76 info.file = internal_strdup("/path/to/my/source"); 77 info.line = 10; 78 info.column = 5; 79 InternalScopedString str; 80 81 // Dump all the AddressInfo fields. 82 RenderFrame(&str, 83 "%% Frame:%n PC:%p Module:%m ModuleOffset:%o " 84 "Function:%f FunctionOffset:%q Source:%s Line:%l " 85 "Column:%c", 86 frame_no, info.address, &info, false, "/path/to/", "function_"); 87 EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 " 88 "Function:foo FunctionOffset:0x100 Source:my/source Line:10 " 89 "Column:5", 90 str.data()); 91 info.Clear(); 92 str.clear(); 93 94 // Test special format specifiers. 95 info.address = 0x400000; 96 RenderFrame(&str, "%M", frame_no, info.address, &info, false); 97 EXPECT_NE(nullptr, internal_strstr(str.data(), "400000")); 98 str.clear(); 99 100 RenderFrame(&str, "%L", frame_no, info.address, &info, false); 101 EXPECT_STREQ("(<unknown module>)", str.data()); 102 str.clear(); 103 104 info.module = internal_strdup("/path/to/module"); 105 info.module_offset = 0x200; 106 RenderFrame(&str, "%M", frame_no, info.address, &info, false); 107 EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x")); 108 EXPECT_NE(nullptr, internal_strstr(str.data(), "200")); 109 str.clear(); 110 111 RenderFrame(&str, "%L", frame_no, info.address, &info, false); 112 EXPECT_STREQ("(/path/to/module+0x200)", str.data()); 113 str.clear(); 114 115 RenderFrame(&str, "%b", frame_no, info.address, &info, false); 116 EXPECT_STREQ("", str.data()); 117 str.clear(); 118 119 info.uuid_size = 2; 120 info.uuid[0] = 0x55; 121 info.uuid[1] = 0x66; 122 123 RenderFrame(&str, "%M", frame_no, info.address, &info, false); 124 EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x")); 125 EXPECT_NE(nullptr, internal_strstr(str.data(), "200")); 126 EXPECT_NE(nullptr, internal_strstr(str.data(), "BuildId: 5566")); 127 str.clear(); 128 129 RenderFrame(&str, "%L", frame_no, info.address, &info, false); 130 EXPECT_STREQ("(/path/to/module+0x200) (BuildId: 5566)", str.data()); 131 str.clear(); 132 133 RenderFrame(&str, "%b", frame_no, info.address, &info, false); 134 EXPECT_STREQ("(BuildId: 5566)", str.data()); 135 str.clear(); 136 137 info.function = internal_strdup("my_function"); 138 RenderFrame(&str, "%F", frame_no, info.address, &info, false); 139 EXPECT_STREQ("in my_function", str.data()); 140 str.clear(); 141 142 info.function_offset = 0x100; 143 RenderFrame(&str, "%F %S", frame_no, info.address, &info, false); 144 EXPECT_STREQ("in my_function+0x100 <null>", str.data()); 145 str.clear(); 146 147 info.file = internal_strdup("my_file"); 148 RenderFrame(&str, "%F %S", frame_no, info.address, &info, false); 149 EXPECT_STREQ("in my_function my_file", str.data()); 150 str.clear(); 151 152 info.line = 10; 153 RenderFrame(&str, "%F %S", frame_no, info.address, &info, false); 154 EXPECT_STREQ("in my_function my_file:10", str.data()); 155 str.clear(); 156 157 info.column = 5; 158 RenderFrame(&str, "%S %L", frame_no, info.address, &info, false); 159 EXPECT_STREQ("my_file:10:5 my_file:10:5", str.data()); 160 str.clear(); 161 162 RenderFrame(&str, "%S %L", frame_no, info.address, &info, true); 163 EXPECT_STREQ("my_file(10,5) my_file(10,5)", str.data()); 164 str.clear(); 165 166 info.column = 0; 167 RenderFrame(&str, "%F %S", frame_no, info.address, &info, true); 168 EXPECT_STREQ("in my_function my_file(10)", str.data()); 169 str.clear(); 170 171 info.line = 0; 172 RenderFrame(&str, "%F %S", frame_no, info.address, &info, true); 173 EXPECT_STREQ("in my_function my_file", str.data()); 174 str.clear(); 175 176 info.Clear(); 177 } 178 179 } // namespace __sanitizer 180