Dark Bit Factory & Gravity

PROGRAMMING => C / C++ /C# => Topic started by: Raizor on June 27, 2012

Title: C# - Memory leak from PInvoke when debugging
Post by: Raizor on June 27, 2012
This is probably a long shot, but I wondered if anyone had any suggestions for overcoming a problem I'm experiencing.

A little bit of background info to explain the problem:

My soft synth is written in C++, in the form of a lib file. When the synth is used for a demo/intro, the demo will simply link to the lib in order to use it.

For the synth VST GUI, I have a C++ DLL that contains the lib file for the synth. My synth interface is written in C# and I communicate with the synth via a C++ DLL (which links to the synth lib and acts as a wrapper for the synth and exposes various method to initialize the synth, get/set params and patch names etc). The C# GUI communicates by using PInvoke to call the methods in the DLL, which in turn calls methods in the synth lib code.

My problem is that when debugging, the C# code calls a method in the DLL to initialize the synth which creates all the synth parts in memory (patches, wavetables etc etc). When debugging terminates, I'm left with a rather large memory leak as the memory allocated by the native code is not freed. After a few test runs in Visual Studio using the debugger, I'm out of memory.

I'm wondering if there is any way round this without having explicit cleanup code in the DLL to free the memory? I'm also concerned that if I do add code to free the memory, I will have no way to call it when debugging terminates and execution is suddenly halted before I get a chance to fire off a call to the cleanup code and free the memory.

Any suggestions most appreciated, many thanks,

Raizor
Title: Re: C# - Memory leak from PInvoke when debugging
Post by: Canopy on June 27, 2012

so if you're running of memory i assume the process under which its allocated hasn't terminated?

is that some kind of persistent runtime?
Title: Re: C# - Memory leak from PInvoke when debugging
Post by: Raizor on June 27, 2012
It should have terminated. The app that I'm debugging is the C# test app that makes calls into the native C++ DLL. When the debugging terminates, the C# app is killed but the memory allocated by the invoked native C++ methods doesn't get freed. The only solution at present, is to restart visual studio when I run out of mem, which is a bit of a pain :(
Title: Re: C# - Memory leak from PInvoke when debugging
Post by: Canopy on June 27, 2012
sounds weird as when your app being debugged terminates it "should" be all cleaned up

never tried it, but one way around it might be to use msvsmon and remote debug back to the local machine so that you only have to restart msvsmon if the problem still persists, it also might make the problem go away.

either that or free up the memory in the native DLLs DLL process detach handler?
Title: Re: C# - Memory leak from PInvoke when debugging
Post by: Raizor on June 27, 2012
Yea, it is odd Canopy. Thanks for the input :)
Title: Re: C# - Memory leak from PInvoke when debugging
Post by: TinDragon on June 27, 2012
** Slightly off topic bit **

Not sure I followed your 1st post correctly but it reads to me like your c# GUI is using a c++.dll to access the c++.dll with the synth in? Or do you mean you have a c++.dll with the synth in which also contains a seperate group of c++ functions to expose the synth functions to c#? 

Either way it sounds overly complex, wouldnt it be easier to have the synth functions in the dll directly exposed to c# since the dll is by the sound of it only really for use with the editor and you will static link the synth .lib for actual production?  Not having done much in c# I assume you added the wrapper as c# needs the funcions called slightly differently than c/c++ would, but your I would assume compiling 2 different versions of the lib for static and dynamic linking by the sound of it so why not make the dll version more c# friendly to start with :)

**On Topic Bit**

On your current memory leak issue, I would hazard a guess that the main c# code is ok but the calls made by/to the dll for the synth are not and windows is for whatever reason assigning VS as the original calling exe, hence why it clears when you close it. Your synth dll is probably allocating memory thats not done in a managed way somewhere so isnt being GC'd by the c# side, if your wrapper functions are actually to work round that then perhaps look into them? I have seen posted about this sort of issue with using dll's with c#, tho not exactly how you'ved discribed, and its always to do with the managed vs unmanaged memory so its probably something to do with that here as well.

Probably all stuff you know how to do, certainly better than me in c#, but sometimes when were staring at are own code we miss simple things so checking the basic's from a friendly nudge never hurts :)

Not the most helpful post I have ever written but my c# skills are abit crap  :-[

Title: Re: C# - Memory leak from PInvoke when debugging
Post by: Canopy on June 27, 2012
for whatever reason assigning VS as the original calling exe, hence why it clears when you close it.

i think you just made me realist how to fix it.

the "whateever reason" is because the debugged process is a child process of VS .

i think if the "Local Windows Debugger" setting iin VS is set to Attach = Yes.. then it will spawn in its own process, and then attach rather than being a child process of visual studio.
Title: Re: C# - Memory leak from PInvoke when debugging
Post by: Raizor on June 27, 2012
TinDragon, there's only one C++, which acts as a wrapper round the synth library:

C++ Synth Library (.lib) -> C++ Wrapper DLL -> C# Synth GUI

so no double DLL shenanigans.

I think you and Canopy may be right in regard to the unmanaged code being attached to VS. I wonder if I can stop that without losing the ability to debug the native/unmanaged code while running the managed/C# project. Something to check, thanks for the pointers (pun intended!) :)

K++
Title: Re: C# - Memory leak from PInvoke when debugging
Post by: Jim on June 27, 2012
Sounds a bit odd.  If the process is actually terminating then it should be freeing all the memory allocations made from the heap although it will not free other unmanaged resources like DirectSound buffers.

Two things I'd try:
1. Project->Properties->Debug - uncheck 'Enable the Visual Studio hosting process'.
2. Start without debugging and attach the debugger afterwards using Debug->Attach to Process...

Jim
Title: Re: C# - Memory leak from PInvoke when debugging
Post by: Raizor on June 28, 2012
Thanks Jim.

Disabling the hosting process doesn't seem to make any difference. I'll just leave it for now and restart when it craps out. Will end up spending more time fixing the problem than it saves if I'm not careful :)
Title: Re: C# - Memory leak from PInvoke when debugging
Post by: Jim on June 29, 2012
Did you try 2?

You can't possibly have wasted as much time as I have cursing at my Raspberry Pi for not rendering my OpenGL, and then me finally realising I'm rendering a 100% transparent quad! :P

Jim
Title: Re: C# - Memory leak from PInvoke when debugging
Post by: Raizor on June 29, 2012
Did you try 2?

You can't possibly have wasted as much time as I have cursing at my Raspberry Pi for not rendering my OpenGL, and then me finally realising I'm rendering a 100% transparent quad! :P

Jim

I've not tried 2, I figured that would be quite a pain to do repeatedly. I will give it a try today though, just to see if it works.

Transparent quads are OpenGL Nirvana! You are truly enlightened :)
Title: Re: C# - Memory leak from PInvoke when debugging
Post by: Raizor on June 29, 2012
I tried the 'start without debugging' technique. More weirdness. devenv.exe's memory usage shoots up each time and the memory still isn't freed after closing the app. This happens even when I don't manually attach the debugger. Most weird :P
Title: Re: C# - Memory leak from PInvoke when debugging
Post by: hellfire on June 29, 2012
It doesn't call DllMain when terminating the debugger?

Title: Re: C# - Memory leak from PInvoke when debugging
Post by: Raizor on June 29, 2012
It doesn't call DllMain when terminating the debugger?

Nope.

Called once with DLL_PROCESS_ATTACH reason for call on startup and then several calls with DLL_THREAD_ATTACH. Nothing at all when debugging is terminated though.