Summary: This commit introduces function __sanitizer::RenderFrame() that allows to render the contents of AddressInfo (essentially, symbolized stack frame) using the custom format string. This function can be used to implement stack frame formatting for both ThreadSanitizer and generic StackTrace::Print(), used in another places. This paves the way towards allowing user to control the format of stack frames, obtaining them in any format he desires, and/or enforcing the consistent output from all sanitizers. Test Plan: compiler-rt test suite Reviewers: kcc Reviewed By: kcc Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D6140 llvm-svn: 221409
123 lines
3.8 KiB
C++
123 lines
3.8 KiB
C++
//===-- sanitizer_common_printer_test.cc ----------------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file is a part of sanitizer_common test suite.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "sanitizer_common/sanitizer_stacktrace_printer.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
namespace __sanitizer {
|
|
|
|
TEST(SanitizerStacktracePrinter, RenderSourceLocation) {
|
|
InternalScopedString str(128);
|
|
RenderSourceLocation(&str, "/dir/file.cc", 10, 5, "");
|
|
EXPECT_STREQ("/dir/file.cc:10:5", str.data());
|
|
|
|
str.clear();
|
|
RenderSourceLocation(&str, "/dir/file.cc", 11, 0, "");
|
|
EXPECT_STREQ("/dir/file.cc:11", str.data());
|
|
|
|
str.clear();
|
|
RenderSourceLocation(&str, "/dir/file.cc", 0, 0, "");
|
|
EXPECT_STREQ("/dir/file.cc", str.data());
|
|
|
|
str.clear();
|
|
RenderSourceLocation(&str, "/dir/file.cc", 10, 5, "/dir/");
|
|
EXPECT_STREQ("file.cc:10:5", str.data());
|
|
}
|
|
|
|
TEST(SanitizerStacktracePrinter, RenderModuleLocation) {
|
|
InternalScopedString str(128);
|
|
RenderModuleLocation(&str, "/dir/exe", 0x123, "");
|
|
EXPECT_STREQ("(/dir/exe+0x123)", str.data());
|
|
|
|
// Check that we strip file prefix if necessary.
|
|
str.clear();
|
|
RenderModuleLocation(&str, "/dir/exe", 0x123, "/dir/");
|
|
EXPECT_STREQ("(exe+0x123)", str.data());
|
|
}
|
|
|
|
TEST(SanitizerStacktracePrinter, RenderFrame) {
|
|
int frame_no = 42;
|
|
AddressInfo info;
|
|
info.address = 0x400000;
|
|
info.module = internal_strdup("/path/to/my/module");
|
|
info.module_offset = 0x200;
|
|
info.function = internal_strdup("function_foo");
|
|
info.function_offset = 0x100;
|
|
info.file = internal_strdup("/path/to/my/source");
|
|
info.line = 10;
|
|
info.column = 5;
|
|
InternalScopedString str(256);
|
|
|
|
// Dump all the AddressInfo fields.
|
|
RenderFrame(&str, "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
|
|
"Function:%f FunctionOffset:%q Source:%s Line:%l "
|
|
"Column:%c",
|
|
frame_no, info, "/path/to/", "function_");
|
|
EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 "
|
|
"Function:foo FunctionOffset:0x100 Source:my/source Line:10 "
|
|
"Column:5",
|
|
str.data());
|
|
info.Clear();
|
|
str.clear();
|
|
|
|
// Test special format specifiers.
|
|
info.address = 0x400000;
|
|
RenderFrame(&str, "%M", frame_no, info);
|
|
EXPECT_NE(nullptr, internal_strstr(str.data(), "400000"));
|
|
str.clear();
|
|
|
|
RenderFrame(&str, "%L", frame_no, info);
|
|
EXPECT_STREQ("(<unknown module>)", str.data());
|
|
str.clear();
|
|
|
|
info.module = internal_strdup("/path/to/module");
|
|
info.module_offset = 0x200;
|
|
RenderFrame(&str, "%M", frame_no, info);
|
|
EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x"));
|
|
EXPECT_NE(nullptr, internal_strstr(str.data(), "200"));
|
|
str.clear();
|
|
|
|
RenderFrame(&str, "%L", frame_no, info);
|
|
EXPECT_STREQ("(/path/to/module+0x200)", str.data());
|
|
str.clear();
|
|
|
|
info.function = internal_strdup("my_function");
|
|
RenderFrame(&str, "%F", frame_no, info);
|
|
EXPECT_STREQ("in my_function", str.data());
|
|
str.clear();
|
|
|
|
info.function_offset = 0x100;
|
|
RenderFrame(&str, "%F %S", frame_no, info);
|
|
EXPECT_STREQ("in my_function+0x100 <null>", str.data());
|
|
str.clear();
|
|
|
|
info.file = internal_strdup("my_file");
|
|
RenderFrame(&str, "%F %S", frame_no, info);
|
|
EXPECT_STREQ("in my_function my_file", str.data());
|
|
str.clear();
|
|
|
|
info.line = 10;
|
|
RenderFrame(&str, "%F %S", frame_no, info);
|
|
EXPECT_STREQ("in my_function my_file:10", str.data());
|
|
str.clear();
|
|
|
|
info.column = 5;
|
|
RenderFrame(&str, "%S %L", frame_no, info);
|
|
EXPECT_STREQ("my_file:10:5 my_file:10:5", str.data());
|
|
str.clear();
|
|
|
|
info.Clear();
|
|
}
|
|
|
|
} // namespace __sanitizer
|