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, "");
22  EXPECT_STREQ("/dir/file.cc:10:5", str.data());
23
24  str.clear();
25  RenderSourceLocation(&str, "/dir/file.cc", 11, 0, "");
26  EXPECT_STREQ("/dir/file.cc:11", str.data());
27
28  str.clear();
29  RenderSourceLocation(&str, "/dir/file.cc", 0, 0, "");
30  EXPECT_STREQ("/dir/file.cc", str.data());
31
32  str.clear();
33  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, "/dir/");
34  EXPECT_STREQ("file.cc:10:5", str.data());
35}
36
37TEST(SanitizerStacktracePrinter, RenderModuleLocation) {
38  InternalScopedString str(128);
39  RenderModuleLocation(&str, "/dir/exe", 0x123, "");
40  EXPECT_STREQ("(/dir/exe+0x123)", str.data());
41
42  // Check that we strip file prefix if necessary.
43  str.clear();
44  RenderModuleLocation(&str, "/dir/exe", 0x123, "/dir/");
45  EXPECT_STREQ("(exe+0x123)", str.data());
46}
47
48TEST(SanitizerStacktracePrinter, RenderFrame) {
49  int frame_no = 42;
50  AddressInfo info;
51  info.address = 0x400000;
52  info.module = internal_strdup("/path/to/my/module");
53  info.module_offset = 0x200;
54  info.function = internal_strdup("function_foo");
55  info.function_offset = 0x100;
56  info.file = internal_strdup("/path/to/my/source");
57  info.line = 10;
58  info.column = 5;
59  InternalScopedString str(256);
60
61  // Dump all the AddressInfo fields.
62  RenderFrame(&str, "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
63                    "Function:%f FunctionOffset:%q Source:%s Line:%l "
64                    "Column:%c",
65              frame_no, info, "/path/to/", "function_");
66  EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 "
67               "Function:foo FunctionOffset:0x100 Source:my/source Line:10 "
68               "Column:5",
69               str.data());
70  info.Clear();
71  str.clear();
72
73  // Test special format specifiers.
74  info.address = 0x400000;
75  RenderFrame(&str, "%M", frame_no, info);
76  EXPECT_NE(nullptr, internal_strstr(str.data(), "400000"));
77  str.clear();
78
79  RenderFrame(&str, "%L", frame_no, info);
80  EXPECT_STREQ("(<unknown module>)", str.data());
81  str.clear();
82
83  info.module = internal_strdup("/path/to/module");
84  info.module_offset = 0x200;
85  RenderFrame(&str, "%M", frame_no, info);
86  EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x"));
87  EXPECT_NE(nullptr, internal_strstr(str.data(), "200"));
88  str.clear();
89
90  RenderFrame(&str, "%L", frame_no, info);
91  EXPECT_STREQ("(/path/to/module+0x200)", str.data());
92  str.clear();
93
94  info.function = internal_strdup("my_function");
95  RenderFrame(&str, "%F", frame_no, info);
96  EXPECT_STREQ("in my_function", str.data());
97  str.clear();
98
99  info.function_offset = 0x100;
100  RenderFrame(&str, "%F %S", frame_no, info);
101  EXPECT_STREQ("in my_function+0x100 <null>", str.data());
102  str.clear();
103
104  info.file = internal_strdup("my_file");
105  RenderFrame(&str, "%F %S", frame_no, info);
106  EXPECT_STREQ("in my_function my_file", str.data());
107  str.clear();
108
109  info.line = 10;
110  RenderFrame(&str, "%F %S", frame_no, info);
111  EXPECT_STREQ("in my_function my_file:10", str.data());
112  str.clear();
113
114  info.column = 5;
115  RenderFrame(&str, "%S %L", frame_no, info);
116  EXPECT_STREQ("my_file:10:5 my_file:10:5", str.data());
117  str.clear();
118
119  info.Clear();
120}
121
122}  // namespace __sanitizer
123