summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-21 19:44:54 +0000
committereroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-21 19:44:54 +0000
commit0ef8a9950e414678454e65bdf6581e7d16dec03f (patch)
tree1a8bb02849f107d7ce81c738205fde32481b0240
parent9a996a6899163967774c4bf904c26b8c1afb18e5 (diff)
downloadchromium_src-0ef8a9950e414678454e65bdf6581e7d16dec03f.zip
chromium_src-0ef8a9950e414678454e65bdf6581e7d16dec03f.tar.gz
chromium_src-0ef8a9950e414678454e65bdf6581e7d16dec03f.tar.bz2
Copy the leak callstacks onto the stack before crashing in LeakTracker::CheckForLeaks.
This way if it is enabled in release builds, the mini-dump will contain the allocation stacktrace. Review URL: http://codereview.chromium.org/208001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26717 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/debug_util.h6
-rw-r--r--base/leak_tracker.h26
2 files changed, 27 insertions, 5 deletions
diff --git a/base/debug_util.h b/base/debug_util.h
index 8ccb020..11c1d7c 100644
--- a/base/debug_util.h
+++ b/base/debug_util.h
@@ -25,6 +25,10 @@ class StackTrace {
public:
// Creates a stacktrace from the current location
StackTrace();
+
+ // Note that the default copy constructor and assignment constructors
+ // are OK.
+
#if defined(OS_WIN)
// Creates a stacktrace for an exception.
// Note: this function will throw an import not found (StackWalk64) exception
@@ -48,8 +52,6 @@ class StackTrace {
static const int MAX_TRACES = 62;
void* trace_[MAX_TRACES];
int count_;
-
- DISALLOW_EVIL_CONSTRUCTORS(StackTrace);
};
class DebugUtil {
diff --git a/base/leak_tracker.h b/base/leak_tracker.h
index a5d105a..de6ff29 100644
--- a/base/leak_tracker.h
+++ b/base/leak_tracker.h
@@ -72,15 +72,35 @@ class LeakTracker : public LinkNode<LeakTracker<T> > {
static void CheckForLeaks() {
// Walk the allocation list and print each entry it contains.
- int count = 0;
+ size_t count = 0;
+
+ // Copy the first 3 leak allocation callstacks onto the stack.
+ // This way if we hit the CHECK() in a release build, the leak
+ // information will be available in mini-dump.
+ const size_t kMaxStackTracesToCopyOntoStack = 3;
+ StackTrace stacktraces[kMaxStackTracesToCopyOntoStack];
+
for (LinkNode<LeakTracker<T> >* node = instances()->head();
node != instances()->end();
node = node->next()) {
+ StackTrace& allocation_stack = node->value()->allocation_stack_;
+
+ if (count < kMaxStackTracesToCopyOntoStack)
+ stacktraces[count] = allocation_stack;
+
++count;
LOG(ERROR) << "Leaked " << node << " which was allocated by:";
- node->value()->allocation_stack_.PrintBacktrace();
+ allocation_stack.PrintBacktrace();
+ }
+
+ CHECK(0u == count);
+
+ // Hack to keep |stacktraces| and |count| alive (so compiler
+ // doesn't optimize it out, and it will appear in mini-dumps).
+ if (count == 0x1234) {
+ for (size_t i = 0; i < kMaxStackTracesToCopyOntoStack; ++i)
+ stacktraces[i].PrintBacktrace();
}
- CHECK(0 == count);
}
static int NumLiveInstances() {