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
TEST(SanitizerStacktracePrinter,RenderSourceLocation)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
TEST(SanitizerStacktracePrinter,RenderModuleLocation)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
TEST(SanitizerStacktracePrinter,RenderFrame)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