Leak detector


#1

Anyone know how completely disable Luce leak detector ?


#2

You can set JUCE_CHECK_MEMORY_LEAKS to 0. (But I’d recommend fixing your leaks instead!)


#3

I find the Juce leak detection quite useless for me for these reasons:

  • it does not give any clues to the leak source (no callstack, no name of the container class, not the line of declaration).
  • it’s based on reference counting on static object, so it can cycle/fail for static objects in the global scope (happened for me with a static Font object).
  • It’s an additional member to your class, you could clash with if you don’t take care, or declare multiple on the same line (or like me, if you use unions).

If I were you I would stick to the very good libraries (VisualLeakDetector for windows, and valgrind for Linux and Mac).

Jules, you could probably improve this declaration to include this:

template <class OwnerClass, const char * filename, const char * function, int line>
class LeakedObjectDetector
{
    const String file;
    const String functionName;
    const int lineNumber;

    LeakedObjectDetector() : file(filename), lineNumber(line), functionName(function)
[...]
  #define JUCE_LEAK_DETECTOR(OwnerClass)         LeakedObjectDetector<OwnerClass, __FILE__, __FUNCTION__, __LINE__> JUCE_JOIN_MACRO (leakDetector, __LINE__);

// In JUCE_common.h
#ifndef __FUNCTION__
#define __FUNCTION__ // Workaround for Visual Studio 6 not supporting the __FUNCTION__ macro
#endif

#4

I don’t really see how that would help? It’ll tell you the file that the class was declared in, but won’t help you find where it was created…

It’s actually not possible anyway, as template parameters can’t be char*, it’s a non-standard feature and very few compilers will accept it.


#5

Well, you can’t get a template to dump a callstack, for sure (even with the FUNCTION macro I used).
But, the idea was to allow double-clicking on the debug console to get straight to the line of code, instead of trying to demangle the C++ name on the output console.
It’s easier to figure out “/path/to/String.h(342)” than Z234_Juce%3421String23Zer4toUTF8$234

I’ve seen implementation of LeakDetectors with pseudo callstack (I’ll check my bookmarks), but it was invasive, since it required the OwnerClass to be a subclass of the LeakDetector system.
While thinking about this, I have another idea, I’ll try to explain in few lines below:

  • Create a main singleton class “StackCollector”, containing a Callstack object (int id; StringArray stack;)
  • Upon LeakDetector constructor, call the singleton’s addCallstack() method, this method recording the current callstack in a newly allocated Callstack object, and returning the allocated id in the LeakDetector object.
  • Upon leak detection in the destructor, call the singleton’s showCallstack(currentId) method, and this would dump the callstack to the console.

For getting the callstack, I have a lot of code around I can give you, but basically, you have backtrace from gnu Lib C, and StackWalk for Windows. I’ve no idea on Mac however.


#6

Well, here, we don’t really care about the template type.
However it’s perfectly correct code I’ve written, just it will not distinguish between LeakDetector<Colour, “oijoij”> and LeakDetector<Colour, “poiopi”> (in the example I’ve used, it doesn’t really care), the second one will just not instantiate a new object.
In fact I could even have written since it’s all hidden in the macro magic:

 template <class OwnerClass, const unsigned long long file, const unsigned int line>
class LeakDetector
{
    [...]
    LeakDetector() : filename((const char*)file, line) 


  #define JUCE_LEAK_DETECTOR(OwnerClass)         LeakedObjectDetector<OwnerClass, (unsigned long long)(void*)__FILE__, __LINE__> JUCE_JOIN_MACRO (leakDetector, __LINE__);

#7

No, it’s really not possible to use strings as template parameters in a robust way. If you try something hacky like casting the pointer to an integer, some compilers will fail to actually add the original string into the binary, because they don’t think you’re using it.

Have you checked the tip recently? I updated it a while ago to return the class name from a static function - have a look at what I’ve done, because it’s a non-hacky way to achieve something similar.


#8

I’d have swear I did a few hour ago, through the Jucer’s auto update function.
Ok, I now get what you’ve done it’s way better.
What about the other idea I’ve talked about ?


#9

About keeping track of the places it gets used? Sure, it’s possible, but my aim with the class was not to create a fully-featured leak debugger, it’s just a quick-and-dirty check to see if there’s a problem. Since it adds almost no overhead, the idea is that you keep it turned on, and if it finds a problem that’s not obvious, you can fire up a proper detector to track it down.