Memory leak hunting
-
On 29/09/2017 at 01:37, xxxxxxxx wrote:
Hi again,
I understand this post isn't quite about the SDK, and probably more C++ related, hence the reason I posted it here in the "General Discussion" area rather than in the SDK part of the forum.After days of trying to track down some memory leaks I realized ... I simply don't know what I am doing.
In the past I used to narrow down the memory leaks to a particular code, from detecting in which part of the plugins things were being performed resulting in memory leaks.
But with this new project, there is just too many things going on at once that I don't know where to start looking.Additionally, I am confused with the information I have regarding memory addresses.
While debugging, looking at the modules I noticed that the plugin (assumably) resides at address 0x7FFA1C2E0000, but using breakpoints in the code to check on the progress of interactions, I notice that all objects are residing around 0x000000DAxxxxxxxx, with a memory leak occuring atMemory Leaks Detected: p:\c4d_perforce_work\release\18.0\modules\c4dplugin\source\src\philip\pluginsystem\operatingsystem.cpp (1323) : Memory leak of 64 bytes () at 000000DA896ABA40 1 blocks not freed
While looking at the .map file generated by Visual Studio, I notice
Preferred load address is 0000000180000000
Now, I understand that this "preferred" load address isn't typically the address the plugin gets loaded at, so all memory address of the .map file will need to be "translated" to the appropriate entry point. But that's where I am confused. What is the actual entry point address of the plugin?
How do I "map" the memory leak address to my objects and functions in the plugin?I have tried google as well, only finding explanations using a simple .exe where the actual entry point address of the application is obvious.
Would appreciate any hints how to proceed.
Thanks,
Daniel -
On 02/10/2017 at 01:18, xxxxxxxx wrote:
Hello,
I'm no expert on this topic so I won't comment on it. But what I can say is that the line above references the allocation of a BaseSelect object. So somewhere a BaseSelect object is allocated that is not freed at the end.
best wishes,
Sebastian -
On 03/10/2017 at 03:50, xxxxxxxx wrote:
Thanks Sebastian.
I commented out pieces of the plugin until I found the part that was responsible for the memory leak.
It was indeed a BaseSelect.
I was using an AutoAlloc<BaseSelect> and assigned a clone of a selection, without first performing a Free().Still, tips on how to detect where the offending call is performed are still welcome. Commenting out pieces is not always a solution. Even if it is it can take up quite some time before finding the right location.
-
On 06/10/2017 at 03:13, xxxxxxxx wrote:
Got a few more memoryleaks popping up.
Knowing what these are about might point me in the right direction were to look.Memory Leaks Detected: p:\c4d_perforce_work\release\19.0\modules\c4dplugin\source\src homas\glsl\gl_program_factory.cpp (7011) : Memory leak of 640 bytes () at 000000BD2EAF38C0 p:\c4d_perforce_work\release\19.0\modules\model\source\gui\ViewportNaviCube.cpp (216) : 5 Memory leaks of 24 bytes (, first leak at 000000C5D62B6980) p:\c4d_perforce_work\release\19.0\modules\model\source\gui\ViewportNaviCube.cpp (217) : 5 Memory leaks of 1128 bytes (, first leak at 000000BD60660980) 3 blocks not freed
p:\c4d_perforce_work\release\19.0\modules\c4dplugin\source\src\philip\objects\polygonobject.cpp (12417) : 6 Memory leaks of 15387 bytes (, first leak at 0000002F30617700)
Thanks
-
On 06/10/2017 at 09:03, xxxxxxxx wrote:
Hello,
these source code locations refer to internal elements of the OpenGL viewport system. It could be that this is somehow related to the HUD system. That's all I can say.
The last issue is related to Ngons (GetNgonEdgesCompact()).
best wishes,
Sebastian -
On 06/10/2017 at 09:14, xxxxxxxx wrote:
Thanks Sebastian.
Ngons ... strange, as I don't support nor handle ngons in my plugin.
Is is that GetNgonEdgesCompact() is internally called as a result of other calls?I have further investigated, and can confirm that the polygon object I was handling does indeed contain Ngons, but no where in the plugin do I call Ngon related functions.
-
On 10/10/2017 at 00:31, xxxxxxxx wrote:
Hello,
based on the memory leak report it is impossible to say in which context GetNgonEdgesCompact() was called. The function is called internally in various situations including selection, subdivision, cloning, UV-editing, etc.
best wishes,
Sebastian -
On 10/10/2017 at 03:33, xxxxxxxx wrote:
I don't know if it's possible but, get the actual call stack linked to the memory leak would be nice.
But since we can't know memory leak on runtime (wich it's obvious), it should be hard, or memory intensive to store a call stack for every new allocation.
Or at least to get block of memory leak detection. A bit like undo where you start/end block and add event for each new allocation.
Or using a metaclass for get memory before/after each functions and allow user to check if it's normal or not.
It's just an idea, it may ask a lot of developpement time for not so much things. -
On 01/11/2017 at 12:19, xxxxxxxx wrote:
Still wondering how to "read/interpret" the memory leak being reported to find the actual place in my plugin where memory leaks are happening. But since no further information is being proposed, I guess it's not something easily explained (if at all possible).
-
On 02/11/2017 at 03:50, xxxxxxxx wrote:
Hello,
as said before, there is no simple way of knowing what causes a memory leak. Typically the problem that causes a memory leak is not a certain line of code but a missing command - a missing deallocation. So a memory leak is not cause by something you do but by something you do not.
The report shows you how many leaks there are and how big they are. So when you test your code you can check if executing your code multiple times does increase the number of leaks or not. Also the size of the leaked object could tell you something.
So the best advice I can give is to carefully handle ownership of allocated memory (e.g. use AutoAllo when possible) and design your code in a way that allows you to test different parts of your code independently.
best wishes,
Sebastian