Commit 4780c997 authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

Add a common templatized implementation of OS::DumpBacktrace() and...

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
parent bd04a838
...@@ -196,27 +196,7 @@ void OS::DebugBreak() { ...@@ -196,27 +196,7 @@ void OS::DebugBreak() {
void OS::DumpBacktrace() { void OS::DumpBacktrace() {
void* trace[100]; POSIXBacktraceHelper<backtrace, backtrace_symbols>::DumpBacktrace();
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);
} }
...@@ -318,30 +298,7 @@ void OS::SignalCodeMovingGC() { ...@@ -318,30 +298,7 @@ void OS::SignalCodeMovingGC() {
int OS::StackWalk(Vector<OS::StackFrame> frames) { int OS::StackWalk(Vector<OS::StackFrame> frames) {
int frames_size = frames.length(); return POSIXBacktraceHelper<backtrace, backtrace_symbols>::StackWalk(frames);
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;
} }
......
...@@ -451,32 +451,9 @@ void OS::DebugBreak() { ...@@ -451,32 +451,9 @@ void OS::DebugBreak() {
void OS::DumpBacktrace() { void OS::DumpBacktrace() {
// backtrace is a glibc extension.
#if defined(__GLIBC__) && !defined(__UCLIBC__) #if defined(__GLIBC__) && !defined(__UCLIBC__)
void* trace[100]; POSIXBacktraceHelper<backtrace, backtrace_symbols>::DumpBacktrace();
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);
#endif #endif
} }
...@@ -630,33 +607,10 @@ void OS::SignalCodeMovingGC() { ...@@ -630,33 +607,10 @@ void OS::SignalCodeMovingGC() {
int OS::StackWalk(Vector<OS::StackFrame> frames) { int OS::StackWalk(Vector<OS::StackFrame> frames) {
// backtrace is a glibc extension. // backtrace is a glibc extension.
#if defined(__GLIBC__) && !defined(__UCLIBC__) #if defined(__GLIBC__) && !defined(__UCLIBC__)
int frames_size = frames.length(); return POSIXBacktraceHelper<backtrace, backtrace_symbols>::StackWalk(frames);
ScopedVector<void*> addresses(frames_size); #else
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 0; return 0;
#endif // defined(__GLIBC__) && !defined(__UCLIBC__) #endif
} }
......
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <cxxabi.h>
#undef MAP_TYPE #undef MAP_TYPE
...@@ -189,7 +190,10 @@ void OS::DebugBreak() { ...@@ -189,7 +190,10 @@ void OS::DebugBreak() {
void OS::DumpBacktrace() { 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() { ...@@ -315,34 +319,9 @@ double OS::LocalTimeOffset() {
int OS::StackWalk(Vector<StackFrame> frames) { int OS::StackWalk(Vector<StackFrame> frames) {
// If weak link to execinfo lib has failed, ie because we are on 10.4, abort. // If weak link to execinfo lib has failed, ie because we are on 10.4, abort.
if (backtrace == NULL) if (backtrace == NULL) return 0;
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);
} }
......
...@@ -28,12 +28,78 @@ ...@@ -28,12 +28,78 @@
#ifndef V8_PLATFORM_POSIX_H_ #ifndef V8_PLATFORM_POSIX_H_
#define V8_PLATFORM_POSIX_H_ #define V8_PLATFORM_POSIX_H_
#include <cxxabi.h>
#include <stdio.h>
#include "platform.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
// Used by platform implementation files during OS::PostSetUp(). // Used by platform implementation files during OS::PostSetUp().
void POSIXPostSetUp(); 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 } } // namespace v8::internal
#endif // V8_PLATFORM_POSIX_H_ #endif // V8_PLATFORM_POSIX_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment