OpenShot Library | libopenshot-audio 0.2.0
juce_HeavyweightLeakedObjectDetector.h
1
2/** @weakgroup juce_core-memory
3 * @{
4 */
5/*
6 ==============================================================================
7
8 This file is part of the JUCE library.
9 Copyright (c) 2017 - ROLI Ltd.
10
11 JUCE is an open source library subject to commercial or open-source
12 licensing.
13
14 The code included in this file is provided under the terms of the ISC license
15 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16 To use, copy, modify, and/or distribute this software for any purpose with or
17 without fee is hereby granted provided that the above copyright notice and
18 this permission notice appear in all copies.
19
20 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22 DISCLAIMED.
23
24 ==============================================================================
25*/
26
27namespace juce
28{
29
30//==============================================================================
31/**
32 This class is a useful way of tracking down hard to find memory leaks when the
33 regular LeakedObjectDetector isn't enough.
34
35 As well as firing when any instances of the OwnerClass type are leaked, it will
36 print out a stack trace showing where the leaked object was created. This is obviously
37 quite a heavyweight task so, unlike the LeakedObjectDetector which should be always
38 be added to your classes, you should only use this object temporarily when you are
39 debugging and remove it when finished.
40
41 To use it, use the JUCE_HEAVYWEIGHT_LEAK_DETECTOR macro as a simple way to put
42 one in your class declaration.
43
44 @tags{Core}
45*/
46template <class OwnerClass>
48{
49public:
50 //==============================================================================
51 HeavyweightLeakedObjectDetector() noexcept { getBacktraceMap().set (this, SystemStats::getStackBacktrace()); }
53
54 ~HeavyweightLeakedObjectDetector() { getBacktraceMap().remove (this); }
55
56private:
57 //==============================================================================
59
60 //==============================================================================
61 struct BacktraceMapHolder
62 {
63 BacktraceMapHolder() = default;
64
65 ~BacktraceMapHolder()
66 {
67 if (map.size() > 0)
68 {
69 DBG ("*** Leaked objects detected: " << map.size() << " instance(s) of class " << getLeakedObjectClassName());
70 DBG (getFormattedBacktracesString());
71
72 /** If you hit this, then you've leaked one or more objects of the type specified by
73 the 'OwnerClass' template parameter - the name and stack trace of its creation should
74 have been printed by the lines above.
75
76 If you're leaking, it's probably because you're using old-fashioned, non-RAII techniques for
77 your object management. Tut, tut. Always, always use std::unique_ptrs, OwnedArrays,
78 ReferenceCountedObjects, etc, and avoid the 'delete' operator at all costs!
79 */
80 jassertfalse;
81 }
82 }
83
84 String getFormattedBacktracesString() const
85 {
86 String str;
87
88 int counter = 1;
89 for (typename BacktraceMap::Iterator i (map); i.next();)
90 {
91 str << "\nBacktrace " << String (counter++) << "\n"
92 << "-----------------------------------------------------------------" << "\n"
93 << i.getValue();
94 }
95
96 return str;
97 }
98
99 BacktraceMap map;
100 };
101
102 static BacktraceMap& getBacktraceMap()
103 {
104 static BacktraceMapHolder holder;
105 return holder.map;
106 }
107
108 static const char* getLeakedObjectClassName()
109 {
110 return OwnerClass::getLeakedObjectClassName();
111 }
112};
113
114//==============================================================================
115#if DOXYGEN || ! defined (JUCE_HEAVYWEIGHT_LEAK_DETECTOR)
116 #if (DOXYGEN || JUCE_CHECK_MEMORY_LEAKS)
117 /** This macro lets you embed a heavyweight leak-detecting object inside a class.
118
119 To use it, simply declare a JUCE_HEAVYWEIGHT_LEAK_DETECTOR (YourClassName) inside a private section
120 of the class declaration. E.g.
121
122 @code
123 class MyClass
124 {
125 public:
126 MyClass();
127 void blahBlah();
128
129 private:
130 JUCE_HEAVYWEIGHT_LEAK_DETECTOR (MyClass)
131 };
132 @endcode
133
134 NB: you should only use this when you really need to track down a tricky memory leak, and
135 should never leave one of these inside a class!
136
137 @see HeavyweightLeakedObjectDetector, JUCE_LEAK_DETECTOR, LeakedObjectDetector
138 */
139 #define JUCE_HEAVYWEIGHT_LEAK_DETECTOR(OwnerClass) \
140 friend class juce::HeavyweightLeakedObjectDetector<OwnerClass>; \
141 static const char* getLeakedObjectClassName() noexcept { return #OwnerClass; } \
142 juce::HeavyweightLeakedObjectDetector<OwnerClass> JUCE_JOIN_MACRO (leakDetector, __LINE__);
143 #else
144 #define JUCE_HEAVYWEIGHT_LEAK_DETECTOR(OwnerClass)
145 #endif
146#endif
147
148} // namespace juce
149
150/** @}*/
Holds a resizable array of primitive or copy-by-value objects.
Definition juce_Array.h:60
void remove(int indexToRemove)
Removes an element from the array.
Definition juce_Array.h:724
void set(int indexToChange, ParameterType newValue)
Replaces an element with a new value.
Definition juce_Array.h:499
This class is a useful way of tracking down hard to find memory leaks when the regular LeakedObjectDe...
The JUCE String class!
Definition juce_String.h:43
static String getStackBacktrace()
Returns a backtrace of the current call-stack.