xref: /openbsd-src/gnu/llvm/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cpp (revision 810390e339a5425391477d5d41c78d7cab2424ac)
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