summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-16 21:17:30 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-16 21:17:30 +0000
commit5485cdcb5bc72c71dd67d982dadf76dd9c78328c (patch)
tree7f3bc0080230211be3adf17777cdf697c91bebb5
parent32a66aed0e57642c8f0da0a4a34383bbc9250a32 (diff)
downloadchromium_src-5485cdcb5bc72c71dd67d982dadf76dd9c78328c.zip
chromium_src-5485cdcb5bc72c71dd67d982dadf76dd9c78328c.tar.gz
chromium_src-5485cdcb5bc72c71dd67d982dadf76dd9c78328c.tar.bz2
Add StackTrace debugging utility class.
For the moment, it only works on Linux, although it should be pretty easy to get it working on Mac with __builtin_return_address and __builtin_frame_address. It will mostly fail to resolve functions. Use this wrapper script: import os import sys import subprocess import re address = re.compile('.*\[(0x[0-9a-fA-F]{4,8})\].*') if __name__ == '__main__': p = subprocess.Popen(sys.argv[1:], stderr = subprocess.STDOUT, stdout = subprocess.PIPE) addr2line = subprocess.Popen(['addr2line', '-e', sys.argv[1], '-f', '-C', '-s'], stdout = subprocess.PIPE, stdin = subprocess.PIPE) for line in p.stdout.readlines(): m = address.match(line); if m is not None: addr2line.stdin.write(m.groups()[0] + '\n') function = addr2line.stdout.readline()[:-1] location = addr2line.stdout.readline()[:-1] sys.stdout.write('%s (%s)\n' % (function, location)) else: sys.stdout.write(line) Review URL: http://codereview.chromium.org/18303 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8218 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/debug_util.h24
-rw-r--r--base/debug_util_posix.cc41
-rw-r--r--base/debug_util_win.cc12
3 files changed, 76 insertions, 1 deletions
diff --git a/base/debug_util.h b/base/debug_util.h
index 4572948..b7b5180 100644
--- a/base/debug_util.h
+++ b/base/debug_util.h
@@ -9,6 +9,29 @@
#ifndef BASE_DEBUG_UTIL_H_
#define BASE_DEBUG_UTIL_H_
+#include "base/basictypes.h"
+
+#include <vector>
+
+// A stacktrace can be helpful in debugging. For example, you can include a
+// stacktrace member in a object (probably around #ifndef NDEBUG) so that you
+// can later see where the given object was created from.
+class StackTrace {
+ public:
+ // Create a stacktrace from the current location
+ StackTrace();
+ // Get an array of instruction pointer values.
+ // count: (output) the number of elements in the returned array
+ const void *const *Addresses(size_t* count);
+ // Print a backtrace to stderr
+ void PrintBacktrace();
+
+ private:
+ std::vector<void*> trace_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(StackTrace);
+};
+
class DebugUtil {
public:
// Starts the registered system-wide JIT debugger to attach it to specified
@@ -27,4 +50,3 @@ class DebugUtil {
};
#endif // BASE_DEBUG_UTIL_H_
-
diff --git a/base/debug_util_posix.cc b/base/debug_util_posix.cc
index a83e144..466bb0e 100644
--- a/base/debug_util_posix.cc
+++ b/base/debug_util_posix.cc
@@ -2,8 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "build/build_config.h"
#include "base/debug_util.h"
+#if defined(OS_LINUX)
+#include <unistd.h>
+#include <execinfo.h>
+#endif
+
+#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
@@ -90,3 +97,37 @@ bool DebugUtil::BeingDebugged() {
void DebugUtil::BreakDebugger() {
asm ("int3");
}
+
+#if defined(OS_LINUX)
+
+StackTrace::StackTrace() {
+ static const unsigned kMaxCallers = 256;
+
+ void* callers[kMaxCallers];
+ int count = backtrace(callers, kMaxCallers);
+ trace_.resize(count);
+ memcpy(&trace_[0], callers, sizeof(void*) * count);
+}
+
+void StackTrace::PrintBacktrace() {
+ fflush(stderr);
+ backtrace_symbols_fd(&trace_[0], trace_.size(), STDERR_FILENO);
+}
+
+#elif defined(OS_MACOSX)
+
+// TODO(port): complete this code
+StackTrace::StackTrace() { }
+
+StackTrace::PrintBacktrace() {
+ NOTIMPLEMENTED();
+}
+
+#endif // defined(OS_MACOSX)
+
+const void *const *StackTrace::Addresses(size_t* count) {
+ *count = trace_.size();
+ if (trace_.size())
+ return &trace_[0];
+ return NULL;
+}
diff --git a/base/debug_util_win.cc b/base/debug_util_win.cc
index 906b71e..348bf44 100644
--- a/base/debug_util_win.cc
+++ b/base/debug_util_win.cc
@@ -101,3 +101,15 @@ void DebugUtil::BreakDebugger() {
__debugbreak();
}
+// TODO(port): not implemented on Windows
+StackTrace::StackTrace() {
+}
+
+const void *const *StackTrace::Addresses(size_t* count) {
+ *count = 0;
+ return NULL;
+}
+
+void PrintBacktrace() {
+ NOTIMPLEMENTED();
+}