Add a common templatized implementation of OS::DumpBacktrace() and OS::StackWalk() to platform-posix.h and use it for Linux, Mac OS X and FreeBSD.

R=dslomov@chromium.org

Review URL: https://codereview.chromium.org/18431004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15644 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
bmeurer@chromium.org 2013-07-12 12:02:26 +00:00
parent bd04a838a7
commit 4780c99790
4 changed files with 80 additions and 124 deletions

View File

@ -196,27 +196,7 @@ void OS::DebugBreak() {
void OS::DumpBacktrace() {
void* trace[100];
int size = backtrace(trace, ARRAY_SIZE(trace));
char** symbols = backtrace_symbols(trace, size);
fprintf(stderr, "\n==== C stack trace ===============================\n\n");
if (size == 0) {
fprintf(stderr, "(empty)\n");
} else if (symbols == NULL) {
fprintf(stderr, "(no symbols)\n");
} else {
for (int i = 1; i < size; ++i) {
fprintf(stderr, "%2d: ", i);
char mangled[201];
if (sscanf(symbols[i], "%*[^(]%*[(]%200[^)+]", mangled) == 1) { // NOLINT
fprintf(stderr, "%s\n", mangled);
} else {
fprintf(stderr, "??\n");
}
}
}
fflush(stderr);
free(symbols);
POSIXBacktraceHelper<backtrace, backtrace_symbols>::DumpBacktrace();
}
@ -318,30 +298,7 @@ void OS::SignalCodeMovingGC() {
int OS::StackWalk(Vector<OS::StackFrame> frames) {
int frames_size = frames.length();
ScopedVector<void*> addresses(frames_size);
int frames_count = backtrace(addresses.start(), frames_size);
char** symbols = backtrace_symbols(addresses.start(), frames_count);
if (symbols == NULL) {
return kStackWalkError;
}
for (int i = 0; i < frames_count; i++) {
frames[i].address = addresses[i];
// Format a text representation of the frame based on the information
// available.
SNPrintF(MutableCStrVector(frames[i].text, kStackWalkMaxTextLen),
"%s",
symbols[i]);
// Make sure line termination is in place.
frames[i].text[kStackWalkMaxTextLen - 1] = '\0';
}
free(symbols);
return frames_count;
return POSIXBacktraceHelper<backtrace, backtrace_symbols>::StackWalk(frames);
}

View File

@ -451,32 +451,9 @@ void OS::DebugBreak() {
void OS::DumpBacktrace() {
// backtrace is a glibc extension.
#if defined(__GLIBC__) && !defined(__UCLIBC__)
void* trace[100];
int size = backtrace(trace, ARRAY_SIZE(trace));
char** symbols = backtrace_symbols(trace, size);
fprintf(stderr, "\n==== C stack trace ===============================\n\n");
if (size == 0) {
fprintf(stderr, "(empty)\n");
} else if (symbols == NULL) {
fprintf(stderr, "(no symbols)\n");
} else {
for (int i = 1; i < size; ++i) {
fprintf(stderr, "%2d: ", i);
char mangled[201];
if (sscanf(symbols[i], "%*[^(]%*[(]%200[^)+]", mangled) == 1) { // NOLINT
int status;
size_t length;
char* demangled = abi::__cxa_demangle(mangled, NULL, &length, &status);
fprintf(stderr, "%s\n", demangled ? demangled : mangled);
free(demangled);
} else {
fprintf(stderr, "??\n");
}
}
}
fflush(stderr);
free(symbols);
POSIXBacktraceHelper<backtrace, backtrace_symbols>::DumpBacktrace();
#endif
}
@ -630,33 +607,10 @@ void OS::SignalCodeMovingGC() {
int OS::StackWalk(Vector<OS::StackFrame> frames) {
// backtrace is a glibc extension.
#if defined(__GLIBC__) && !defined(__UCLIBC__)
int frames_size = frames.length();
ScopedVector<void*> addresses(frames_size);
int frames_count = backtrace(addresses.start(), frames_size);
char** symbols = backtrace_symbols(addresses.start(), frames_count);
if (symbols == NULL) {
return kStackWalkError;
}
for (int i = 0; i < frames_count; i++) {
frames[i].address = addresses[i];
// Format a text representation of the frame based on the information
// available.
SNPrintF(MutableCStrVector(frames[i].text, kStackWalkMaxTextLen),
"%s",
symbols[i]);
// Make sure line termination is in place.
frames[i].text[kStackWalkMaxTextLen - 1] = '\0';
}
free(symbols);
return frames_count;
#else // defined(__GLIBC__) && !defined(__UCLIBC__)
return POSIXBacktraceHelper<backtrace, backtrace_symbols>::StackWalk(frames);
#else
return 0;
#endif // defined(__GLIBC__) && !defined(__UCLIBC__)
#endif
}

View File

@ -53,6 +53,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <cxxabi.h>
#undef MAP_TYPE
@ -189,7 +190,10 @@ void OS::DebugBreak() {
void OS::DumpBacktrace() {
// Currently unsupported.
// If weak link to execinfo lib has failed, ie because we are on 10.4, abort.
if (backtrace == NULL) return;
POSIXBacktraceHelper<backtrace, backtrace_symbols>::DumpBacktrace();
}
@ -315,34 +319,9 @@ double OS::LocalTimeOffset() {
int OS::StackWalk(Vector<StackFrame> frames) {
// If weak link to execinfo lib has failed, ie because we are on 10.4, abort.
if (backtrace == NULL)
return 0;
if (backtrace == NULL) return 0;
int frames_size = frames.length();
ScopedVector<void*> addresses(frames_size);
int frames_count = backtrace(addresses.start(), frames_size);
char** symbols = backtrace_symbols(addresses.start(), frames_count);
if (symbols == NULL) {
return kStackWalkError;
}
for (int i = 0; i < frames_count; i++) {
frames[i].address = addresses[i];
// Format a text representation of the frame based on the information
// available.
SNPrintF(MutableCStrVector(frames[i].text,
kStackWalkMaxTextLen),
"%s",
symbols[i]);
// Make sure line termination is in place.
frames[i].text[kStackWalkMaxTextLen - 1] = '\0';
}
free(symbols);
return frames_count;
return POSIXBacktraceHelper<backtrace, backtrace_symbols>::StackWalk(frames);
}

View File

@ -28,12 +28,78 @@
#ifndef V8_PLATFORM_POSIX_H_
#define V8_PLATFORM_POSIX_H_
#include <cxxabi.h>
#include <stdio.h>
#include "platform.h"
namespace v8 {
namespace internal {
// Used by platform implementation files during OS::PostSetUp().
void POSIXPostSetUp();
// Used by platform implementation files during OS::DumpBacktrace()
// and OS::StackWalk().
template<int (*backtrace)(void**, int),
char** (*backtrace_symbols)(void* const*, int)>
struct POSIXBacktraceHelper {
static void DumpBacktrace() {
void* trace[100];
int size = backtrace(trace, ARRAY_SIZE(trace));
char** symbols = backtrace_symbols(trace, size);
fprintf(stderr, "\n==== C stack trace ===============================\n\n");
if (size == 0) {
fprintf(stderr, "(empty)\n");
} else if (symbols == NULL) {
fprintf(stderr, "(no symbols)\n");
} else {
for (int i = 1; i < size; ++i) {
fprintf(stderr, "%2d: ", i);
char mangled[201];
if (sscanf(symbols[i], "%*[^(]%*[(]%200[^)+]", mangled) == 1) {// NOLINT
int status;
size_t length;
char* demangled = abi::__cxa_demangle(
mangled, NULL, &length, &status);
fprintf(stderr, "%s\n", demangled != NULL ? demangled : mangled);
free(demangled);
} else {
fprintf(stderr, "??\n");
}
}
}
fflush(stderr);
free(symbols);
}
static int StackWalk(Vector<OS::StackFrame> frames) {
int frames_size = frames.length();
ScopedVector<void*> addresses(frames_size);
int frames_count = backtrace(addresses.start(), frames_size);
char** symbols = backtrace_symbols(addresses.start(), frames_count);
if (symbols == NULL) {
return OS::kStackWalkError;
}
for (int i = 0; i < frames_count; i++) {
frames[i].address = addresses[i];
// Format a text representation of the frame based on the information
// available.
OS::SNPrintF(MutableCStrVector(frames[i].text, OS::kStackWalkMaxTextLen),
"%s", symbols[i]);
// Make sure line termination is in place.
frames[i].text[OS::kStackWalkMaxTextLen - 1] = '\0';
}
free(symbols);
return frames_count;
}
};
} } // namespace v8::internal
#endif // V8_PLATFORM_POSIX_H_