| 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
|
|
|
|
|