Add a common templatized implementation of OS::DumpBacktrace() and OS::StackWalk...
authorbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 12 Jul 2013 12:02:26 +0000 (12:02 +0000)
committerbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 12 Jul 2013 12:02:26 +0000 (12:02 +0000)
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

src/platform-freebsd.cc
src/platform-linux.cc
src/platform-macos.cc
src/platform-posix.h

index 210ccb1..c771cd3 100644 (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);
 }
 
 
index e0d3de6..ace4056 100644 (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
 }
 
 
index e8c25fa..097691b 100644 (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;
-
-  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);
+  if (backtrace == NULL) return 0;
 
-  return frames_count;
+  return POSIXBacktraceHelper<backtrace, backtrace_symbols>::StackWalk(frames);
 }
 
 
index 7a982ed..79178fd 100644 (file)
 #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_