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) {
|
void PrintStack(int first_frames_to_skip) {
|
||||||
// reset to default handler
|
|
||||||
signal(sig, SIG_DFL);
|
|
||||||
|
|
||||||
fprintf(stderr, "Received signal %d (%s)\n", sig, strsignal(sig));
|
|
||||||
|
|
||||||
const int kMaxFrames = 100;
|
const int kMaxFrames = 100;
|
||||||
void *frames[kMaxFrames];
|
void *frames[kMaxFrames];
|
||||||
|
|
||||||
@ -45,11 +40,8 @@ static void StackTraceHandler(int sig) {
|
|||||||
|
|
||||||
auto executable = GetExecutableName();
|
auto executable = GetExecutableName();
|
||||||
|
|
||||||
const int kSkip = 2; // skip the top two signal handler related frames
|
for (int i = first_frames_to_skip; i < num_frames; ++i) {
|
||||||
|
fprintf(stderr, "#%-2d ", i - first_frames_to_skip);
|
||||||
for (int i = kSkip; i < num_frames; ++i)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "#%-2d %p ", i - kSkip, frames[i]);
|
|
||||||
if (symbols) {
|
if (symbols) {
|
||||||
fprintf(stderr, "%s ", symbols[i]);
|
fprintf(stderr, "%s ", symbols[i]);
|
||||||
}
|
}
|
||||||
@ -57,22 +49,29 @@ static void StackTraceHandler(int sig) {
|
|||||||
// out source to addr2line, for the address translation
|
// out source to addr2line, for the address translation
|
||||||
const int kLineMax = 256;
|
const int kLineMax = 256;
|
||||||
char cmd[kLineMax];
|
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");
|
auto f = popen(cmd, "r");
|
||||||
if (f) {
|
if (f) {
|
||||||
char line[kLineMax];
|
char line[kLineMax];
|
||||||
while (fgets(line, sizeof(line), f)) {
|
while (fgets(line, sizeof(line), f)) {
|
||||||
fprintf(stderr, "%s", line);
|
line[strlen(line) - 1] = 0; // remove newline
|
||||||
|
fprintf(stderr, "%s\t", line);
|
||||||
}
|
}
|
||||||
pclose(f);
|
pclose(f);
|
||||||
} else {
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
}
|
}
|
||||||
} else {
|
} 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...)
|
// re-signal to default handler (so we still get core dump if needed...)
|
||||||
raise(sig);
|
raise(sig);
|
||||||
}
|
}
|
||||||
@ -96,6 +95,7 @@ void InstallStackTraceHandler() {
|
|||||||
namespace rocksdb {
|
namespace rocksdb {
|
||||||
|
|
||||||
void InstallStackTraceHandler() {}
|
void InstallStackTraceHandler() {}
|
||||||
|
void PrintStack(int first_frames_to_skip) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,4 +11,7 @@ namespace rocksdb {
|
|||||||
// Currently supports linux only. No-op otherwise.
|
// Currently supports linux only. No-op otherwise.
|
||||||
void InstallStackTraceHandler();
|
void InstallStackTraceHandler();
|
||||||
|
|
||||||
|
// Prints stack, skips skip_first_frames frames
|
||||||
|
void PrintStack(int first_frames_to_skip = 0);
|
||||||
|
|
||||||
} // namespace rocksdb
|
} // namespace rocksdb
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "rocksdb/env.h"
|
#include "rocksdb/env.h"
|
||||||
#include "rocksdb/slice.h"
|
#include "rocksdb/slice.h"
|
||||||
#include "util/random.h"
|
#include "util/random.h"
|
||||||
|
#include "util/stack_trace.h"
|
||||||
|
|
||||||
namespace rocksdb {
|
namespace rocksdb {
|
||||||
namespace test {
|
namespace test {
|
||||||
@ -58,6 +59,7 @@ class Tester {
|
|||||||
~Tester() {
|
~Tester() {
|
||||||
if (!ok_) {
|
if (!ok_) {
|
||||||
fprintf(stderr, "%s:%d:%s\n", fname_, line_, ss_.str().c_str());
|
fprintf(stderr, "%s:%d:%s\n", fname_, line_, ss_.str().c_str());
|
||||||
|
PrintStack(2);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user