220 lines · cpp
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-exception6//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 "gmock/gmock.h"15#include "gtest/gtest.h"16#include "interception/interception.h"17 18using testing::MatchesRegex;19 20namespace __sanitizer {21 22class TestFormattedStackTracePrinter final : public FormattedStackTracePrinter {23 public:24 ~TestFormattedStackTracePrinter() {}25};26 27TEST(FormattedStackTracePrinter, RenderSourceLocation) {28 InternalScopedString str;29 TestFormattedStackTracePrinter printer;30 31 printer.RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "");32 EXPECT_STREQ("/dir/file.cc:10:5", str.data());33 34 str.clear();35 printer.RenderSourceLocation(&str, "/dir/file.cc", 11, 0, false, "");36 EXPECT_STREQ("/dir/file.cc:11", str.data());37 38 str.clear();39 printer.RenderSourceLocation(&str, "/dir/file.cc", 0, 0, false, "");40 EXPECT_STREQ("/dir/file.cc", str.data());41 42 str.clear();43 printer.RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "/dir/");44 EXPECT_STREQ("file.cc:10:5", str.data());45 46 str.clear();47 printer.RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, "");48 EXPECT_STREQ("/dir/file.cc(10,5)", str.data());49 50 str.clear();51 printer.RenderSourceLocation(&str, "/dir/file.cc", 11, 0, true, "");52 EXPECT_STREQ("/dir/file.cc(11)", str.data());53 54 str.clear();55 printer.RenderSourceLocation(&str, "/dir/file.cc", 0, 0, true, "");56 EXPECT_STREQ("/dir/file.cc", str.data());57 58 str.clear();59 printer.RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, "/dir/");60 EXPECT_STREQ("file.cc(10,5)", str.data());61}62 63TEST(FormattedStackTracePrinter, RenderModuleLocation) {64 InternalScopedString str;65 TestFormattedStackTracePrinter printer;66 printer.RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, "");67 EXPECT_STREQ("(/dir/exe+0x123)", str.data());68 69 // Check that we strip file prefix if necessary.70 str.clear();71 printer.RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown,72 "/dir/");73 EXPECT_STREQ("(exe+0x123)", str.data());74 75 // Check that we render the arch.76 str.clear();77 printer.RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchX86_64H,78 "/dir/");79 EXPECT_STREQ("(exe:x86_64h+0x123)", str.data());80}81 82TEST(FormattedStackTracePrinter, RenderFrame) {83 TestFormattedStackTracePrinter printer;84 int frame_no = 42;85 AddressInfo info;86 info.address = 0x400000;87 info.module = internal_strdup("/path/to/my/module");88 info.module_offset = 0x200;89 info.function = internal_strdup("foo");90 info.function_offset = 0x100;91 info.file = internal_strdup("/path/to/my/source");92 info.line = 10;93 info.column = 5;94 InternalScopedString str;95 96 // Dump all the AddressInfo fields.97 printer.RenderFrame(&str,98 "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "99 "Function:%f FunctionOffset:%q Source:%s Line:%l "100 "Column:%c",101 frame_no, info.address, &info, false, "/path/to/");102 EXPECT_THAT(103 str.data(),104 MatchesRegex(105 "% Frame:42 PC:0x0*400000 Module:my/module ModuleOffset:0x200 "106 "Function:foo FunctionOffset:0x100 Source:my/source Line:10 "107 "Column:5"));108 109 str.clear();110 // Check that RenderFrame() strips interceptor prefixes.111 info.function = internal_strdup(SANITIZER_STRINGIFY(WRAP(bar)));112 printer.RenderFrame(&str,113 "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "114 "Function:%f FunctionOffset:%q Source:%s Line:%l "115 "Column:%c",116 frame_no, info.address, &info, false, "/path/to/");117 EXPECT_THAT(118 str.data(),119 MatchesRegex(120 "% Frame:42 PC:0x0*400000 Module:my/module ModuleOffset:0x200 "121 "Function:bar FunctionOffset:0x100 Source:my/source Line:10 "122 "Column:5"));123 info.Clear();124 str.clear();125 126 // Test special format specifiers.127 info.address = 0x400000;128 printer.RenderFrame(&str, "%M", frame_no, info.address, &info, false);129 EXPECT_NE(nullptr, internal_strstr(str.data(), "400000"));130 str.clear();131 132 printer.RenderFrame(&str, "%L", frame_no, info.address, &info, false);133 EXPECT_STREQ("(<unknown module>)", str.data());134 str.clear();135 136 info.module = internal_strdup("/path/to/module");137 info.module_offset = 0x200;138 printer.RenderFrame(&str, "%M", frame_no, info.address, &info, false);139 EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x"));140 EXPECT_NE(nullptr, internal_strstr(str.data(), "200"));141 str.clear();142 143 printer.RenderFrame(&str, "%L", frame_no, info.address, &info, false);144 EXPECT_STREQ("(/path/to/module+0x200)", str.data());145 str.clear();146 147 printer.RenderFrame(&str, "%b", frame_no, info.address, &info, false);148 EXPECT_STREQ("", str.data());149 str.clear();150 151 info.uuid_size = 2;152 info.uuid[0] = 0x55;153 info.uuid[1] = 0x66;154 155 printer.RenderFrame(&str, "%M", frame_no, info.address, &info, false);156 EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x"));157 EXPECT_NE(nullptr, internal_strstr(str.data(), "200"));158#if SANITIZER_APPLE159 EXPECT_EQ(nullptr, internal_strstr(str.data(), "BuildId: 5566"));160#else161 EXPECT_NE(nullptr, internal_strstr(str.data(), "BuildId: 5566"));162#endif163 str.clear();164 165 printer.RenderFrame(&str, "%L", frame_no, info.address, &info, false);166#if SANITIZER_APPLE167 EXPECT_STREQ("(/path/to/module+0x200)", str.data());168#else169 EXPECT_STREQ("(/path/to/module+0x200) (BuildId: 5566)", str.data());170#endif171 str.clear();172 173 printer.RenderFrame(&str, "%b", frame_no, info.address, &info, false);174 EXPECT_STREQ("(BuildId: 5566)", str.data());175 str.clear();176 177 info.function = internal_strdup("my_function");178 printer.RenderFrame(&str, "%F", frame_no, info.address, &info, false);179 EXPECT_STREQ("in my_function", str.data());180 str.clear();181 182 info.function_offset = 0x100;183 printer.RenderFrame(&str, "%F %S", frame_no, info.address, &info, false);184 EXPECT_STREQ("in my_function+0x100 <null>", str.data());185 str.clear();186 187 info.file = internal_strdup("my_file");188 printer.RenderFrame(&str, "%F %S", frame_no, info.address, &info, false);189 EXPECT_STREQ("in my_function my_file", str.data());190 str.clear();191 192 info.line = 10;193 printer.RenderFrame(&str, "%F %S", frame_no, info.address, &info, false);194 EXPECT_STREQ("in my_function my_file:10", str.data());195 str.clear();196 197 info.column = 5;198 printer.RenderFrame(&str, "%S %L", frame_no, info.address, &info, false);199 EXPECT_STREQ("my_file:10:5 my_file:10:5", str.data());200 str.clear();201 202 printer.RenderFrame(&str, "%S %L", frame_no, info.address, &info, true);203 EXPECT_STREQ("my_file(10,5) my_file(10,5)", str.data());204 str.clear();205 206 info.column = 0;207 printer.RenderFrame(&str, "%F %S", frame_no, info.address, &info, true);208 EXPECT_STREQ("in my_function my_file(10)", str.data());209 str.clear();210 211 info.line = 0;212 printer.RenderFrame(&str, "%F %S", frame_no, info.address, &info, true);213 EXPECT_STREQ("in my_function my_file", str.data());214 str.clear();215 216 info.Clear();217}218 219} // namespace __sanitizer220