~alinuxninja/nginx-edge/trunk

« back to all changes in this revision

Viewing changes to debian/modules/ngx_pagespeed/psol/include/third_party/chromium/src/base/debug/leak_tracker.h

  • Committer: Vivian
  • Date: 2015-12-04 18:20:11 UTC
  • Revision ID: git-v1:a36f2bc32e884f7473b3a47040e5411306144d7d
* Do not extract psol.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2
 
// Use of this source code is governed by a BSD-style license that can be
3
 
// found in the LICENSE file.
4
 
 
5
 
#ifndef BASE_DEBUG_LEAK_TRACKER_H_
6
 
#define BASE_DEBUG_LEAK_TRACKER_H_
7
 
 
8
 
// Only enable leak tracking in debug builds.
9
 
#ifndef NDEBUG
10
 
#define ENABLE_LEAK_TRACKER
11
 
#endif
12
 
 
13
 
#ifdef ENABLE_LEAK_TRACKER
14
 
#include "base/containers/linked_list.h"
15
 
#include "base/debug/stack_trace.h"
16
 
#include "base/logging.h"
17
 
#endif  // ENABLE_LEAK_TRACKER
18
 
 
19
 
// LeakTracker is a helper to verify that all instances of a class
20
 
// have been destroyed.
21
 
//
22
 
// It is particularly useful for classes that are bound to a single thread --
23
 
// before destroying that thread, one can check that there are no remaining
24
 
// instances of that class.
25
 
//
26
 
// For example, to enable leak tracking for class net::URLRequest, start by
27
 
// adding a member variable of type LeakTracker<net::URLRequest>.
28
 
//
29
 
//   class URLRequest {
30
 
//     ...
31
 
//    private:
32
 
//     base::LeakTracker<URLRequest> leak_tracker_;
33
 
//   };
34
 
//
35
 
//
36
 
// Next, when we believe all instances of net::URLRequest have been deleted:
37
 
//
38
 
//   LeakTracker<net::URLRequest>::CheckForLeaks();
39
 
//
40
 
// Should the check fail (because there are live instances of net::URLRequest),
41
 
// then the allocation callstack for each leaked instances is dumped to
42
 
// the error log.
43
 
//
44
 
// If ENABLE_LEAK_TRACKER is not defined, then the check has no effect.
45
 
 
46
 
namespace base {
47
 
namespace debug {
48
 
 
49
 
#ifndef ENABLE_LEAK_TRACKER
50
 
 
51
 
// If leak tracking is disabled, do nothing.
52
 
template<typename T>
53
 
class LeakTracker {
54
 
 public:
55
 
  ~LeakTracker() {}
56
 
  static void CheckForLeaks() {}
57
 
  static int NumLiveInstances() { return -1; }
58
 
};
59
 
 
60
 
#else
61
 
 
62
 
// If leak tracking is enabled we track where the object was allocated from.
63
 
 
64
 
template<typename T>
65
 
class LeakTracker : public LinkNode<LeakTracker<T> > {
66
 
 public:
67
 
  LeakTracker() {
68
 
    instances()->Append(this);
69
 
  }
70
 
 
71
 
  ~LeakTracker() {
72
 
    this->RemoveFromList();
73
 
  }
74
 
 
75
 
  static void CheckForLeaks() {
76
 
    // Walk the allocation list and print each entry it contains.
77
 
    size_t count = 0;
78
 
 
79
 
    // Copy the first 3 leak allocation callstacks onto the stack.
80
 
    // This way if we hit the CHECK() in a release build, the leak
81
 
    // information will be available in mini-dump.
82
 
    const size_t kMaxStackTracesToCopyOntoStack = 3;
83
 
    StackTrace stacktraces[kMaxStackTracesToCopyOntoStack];
84
 
 
85
 
    for (LinkNode<LeakTracker<T> >* node = instances()->head();
86
 
         node != instances()->end();
87
 
         node = node->next()) {
88
 
      StackTrace& allocation_stack = node->value()->allocation_stack_;
89
 
 
90
 
      if (count < kMaxStackTracesToCopyOntoStack)
91
 
        stacktraces[count] = allocation_stack;
92
 
 
93
 
      ++count;
94
 
      if (LOG_IS_ON(ERROR)) {
95
 
        LOG_STREAM(ERROR) << "Leaked " << node << " which was allocated by:";
96
 
        allocation_stack.OutputToStream(&LOG_STREAM(ERROR));
97
 
      }
98
 
    }
99
 
 
100
 
    CHECK_EQ(0u, count);
101
 
 
102
 
    // Hack to keep |stacktraces| and |count| alive (so compiler
103
 
    // doesn't optimize it out, and it will appear in mini-dumps).
104
 
    if (count == 0x1234) {
105
 
      for (size_t i = 0; i < kMaxStackTracesToCopyOntoStack; ++i)
106
 
        stacktraces[i].Print();
107
 
    }
108
 
  }
109
 
 
110
 
  static int NumLiveInstances() {
111
 
    // Walk the allocation list and count how many entries it has.
112
 
    int count = 0;
113
 
    for (LinkNode<LeakTracker<T> >* node = instances()->head();
114
 
         node != instances()->end();
115
 
         node = node->next()) {
116
 
      ++count;
117
 
    }
118
 
    return count;
119
 
  }
120
 
 
121
 
 private:
122
 
  // Each specialization of LeakTracker gets its own static storage.
123
 
  static LinkedList<LeakTracker<T> >* instances() {
124
 
    static LinkedList<LeakTracker<T> > list;
125
 
    return &list;
126
 
  }
127
 
 
128
 
  StackTrace allocation_stack_;
129
 
};
130
 
 
131
 
#endif  // ENABLE_LEAK_TRACKER
132
 
 
133
 
}  // namespace debug
134
 
}  // namespace base
135
 
 
136
 
#endif  // BASE_DEBUG_LEAK_TRACKER_H_