Commit 509ab86b authored by Lee Howes's avatar Lee Howes Committed by Facebook GitHub Bot

Add another option to control output formatting of stack traces

Summary:
The current stack trace formatting is based on repeated string appends with newlines. This change adds more control so that we can produce file and line information only, without unnecessary newlines.

New format:
  ./folly/experimental/symbolizer/Symbolizer.h:77
  ./folly/experimental/symbolizer/test/StackTraceTest.cpp:209
  ./folly/experimental/symbolizer/test/StackTraceTest.cpp:213
  ./folly/experimental/symbolizer/test/StackTraceTest.cpp:258

Reviewed By: yfeldblum

Differential Revision: D21562670

fbshipit-source-id: 7d05605cbda686e2f1c87577647c7ab7581f8580
parent 59a079eb
......@@ -271,7 +271,7 @@ void SymbolizePrinter::print(const SymbolizedFrame& frame) {
color(Color::DEFAULT);
};
if (!(options_ & NO_FRAME_ADDRESS)) {
if (!(options_ & NO_FRAME_ADDRESS) && !(options_ & TERSE_FILE_AND_LINE)) {
color(kAddressColor);
AddressFormatter formatter;
......@@ -288,13 +288,15 @@ void SymbolizePrinter::print(const SymbolizedFrame& frame) {
return;
}
if (!frame.name || frame.name[0] == '\0') {
doPrint(" (unknown)");
} else {
char demangledBuf[2048];
demangle(frame.name, demangledBuf, sizeof(demangledBuf));
doPrint(" ");
doPrint(demangledBuf[0] == '\0' ? frame.name : demangledBuf);
if (!(options_ & TERSE_FILE_AND_LINE)) {
if (!frame.name || frame.name[0] == '\0') {
doPrint(" (unknown)");
} else {
char demangledBuf[2048];
demangle(frame.name, demangledBuf, sizeof(demangledBuf));
doPrint(" ");
doPrint(demangledBuf[0] == '\0' ? frame.name : demangledBuf);
}
}
if (!(options_ & NO_FILE_AND_LINE)) {
......@@ -303,17 +305,23 @@ void SymbolizePrinter::print(const SymbolizedFrame& frame) {
fileBuf[0] = '\0';
if (frame.location.hasFileAndLine) {
frame.location.file.toBuffer(fileBuf, sizeof(fileBuf));
doPrint("\n");
doPrint(pad);
if (!(options_ & TERSE_FILE_AND_LINE)) {
doPrint("\n");
doPrint(pad);
}
doPrint(fileBuf);
char buf[22];
uint32_t n = uint64ToBufferUnsafe(frame.location.line, buf);
doPrint(":");
doPrint(StringPiece(buf, n));
} else {
if ((options_ & TERSE_FILE_AND_LINE)) {
doPrint("(unknown)");
}
}
if (frame.location.hasMainFile) {
if (frame.location.hasMainFile && !(options_ & TERSE_FILE_AND_LINE)) {
char mainFileBuf[PATH_MAX];
mainFileBuf[0] = '\0';
frame.location.mainFile.toBuffer(mainFileBuf, sizeof(mainFileBuf));
......
......@@ -230,6 +230,9 @@ class SymbolizePrinter {
// Skip frame address information
NO_FRAME_ADDRESS = 1 << 4,
// Simple file and line output
TERSE_FILE_AND_LINE = 1 << 5,
};
// NOTE: enum values used as indexes in kColorMap.
......
......@@ -20,6 +20,8 @@
#include <folly/experimental/symbolizer/StackTrace.h>
#include <folly/experimental/symbolizer/Symbolizer.h>
#include <boost/regex.hpp>
#include <glog/logging.h>
#include <folly/portability/GTest.h>
......@@ -172,3 +174,55 @@ TEST(StackTraceTest, FastStackTracePrinter) {
testStackTracePrinter<FastStackTracePrinter>(printer, file.fd());
}
TEST(StackTraceTest, TerseStackTracePrinter) {
test::TemporaryFile file;
FastStackTracePrinter printer{
std::make_unique<FDSymbolizePrinter>(file.fd(), SymbolizePrinter::TERSE)};
testStackTracePrinter<FastStackTracePrinter>(printer, file.fd());
}
TEST(StackTraceTest, TerseFileAndLineStackTracePrinter) {
test::TemporaryFile file;
FastStackTracePrinter printer{std::make_unique<FDSymbolizePrinter>(
file.fd(), SymbolizePrinter::TERSE_FILE_AND_LINE)};
testStackTracePrinter<FastStackTracePrinter>(printer, file.fd());
}
namespace {
constexpr int frames = 5;
FOLLY_NOINLINE void foo(FrameArray<frames>& addresses) {
getStackTraceSafe(addresses);
}
FOLLY_NOINLINE void bar(FrameArray<frames>& addresses) {
foo(addresses);
}
FOLLY_NOINLINE void baz(FrameArray<frames>& addresses) {
bar(addresses);
}
} // namespace
TEST(StackTraceTest, TerseFileAndLineStackTracePrinterOutput) {
Symbolizer symbolizer(LocationInfoMode::FULL);
FrameArray<frames> addresses;
StringSymbolizePrinter printer(SymbolizePrinter::TERSE_FILE_AND_LINE);
baz(addresses);
symbolizer.symbolize(addresses);
printer.println(addresses, 0);
// Match a sequence of file+line results that should appear as:
// ./folly/experimental/symbolizer/test/StackTraceTest.cpp:202
// or:
// (unknown)
boost::regex regex("((([^:]*:[0-9]*)|(\\(unknown\\)))\n)+");
auto match = boost::regex_match(
printer.str(), regex, boost::regex_constants::match_not_dot_newline);
ASSERT_TRUE(match);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment