mirror of https://github.com/facebook/rocksdb.git
Print out stack trace in mac, too
Summary: While debugging Mac-only issue with ThreadLocalPtr, this was very useful. Let's print out stack trace in MAC OS, too. Test Plan: Verified that somewhat useful stack trace was generated on mac. Will run PrintStack() on linux, too. Reviewers: ljin, haobo Reviewed By: haobo CC: leveldb Differential Revision: https://reviews.facebook.net/D18189
This commit is contained in:
parent
a570740727
commit
f9f8965e96
|
@ -17,6 +17,7 @@ build_config.mk
|
|||
*.jar
|
||||
*.*jnilib*
|
||||
*.d-e
|
||||
*.o-*
|
||||
|
||||
ldb
|
||||
manifest_dump
|
||||
|
|
|
@ -28,11 +28,11 @@
|
|||
#include "rocksdb/statistics.h"
|
||||
#include "rocksdb/perf_context.h"
|
||||
#include "port/port.h"
|
||||
#include "port/stack_trace.h"
|
||||
#include "util/crc32c.h"
|
||||
#include "util/histogram.h"
|
||||
#include "util/mutexlock.h"
|
||||
#include "util/random.h"
|
||||
#include "util/stack_trace.h"
|
||||
#include "util/string_util.h"
|
||||
#include "util/statistics.h"
|
||||
#include "util/testutil.h"
|
||||
|
@ -2528,7 +2528,7 @@ class Benchmark {
|
|||
} // namespace rocksdb
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
rocksdb::InstallStackTraceHandler();
|
||||
rocksdb::port::InstallStackTraceHandler();
|
||||
google::SetUsageMessage(std::string("\nUSAGE:\n") + std::string(argv[0]) +
|
||||
" [OPTIONS]...");
|
||||
google::ParseCommandLineFlags(&argc, &argv, true);
|
||||
|
|
|
@ -3,9 +3,19 @@
|
|||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
#include "util/stack_trace.h"
|
||||
#include "port/stack_trace.h"
|
||||
|
||||
#ifdef OS_LINUX
|
||||
namespace rocksdb {
|
||||
namespace port {
|
||||
|
||||
#if defined(ROCKSDB_LITE) || !(defined(OS_LINUX) || defined(OS_MACOSX))
|
||||
|
||||
// noop
|
||||
|
||||
void InstallStackTraceHandler() {}
|
||||
void PrintStack(int first_frames_to_skip) {}
|
||||
|
||||
#else
|
||||
|
||||
#include <execinfo.h>
|
||||
#include <signal.h>
|
||||
|
@ -14,10 +24,10 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace rocksdb {
|
||||
namespace {
|
||||
|
||||
static const char* GetExecutableName()
|
||||
{
|
||||
#ifdef OS_LINUX
|
||||
const char* GetExecutableName() {
|
||||
static char name[1024];
|
||||
|
||||
char link[1024];
|
||||
|
@ -31,38 +41,56 @@ static const char* GetExecutableName()
|
|||
}
|
||||
}
|
||||
|
||||
void PrintStackTraceLine(const char* symbol, void* frame) {
|
||||
static const char* executable = GetExecutableName();
|
||||
if (symbol) {
|
||||
fprintf(stderr, "%s ", symbol);
|
||||
}
|
||||
if (executable) {
|
||||
// out source to addr2line, for the address translation
|
||||
const int kLineMax = 256;
|
||||
char cmd[kLineMax];
|
||||
snprintf(cmd, kLineMax, "addr2line %p -e %s -f -C 2>&1", frame, executable);
|
||||
auto f = popen(cmd, "r");
|
||||
if (f) {
|
||||
char line[kLineMax];
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
line[strlen(line) - 1] = 0; // remove newline
|
||||
fprintf(stderr, "%s\t", line);
|
||||
}
|
||||
pclose(f);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, " %p", frame);
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#elif OS_MACOSX
|
||||
|
||||
void PrintStackTraceLine(const char* symbol, void* frame) {
|
||||
// TODO(icanadi) demangle
|
||||
if (symbol) {
|
||||
fprintf(stderr, "%s ", symbol);
|
||||
}
|
||||
fprintf(stderr, " %p", frame);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
void PrintStack(int first_frames_to_skip) {
|
||||
const int kMaxFrames = 100;
|
||||
void *frames[kMaxFrames];
|
||||
void* frames[kMaxFrames];
|
||||
|
||||
auto num_frames = backtrace(frames, kMaxFrames);
|
||||
auto symbols = backtrace_symbols(frames, num_frames);
|
||||
|
||||
auto executable = GetExecutableName();
|
||||
|
||||
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]);
|
||||
}
|
||||
if (executable) {
|
||||
// out source to addr2line, for the address translation
|
||||
const int kLineMax = 256;
|
||||
char cmd[kLineMax];
|
||||
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)) {
|
||||
line[strlen(line) - 1] = 0; // remove newline
|
||||
fprintf(stderr, "%s\t", line);
|
||||
}
|
||||
pclose(f);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, " %p", frames[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
PrintStackTraceLine((symbols != nullptr) ? symbols[i] : nullptr, frames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,18 +113,9 @@ void InstallStackTraceHandler() {
|
|||
signal(SIGABRT, StackTraceHandler);
|
||||
|
||||
printf("Installed stack trace handler for SIGILL SIGSEGV SIGBUS SIGABRT\n");
|
||||
|
||||
}
|
||||
|
||||
} // namespace rocksdb
|
||||
#endif
|
||||
|
||||
#else // no-op for non-linux system for now
|
||||
|
||||
namespace rocksdb {
|
||||
|
||||
void InstallStackTraceHandler() {}
|
||||
void PrintStack(int first_frames_to_skip) {}
|
||||
|
||||
}
|
||||
|
||||
#endif // OS_LINUX
|
||||
} // namespace port
|
||||
} // namespace rocksdb
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
//
|
||||
#pragma once
|
||||
namespace rocksdb {
|
||||
namespace port {
|
||||
|
||||
// Install a signal handler to print callstack on the following signals:
|
||||
// SIGILL SIGSEGV SIGBUS SIGABRT
|
||||
|
@ -14,4 +15,5 @@ void InstallStackTraceHandler();
|
|||
// Prints stack, skips skip_first_frames frames
|
||||
void PrintStack(int first_frames_to_skip = 0);
|
||||
|
||||
} // namespace rocksdb
|
||||
} // namespace port
|
||||
} // namespace rocksdb
|
|
@ -3,7 +3,7 @@
|
|||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
#include "util/stack_trace.h"
|
||||
#include "port/stack_trace.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace {
|
||||
|
@ -26,7 +26,7 @@ void f3() {
|
|||
} // namespace
|
||||
|
||||
int main() {
|
||||
rocksdb::InstallStackTraceHandler();
|
||||
rocksdb::port::InstallStackTraceHandler();
|
||||
|
||||
f3();
|
||||
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sstream>
|
||||
#include "port/stack_trace.h"
|
||||
#include "rocksdb/env.h"
|
||||
#include "rocksdb/slice.h"
|
||||
#include "util/random.h"
|
||||
#include "util/stack_trace.h"
|
||||
|
||||
namespace rocksdb {
|
||||
namespace test {
|
||||
|
@ -59,7 +59,7 @@ class Tester {
|
|||
~Tester() {
|
||||
if (!ok_) {
|
||||
fprintf(stderr, "%s:%d:%s\n", fname_, line_, ss_.str().c_str());
|
||||
PrintStack(2);
|
||||
port::PrintStack(2);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue