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:
parent
bd04a838a7
commit
4780c99790
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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_
|
||||
|
Loading…
Reference in New Issue
Block a user