Print stack trace on assertion failure
Summary: This will help me a lot! When we hit an assertion in unittest, we get the whole stack trace now. Also, changed stack trace a bit, we now include actual demangled C++ class::function symbols! Test Plan: Added ASSERT_TRUE(false) to a test, observed a stack trace Reviewers: haobo, dhruba, kailiu Reviewed By: kailiu CC: leveldb Differential Revision: https://reviews.facebook.net/D14499
This commit is contained in:
parent
07c8448845
commit
9644e0e0c7
@ -31,12 +31,7 @@ static const char* GetExecutableName()
|
||||
}
|
||||
}
|
||||
|
||||
static void StackTraceHandler(int sig) {
|
||||
// reset to default handler
|
||||
signal(sig, SIG_DFL);
|
||||
|
||||
fprintf(stderr, "Received signal %d (%s)\n", sig, strsignal(sig));
|
||||
|
||||
void PrintStack(int first_frames_to_skip) {
|
||||
const int kMaxFrames = 100;
|
||||
void *frames[kMaxFrames];
|
||||
|
||||
@ -45,11 +40,8 @@ static void StackTraceHandler(int sig) {
|
||||
|
||||
auto executable = GetExecutableName();
|
||||
|
||||
const int kSkip = 2; // skip the top two signal handler related frames
|
||||
|
||||
for (int i = kSkip; i < num_frames; ++i)
|
||||
{
|
||||
fprintf(stderr, "#%-2d %p ", i - kSkip, frames[i]);
|
||||
for (int i = first_frames_to_skip; i < num_frames; ++i) {
|
||||
fprintf(stderr, "#%-2d ", i - first_frames_to_skip);
|
||||
if (symbols) {
|
||||
fprintf(stderr, "%s ", symbols[i]);
|
||||
}
|
||||
@ -57,22 +49,29 @@ static void StackTraceHandler(int sig) {
|
||||
// out source to addr2line, for the address translation
|
||||
const int kLineMax = 256;
|
||||
char cmd[kLineMax];
|
||||
sprintf(cmd,"addr2line %p -e %s 2>&1", frames[i] , executable);
|
||||
sprintf(cmd, "addr2line %p -e %s -f -C 2>&1", frames[i], executable);
|
||||
auto f = popen(cmd, "r");
|
||||
if (f) {
|
||||
char line[kLineMax];
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
fprintf(stderr, "%s", line);
|
||||
line[strlen(line) - 1] = 0; // remove newline
|
||||
fprintf(stderr, "%s\t", line);
|
||||
}
|
||||
pclose(f);
|
||||
} else {
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " %p", frames[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void StackTraceHandler(int sig) {
|
||||
// reset to default handler
|
||||
signal(sig, SIG_DFL);
|
||||
fprintf(stderr, "Received signal %d (%s)\n", sig, strsignal(sig));
|
||||
// skip the top three signal handler related frames
|
||||
PrintStack(3);
|
||||
// re-signal to default handler (so we still get core dump if needed...)
|
||||
raise(sig);
|
||||
}
|
||||
@ -96,6 +95,7 @@ void InstallStackTraceHandler() {
|
||||
namespace rocksdb {
|
||||
|
||||
void InstallStackTraceHandler() {}
|
||||
void PrintStack(int first_frames_to_skip) {}
|
||||
|
||||
}
|
||||
|
||||
|
@ -11,4 +11,7 @@ namespace rocksdb {
|
||||
// Currently supports linux only. No-op otherwise.
|
||||
void InstallStackTraceHandler();
|
||||
|
||||
// Prints stack, skips skip_first_frames frames
|
||||
void PrintStack(int first_frames_to_skip = 0);
|
||||
|
||||
} // namespace rocksdb
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "rocksdb/env.h"
|
||||
#include "rocksdb/slice.h"
|
||||
#include "util/random.h"
|
||||
#include "util/stack_trace.h"
|
||||
|
||||
namespace rocksdb {
|
||||
namespace test {
|
||||
@ -58,6 +59,7 @@ class Tester {
|
||||
~Tester() {
|
||||
if (!ok_) {
|
||||
fprintf(stderr, "%s:%d:%s\n", fname_, line_, ss_.str().c_str());
|
||||
PrintStack(2);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user