Stack imbalance between SharedMemoryMgr and SharedQueue


SharedMemoryMgr uses the cdecl calling convention for five methods. The SharedQueue class that calls these methods uses the stdcall convention. As a result, there is a memory leak every time a call is made, because each side assumes the other will clean up the stack.
Here are the declarations in SharedMemoryMgr (C++):
extern INT32 __cdecl InitMemoryMgr(LPCTSTR SharedMemoryName, DWORD SharedMemorySize, PCOMMBUFFER *CommBufferIn);
extern INT32 __cdecl JoinMemoryMgr(LPCTSTR SharedMemoryName, PCOMMBUFFER *CommBufferIn);
extern INT32 __cdecl ReleaseMemoryMgr(PCOMMBUFFER *CommBufferIn);
extern INT32 __cdecl PutBuffer(LPCSTR pEventBuffer, DWORD dwEventLength, DWORD dwTimeOut, PCOMMBUFFER *CommBufferIn);
extern INT32 __cdecl GetBuffer(LPCSTR pEventBuffer, DWORD dwEventBufferLength, DWORD dwTimeOut, DWORD *pBytesRead, PCOMMBUFFER *CommBufferIn);
Here is a sample C# declaration, in SharedQueue.cs:
        [DllImport(SharedMemoryMgr, ExactSpelling = true, CharSet = CharSet.Ansi)]
        internal static extern ReturnCode InitMemoryMgr(
            String sharedMemoryName,
            UInt32 sharedMemorySize,
            ref IntPtr commBuffer);
To fix this issue, the DllImportAttribute should have the calling convention specified:
        [DllImport(SharedMemoryMgr, ExactSpelling = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        internal static extern ReturnCode InitMemoryMgr(
            String sharedMemoryName,
            UInt32 sharedMemorySize,
            ref IntPtr commBuffer);
Closed Dec 11, 2010 at 2:50 AM by keithh
Bug is fixed and code checked-in.


keithh wrote Dec 3, 2010 at 4:35 PM

Thanks for the find. I am making some other changes to the code and will check everything in sometime in January.

Coffee_fan wrote Dec 4, 2010 at 2:15 AM

Thanks DeeGee and Keith. Please keep in mind that the impact may not be low if you are sending thousands of events per second. Added my vote for a fix.

DeeGee wrote Dec 4, 2010 at 7:16 PM

I've rebuilt the projects using .NET 4.0, and I'm in the midst of replacing SharedMemoryMgr.dll with a set of .NET classes in the SharedQueue assembly, since we now have a System.IO.MemoryMapped file class. I don't know how performance will compare, but in our environment there have been issues deploying the SharedMemoryMgr to all locations where we need it.

keithh wrote Dec 6, 2010 at 8:58 PM

I will be testing the fixes later today. If all works well, I'll update Codeplex.

I'll be interested to hear how well an all .Net version of the SharedMemoryMgr works. Using shared memory from .Net via pinvokes was too costly. I haven't looked at .Net 4.0's implementation to see how efficient it might be.

keithh wrote Dec 11, 2010 at 12:49 AM

I updated the installs on the download page with the fix. I still need to update the source code and then I'll close this out.