Skip to content

Commit

Permalink
arch: Simplify crash message, also add argument to skip unknown frame…
Browse files Browse the repository at this point in the history
…s when printing stack traces.

(Internal change: 2190014)
  • Loading branch information
gitamohr authored and pixar-oss committed Sep 23, 2021
1 parent e0da0a7 commit c1efe0b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 19 deletions.
61 changes: 45 additions & 16 deletions pxr/base/arch/stackTrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,7 @@ Arch_LogInfo::EmitAnyExtraLogInfo(FILE *outFile, size_t max) const
fputs(":\n", outFile);
for (std::string const &line: *i->second) {
if (max && n++ >= max) {
fputs("... full diagnostics reported in the stack trace "
"file.\n", outFile);
fputs("... see full diagnostics in crash report.\n", outFile);
return;
}
fputs(line.c_str(), outFile);
Expand Down Expand Up @@ -1046,10 +1045,30 @@ ArchLogPostMortem(const char* reason,
hostname[0] = '\0';
}

auto printNDashes = [](int nDashes) {
const char *dash64 =
"----------------------------------------------------------------";
int dividend = nDashes / 64;
int remainder = nDashes % 64;
while (dividend--) {
fputs(dash64, stderr);
}
fputs(dash64 + 64 - remainder, stderr);
};

const char *haltMsg = " terminated";
int labelSize = strlen(progname) + strlen(haltMsg);
int bannerSize = std::max<int>(80, labelSize + strlen("-- ") * 2);

fputs("\n", stderr);
fputs("------------------------ '", stderr);
int numLeadingDashes = (bannerSize - labelSize) / 2 - 1;
printNDashes(numLeadingDashes);
fputs(" ", stderr);
fputs(progname, stderr);
fputs("' is dying ------------------------\n", stderr);
fputs(haltMsg, stderr);
fputs(" ", stderr);
printNDashes(bannerSize - numLeadingDashes - labelSize - 2);
fputs("\n", stderr);

// print out any registered program info
{
Expand All @@ -1065,19 +1084,21 @@ ArchLogPostMortem(const char* reason,
fputs(message, stderr);
fputs("\n", stderr);
}
fputs("The stack can be found in ", stderr);

fputs("writing crash report to [ ", stderr);
fputs(hostname, stderr);
fputs(":", stderr);
fputs(logfile, stderr);
fputs("\n", stderr);
fputs(" ] ...", stderr);
fflush(stderr);

int loggedStack = _LogStackTraceForPid(logfile);
fputs("done.\n", stderr);
fputs(" done.\n", stderr);
// Additionally, print the first few lines of extra log information since
// developers don't always think to look for it in the stack trace file.
ArchStackTrace_GetLogInfo().EmitAnyExtraLogInfo(stderr, 3 /* max */);
fputs("------------------------------------------------------------------\n",
stderr);
printNDashes(bannerSize);
fputs("\n", stderr);

if (loggedStack) {
_FinishLoggingFatalStackTrace(progname, logfile, NULL /*session log*/,
Expand Down Expand Up @@ -1312,6 +1333,7 @@ ArchGetStackFrames(size_t maxdepth, size_t skip, vector<uintptr_t> *frames)
/* use the exception handling mechanism to unwind our stack.
* note this is gcc >= 3.3.3 only.
*/
frames->reserve(maxdepth);
Arch_UnwindContext context(maxdepth, skip, frames);
_Unwind_Backtrace(Arch_unwindcb, (void*)&context);
}
Expand Down Expand Up @@ -1378,22 +1400,24 @@ Arch_DefaultStackTraceCallback(uintptr_t address)
return ArchStringPrintf("%s+%#0lx", symbolName.c_str(), symbolOffset);
}
else {
return ArchStringPrintf("%#016lx", address);
return "<unknown>";
}
}

static
vector<string>
Arch_GetStackTrace(const vector<uintptr_t> &frames);
Arch_GetStackTrace(const vector<uintptr_t> &frames,
bool skipUnknownFrames=false);

/*
* ArchPrintStackFrames
* print out stack frames to the given ostream.
*/
void
ArchPrintStackFrames(ostream& oss, const vector<uintptr_t> &frames)
ArchPrintStackFrames(ostream& oss, const vector<uintptr_t> &frames,
bool skipUnknownFrames)
{
const vector<string> result = Arch_GetStackTrace(frames);
const vector<string> result = Arch_GetStackTrace(frames, skipUnknownFrames);
for (size_t i = 0; i < result.size(); i++) {
oss << result[i] << std::endl;
}
Expand All @@ -1420,8 +1444,9 @@ Arch_GetStackTraceCallback()
return &callback;
}

vector<string>
Arch_GetStackTrace(const vector<uintptr_t> &frames)
static vector<string>
Arch_GetStackTrace(const vector<uintptr_t> &frames,
bool skipUnknownFrames)
{
vector<string> rv;

Expand All @@ -1435,10 +1460,14 @@ Arch_GetStackTrace(const vector<uintptr_t> &frames)
if (!callback) {
callback = Arch_DefaultStackTraceCallback;
}
int n = 0;
for (size_t i = 0; i < frames.size(); i++) {
const std::string symbolic = callback(frames[i]);
if (skipUnknownFrames && symbolic == "<unknown>") {
continue;
}
rv.push_back(ArchStringPrintf(" #%-3i 0x%016lx in %s",
(int)i, frames[i], symbolic.c_str()));
n++, frames[i], symbolic.c_str()));
}

return rv;
Expand Down
3 changes: 2 additions & 1 deletion pxr/base/arch/stackTrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ void ArchGetStackFrames(size_t maxDepth, size_t numFramesToSkipAtTop,
/// Print stack frames to the given ostream.
ARCH_API
void ArchPrintStackFrames(std::ostream& out,
const std::vector<uintptr_t> &frames);
const std::vector<uintptr_t> &frames,
bool skipUnknownFrames = false);

/// Callback for handling crashes.
/// \see ArchCrashHandlerSystemv
Expand Down
4 changes: 2 additions & 2 deletions pxr/base/tf/stackTrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,12 @@ TfLogCrash(
// Create a nicely formatted message describing the crash
std::string fullMessage = TfStringPrintf(
"%s crashed. %s: %s\n"
"in %s at line %zu of %s\n",
"in %s at line %zu of %s",
ArchGetProgramNameForErrors(), reason.c_str(), message.c_str(),
context.GetFunction(), context.GetLine(), context.GetFile());

if (!additionalInfo.empty()) {
fullMessage += additionalInfo + "\n";
fullMessage += "\n" + additionalInfo;
}

Tf_ScopeDescriptionStackReportLock descStackReport;
Expand Down

0 comments on commit c1efe0b

Please sign in to comment.