1//===-- sanitizer_common_printer_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 sanitizer_common test suite.
11//
12//===----------------------------------------------------------------------===//
13#include "sanitizer_common/sanitizer_stacktrace_printer.h"
14
15#include "gtest/gtest.h"
16
17namespace __sanitizer {
18
19TEST(SanitizerStacktracePrinter, RenderSourceLocation) {
20  InternalScopedString str(128);
21  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "");
22  EXPECT_STREQ("/dir/file.cc:10:5", str.data());
23
24  str.clear();
25  RenderSourceLocation(&str, "/dir/file.cc", 11, 0, false, "");
26  EXPECT_STREQ("/dir/file.cc:11", str.data());
27
28  str.clear();
29  RenderSourceLocation(&str, "/dir/file.cc", 0, 0, false, "");
30  EXPECT_STREQ("/dir/file.cc", str.data());
31
32  str.clear();
33  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "/dir/");
34  EXPECT_STREQ("file.cc:10:5", str.data());
35
36  str.clear();
37  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, "");
38  EXPECT_STREQ("/dir/file.cc(10,5)", str.data());
39
40  str.clear();
41  RenderSourceLocation(&str, "/dir/file.cc", 11, 0, true, "");
42  EXPECT_STREQ("/dir/file.cc(11)", str.data());
43
44  str.clear();
45  RenderSourceLocation(&str, "/dir/file.cc", 0, 0, true, "");
46  EXPECT_STREQ("/dir/file.cc", str.data());
47
48  str.clear();
49  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, "/dir/");
50  EXPECT_STREQ("file.cc(10,5)", str.data());
51}
52
53TEST(SanitizerStacktracePrinter, RenderModuleLocation) {
54  InternalScopedString str(128);
55  RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, "");
56  EXPECT_STREQ("(/dir/exe+0x123)", str.data());
57
58  // Check that we strip file prefix if necessary.
59  str.clear();
60  RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, "/dir/");
61  EXPECT_STREQ("(exe+0x123)", str.data());
62
63  // Check that we render the arch.
64  str.clear();
65  RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchX86_64H, "/dir/");
66  EXPECT_STREQ("(exe:x86_64h+0x123)", str.data());
67}
68
69TEST(SanitizerStacktracePrinter, RenderFrame) {
70  int frame_no = 42;
71  AddressInfo info;
72  info.address = 0x400000;
73  info.module = internal_strdup("/path/to/my/module");
74  info.module_offset = 0x200;
75  info.function = internal_strdup("function_foo");
76  info.function_offset = 0x100;
77  info.file = internal_strdup("/path/to/my/source");
78  info.line = 10;
79  info.column = 5;
80  InternalScopedString str(256);
81
82  // Dump all the AddressInfo fields.
83  RenderFrame(&str, "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
84                    "Function:%f FunctionOffset:%q Source:%s Line:%l "
85                    "Column:%c",
86              frame_no, 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, false);
97  EXPECT_NE(nullptr, internal_strstr(str.data(), "400000"));
98  str.clear();
99
100  RenderFrame(&str, "%L", frame_no, 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, 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, false);
112  EXPECT_STREQ("(/path/to/module+0x200)", str.data());
113  str.clear();
114
115  info.function = internal_strdup("my_function");
116  RenderFrame(&str, "%F", frame_no, info, false);
117  EXPECT_STREQ("in my_function", str.data());
118  str.clear();
119
120  info.function_offset = 0x100;
121  RenderFrame(&str, "%F %S", frame_no, info, false);
122  EXPECT_STREQ("in my_function+0x100 <null>", str.data());
123  str.clear();
124
125  info.file = internal_strdup("my_file");
126  RenderFrame(&str, "%F %S", frame_no, info, false);
127  EXPECT_STREQ("in my_function my_file", str.data());
128  str.clear();
129
130  info.line = 10;
131  RenderFrame(&str, "%F %S", frame_no, info, false);
132  EXPECT_STREQ("in my_function my_file:10", str.data());
133  str.clear();
134
135  info.column = 5;
136  RenderFrame(&str, "%S %L", frame_no, info, false);
137  EXPECT_STREQ("my_file:10:5 my_file:10:5", str.data());
138  str.clear();
139
140  RenderFrame(&str, "%S %L", frame_no, info, true);
141  EXPECT_STREQ("my_file(10,5) my_file(10,5)", str.data());
142  str.clear();
143
144  info.column = 0;
145  RenderFrame(&str, "%F %S", frame_no, info, true);
146  EXPECT_STREQ("in my_function my_file(10)", str.data());
147  str.clear();
148
149  info.line = 0;
150  RenderFrame(&str, "%F %S", frame_no, info, true);
151  EXPECT_STREQ("in my_function my_file", str.data());
152  str.clear();
153
154  info.Clear();
155}
156
157}  // namespace __sanitizer
158