Index: base/leak_tracker.h |
=================================================================== |
--- base/leak_tracker.h (revision 0) |
+++ base/leak_tracker.h (revision 0) |
@@ -0,0 +1,106 @@ |
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef BASE_LEAK_TRACKER_H_ |
+#define BASE_LEAK_TRACKER_H_ |
+ |
+#ifndef NDEBUG |
+#include "base/debug_util.h" |
+#include "base/linked_list.h" |
+#include "base/logging.h" |
+#endif |
+ |
+// LeakTracker is a debug helper to verify that all instances of a class |
+// have been destroyed. |
+// |
+// It is particularly useful for classes that are bound to a single thread -- |
+// before destroying that thread, one can check that there are no remaining |
+// instances of that class. |
+// |
+// For example, to enable leak tracking for class URLRequest, start by |
+// adding a member variable of type LeakTracker<URLRequest>. |
+// |
+// class URLRequest { |
+// ... |
+// private: |
+// base::LeakTracker<URLRequest> leak_tracker_; |
+// }; |
+// |
+// |
+// Next, when we believe all instances of URLRequest have been deleted: |
+// |
+// LeakTracker<URLRequest>::CheckForLeaks(); |
+// |
+// Should the check fail (because there are live instances of URLRequest), |
+// then the allocation callstack for each leaked instances is dumped to |
+// the error log. |
+// |
+// In RELEASE mode the check has no effect. |
+ |
+namespace base { |
+ |
+#ifdef NDEBUG |
+ |
+// In release mode we do nothing. |
+template<typename T> |
+class LeakTracker { |
+ public: |
+ static void CheckForLeaks() {} |
+ static int NumLiveInstances() { return -1; } |
+}; |
+ |
+#else |
+ |
+// In debug mode we track where the object was allocated from. |
+ |
+template<typename T> |
+class LeakTracker : public LinkNode<LeakTracker<T> > { |
+ public: |
+ LeakTracker() { |
+ instances()->Append(this); |
+ } |
+ |
+ ~LeakTracker() { |
+ this->RemoveFromList(); |
+ } |
+ |
+ static void CheckForLeaks() { |
+ // Walk the allocation list and print each entry it contains. |
+ int count = 0; |
+ for (LinkNode<LeakTracker<T> >* node = instances()->head(); |
+ node != instances()->end(); |
+ node = node->next()) { |
+ ++count; |
+ LOG(ERROR) << "Leaked " << node << " which was allocated by:"; |
+ node->value()->allocation_stack_.PrintBacktrace(); |
+ } |
+ DCHECK_EQ(0, count); |
+ } |
+ |
+ static int NumLiveInstances() { |
+ // Walk the allocation list and count how many entries it has. |
+ int count = 0; |
+ for (LinkNode<LeakTracker<T> >* node = instances()->head(); |
+ node != instances()->end(); |
+ node = node->next()) { |
+ ++count; |
+ } |
+ return count; |
+ } |
+ |
+ private: |
+ // Each specialization of LeakTracker gets its own static storage. |
+ static LinkedList<LeakTracker<T> >* instances() { |
+ static LinkedList<LeakTracker<T> > list; |
+ return &list; |
+ } |
+ |
+ StackTrace allocation_stack_; |
+}; |
+ |
+#endif // NDEBUG |
+ |
+} // namespace base |
+ |
+#endif // BASE_LEAK_TRACKER_H_ |
Property changes on: base\leak_tracker.h |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |