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 
17 namespace __sanitizer {
18 
TEST(SanitizerStacktracePrinter,RenderSourceLocation)19 TEST(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 
TEST(SanitizerStacktracePrinter,RenderModuleLocation)53 TEST(SanitizerStacktracePrinter, RenderModuleLocation) {
54   InternalScopedString str(128);
55   RenderModuleLocation(&str, "/dir/exe", 0x123, "");
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, "/dir/");
61   EXPECT_STREQ("(exe+0x123)", str.data());
62 }
63 
TEST(SanitizerStacktracePrinter,RenderFrame)64 TEST(SanitizerStacktracePrinter, RenderFrame) {
65   int frame_no = 42;
66   AddressInfo info;
67   info.address = 0x400000;
68   info.module = internal_strdup("/path/to/my/module");
69   info.module_offset = 0x200;
70   info.function = internal_strdup("function_foo");
71   info.function_offset = 0x100;
72   info.file = internal_strdup("/path/to/my/source");
73   info.line = 10;
74   info.column = 5;
75   InternalScopedString str(256);
76 
77   // Dump all the AddressInfo fields.
78   RenderFrame(&str, "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
79                     "Function:%f FunctionOffset:%q Source:%s Line:%l "
80                     "Column:%c",
81               frame_no, info, false, "/path/to/", "function_");
82   EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 "
83                "Function:foo FunctionOffset:0x100 Source:my/source Line:10 "
84                "Column:5",
85                str.data());
86   info.Clear();
87   str.clear();
88 
89   // Test special format specifiers.
90   info.address = 0x400000;
91   RenderFrame(&str, "%M", frame_no, info, false);
92   EXPECT_NE(nullptr, internal_strstr(str.data(), "400000"));
93   str.clear();
94 
95   RenderFrame(&str, "%L", frame_no, info, false);
96   EXPECT_STREQ("(<unknown module>)", str.data());
97   str.clear();
98 
99   info.module = internal_strdup("/path/to/module");
100   info.module_offset = 0x200;
101   RenderFrame(&str, "%M", frame_no, info, false);
102   EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x"));
103   EXPECT_NE(nullptr, internal_strstr(str.data(), "200"));
104   str.clear();
105 
106   RenderFrame(&str, "%L", frame_no, info, false);
107   EXPECT_STREQ("(/path/to/module+0x200)", str.data());
108   str.clear();
109 
110   info.function = internal_strdup("my_function");
111   RenderFrame(&str, "%F", frame_no, info, false);
112   EXPECT_STREQ("in my_function", str.data());
113   str.clear();
114 
115   info.function_offset = 0x100;
116   RenderFrame(&str, "%F %S", frame_no, info, false);
117   EXPECT_STREQ("in my_function+0x100 <null>", str.data());
118   str.clear();
119 
120   info.file = internal_strdup("my_file");
121   RenderFrame(&str, "%F %S", frame_no, info, false);
122   EXPECT_STREQ("in my_function my_file", str.data());
123   str.clear();
124 
125   info.line = 10;
126   RenderFrame(&str, "%F %S", frame_no, info, false);
127   EXPECT_STREQ("in my_function my_file:10", str.data());
128   str.clear();
129 
130   info.column = 5;
131   RenderFrame(&str, "%S %L", frame_no, info, false);
132   EXPECT_STREQ("my_file:10:5 my_file:10:5", str.data());
133   str.clear();
134 
135   RenderFrame(&str, "%S %L", frame_no, info, true);
136   EXPECT_STREQ("my_file(10,5) my_file(10,5)", str.data());
137   str.clear();
138 
139   info.column = 0;
140   RenderFrame(&str, "%F %S", frame_no, info, true);
141   EXPECT_STREQ("in my_function my_file(10)", str.data());
142   str.clear();
143 
144   info.line = 0;
145   RenderFrame(&str, "%F %S", frame_no, info, true);
146   EXPECT_STREQ("in my_function my_file", str.data());
147   str.clear();
148 
149   info.Clear();
150 }
151 
152 }  // namespace __sanitizer
153