1850SN/A//===-- sanitizer_common_printer_test.cc ----------------------------------===//
2850SN/A//
3850SN/A//                     The LLVM Compiler Infrastructure
4850SN/A//
5850SN/A// This file is distributed under the University of Illinois Open Source
6850SN/A// License. See LICENSE.TXT for details.
7850SN/A//
8850SN/A//===----------------------------------------------------------------------===//
9850SN/A//
10850SN/A// This file is a part of sanitizer_common test suite.
11850SN/A//
12850SN/A//===----------------------------------------------------------------------===//
13850SN/A#include "sanitizer_common/sanitizer_stacktrace_printer.h"
14850SN/A
15850SN/A#include "gtest/gtest.h"
16850SN/A
17850SN/Anamespace __sanitizer {
18850SN/A
19850SN/ATEST(SanitizerStacktracePrinter, RenderSourceLocation) {
20850SN/A  InternalScopedString str(128);
21850SN/A  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "");
22850SN/A  EXPECT_STREQ("/dir/file.cc:10:5", str.data());
23850SN/A
24850SN/A  str.clear();
25850SN/A  RenderSourceLocation(&str, "/dir/file.cc", 11, 0, false, "");
26850SN/A  EXPECT_STREQ("/dir/file.cc:11", str.data());
27850SN/A
28911SN/A  str.clear();
29850SN/A  RenderSourceLocation(&str, "/dir/file.cc", 0, 0, false, "");
30850SN/A  EXPECT_STREQ("/dir/file.cc", str.data());
311134Sattila
32850SN/A  str.clear();
33911SN/A  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "/dir/");
34850SN/A  EXPECT_STREQ("file.cc:10:5", str.data());
35850SN/A
361810Sattila  str.clear();
37850SN/A  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, "");
38850SN/A  EXPECT_STREQ("/dir/file.cc(10,5)", str.data());
39850SN/A
40850SN/A  str.clear();
41850SN/A  RenderSourceLocation(&str, "/dir/file.cc", 11, 0, true, "");
42850SN/A  EXPECT_STREQ("/dir/file.cc(11)", str.data());
43850SN/A
44850SN/A  str.clear();
45850SN/A  RenderSourceLocation(&str, "/dir/file.cc", 0, 0, true, "");
46850SN/A  EXPECT_STREQ("/dir/file.cc", str.data());
47850SN/A
48850SN/A  str.clear();
49850SN/A  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, "/dir/");
501152Sattila  EXPECT_STREQ("file.cc(10,5)", str.data());
51850SN/A}
52850SN/A
53850SN/ATEST(SanitizerStacktracePrinter, RenderModuleLocation) {
54850SN/A  InternalScopedString str(128);
551152Sattila  RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, "");
56850SN/A  EXPECT_STREQ("(/dir/exe+0x123)", str.data());
57850SN/A
581152Sattila  // Check that we strip file prefix if necessary.
59850SN/A  str.clear();
60850SN/A  RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, "/dir/");
61850SN/A  EXPECT_STREQ("(exe+0x123)", str.data());
62850SN/A
63850SN/A  // Check that we render the arch.
64850SN/A  str.clear();
651173Sattila  RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchX86_64H, "/dir/");
66850SN/A  EXPECT_STREQ("(exe:x86_64h+0x123)", str.data());
67850SN/A}
68850SN/A
69850SN/ATEST(SanitizerStacktracePrinter, RenderFrame) {
701152Sattila  int frame_no = 42;
71850SN/A  AddressInfo info;
72850SN/A  info.address = 0x400000;
73850SN/A  info.module = internal_strdup("/path/to/my/module");
741152Sattila  info.module_offset = 0x200;
75850SN/A  info.function = internal_strdup("function_foo");
76850SN/A  info.function_offset = 0x100;
77850SN/A  info.file = internal_strdup("/path/to/my/source");
78850SN/A  info.line = 10;
791070Sattila  info.column = 5;
80911SN/A  InternalScopedString str(256);
81850SN/A
82850SN/A  // Dump all the AddressInfo fields.
83850SN/A  RenderFrame(&str, "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
84850SN/A                    "Function:%f FunctionOffset:%q Source:%s Line:%l "
85850SN/A                    "Column:%c",
86850SN/A              frame_no, info, false, "/path/to/", "function_");
87850SN/A  EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 "
88850SN/A               "Function:foo FunctionOffset:0x100 Source:my/source Line:10 "
891152Sattila               "Column:5",
90850SN/A               str.data());
911444Sattila  info.Clear();
92850SN/A  str.clear();
93850SN/A
94850SN/A  // Test special format specifiers.
95850SN/A  info.address = 0x400000;
96850SN/A  RenderFrame(&str, "%M", frame_no, info, false);
97850SN/A  EXPECT_NE(nullptr, internal_strstr(str.data(), "400000"));
98850SN/A  str.clear();
99850SN/A
100850SN/A  RenderFrame(&str, "%L", frame_no, info, false);
101850SN/A  EXPECT_STREQ("(<unknown module>)", str.data());
1021137Sattila  str.clear();
1031137Sattila
1041137Sattila  info.module = internal_strdup("/path/to/module");
1051137Sattila  info.module_offset = 0x200;
1061137Sattila  RenderFrame(&str, "%M", frame_no, info, false);
1071137Sattila  EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x"));
1081137Sattila  EXPECT_NE(nullptr, internal_strstr(str.data(), "200"));
109850SN/A  str.clear();
1101444Sattila
111850SN/A  RenderFrame(&str, "%L", frame_no, info, false);
112850SN/A  EXPECT_STREQ("(/path/to/module+0x200)", str.data());
113850SN/A  str.clear();
114850SN/A
115850SN/A  info.function = internal_strdup("my_function");
116850SN/A  RenderFrame(&str, "%F", frame_no, info, false);
117850SN/A  EXPECT_STREQ("in my_function", str.data());
118850SN/A  str.clear();
119850SN/A
120850SN/A  info.function_offset = 0x100;
121850SN/A  RenderFrame(&str, "%F %S", frame_no, info, false);
122850SN/A  EXPECT_STREQ("in my_function+0x100 <null>", str.data());
123858SN/A  str.clear();
124850SN/A
125850SN/A  info.file = internal_strdup("my_file");
1261810Sattila  RenderFrame(&str, "%F %S", frame_no, info, false);
127850SN/A  EXPECT_STREQ("in my_function my_file", str.data());
1281810Sattila  str.clear();
129850SN/A
130850SN/A  info.line = 10;
131850SN/A  RenderFrame(&str, "%F %S", frame_no, info, false);
132850SN/A  EXPECT_STREQ("in my_function my_file:10", str.data());
133850SN/A  str.clear();
134850SN/A
135850SN/A  info.column = 5;
136850SN/A  RenderFrame(&str, "%S %L", frame_no, info, false);
137850SN/A  EXPECT_STREQ("my_file:10:5 my_file:10:5", str.data());
138850SN/A  str.clear();
1391152Sattila
1401152Sattila  RenderFrame(&str, "%S %L", frame_no, info, true);
141850SN/A  EXPECT_STREQ("my_file(10,5) my_file(10,5)", str.data());
142850SN/A  str.clear();
1431152Sattila
1441152Sattila  info.column = 0;
1451152Sattila  RenderFrame(&str, "%F %S", frame_no, info, true);
1461152Sattila  EXPECT_STREQ("in my_function my_file(10)", str.data());
1471152Sattila  str.clear();
1481152Sattila
1491152Sattila  info.line = 0;
1501152Sattila  RenderFrame(&str, "%F %S", frame_no, info, true);
1511152Sattila  EXPECT_STREQ("in my_function my_file", str.data());
1521152Sattila  str.clear();
1531152Sattila
1541152Sattila  info.Clear();
1551152Sattila}
1561152Sattila
1571152Sattila}  // namespace __sanitizer
1581152Sattila