I've narrowed it doen to a subclass I created to monitor the Win32 events
fired for the Serial Port (Using WaitCommEvent).
The "Status" subclass allocates unmanaged memory for the Event Handle and
Overlapped struct in the ctor and frees the memory in the
(IDisposable).Dispose method for the object. An infinite loop checks the
event / status on a background thread. No memory is allocated explicitly in
this loop, however I'm definately leaking my stack memory from within this
loop.
This leads me to believe it's a problem with my P/Invoke declarations. The
only thing I do differently than most other P/Invoke statements I've seen is
rather than using "out uint" for event masks, I'm using "out MyEnum". I
think this is where my problem lies, however it takes me almost an hour to
reproduce this error so I'm having some difficulty narrowing it down.
<code>
[Flags]
private enum ModemStatus : uint
{
MS_CTS_ON = 0x0010,
MS_DSR_ON = 0x0020,
MS_RING_ON = 0x0040,
MS_RLSD_ON = 0x0080
}
[DllImport("kernel32.dll")]
private static extern bool GetCommModemStatus(IntPtr hFile, out
ModemStatus lpModemStat);
</code>
Do I have to clean lpModemStat explicitly?
Is this possibly a problem with P/Invoke?
How can I explicitly free lpModemStat for testing?
Is there a way for me to watch my stack allocation at runtime?
Thanks in Advance
(P.S. Sorry for the duplicate post. This was originally posted in
microsoft.public.dotnet.framework until I realized that it's likely an
interop issue)
What happens if for example the CTS signal and ring indicator signal are
both on?
...
[DllImport("kernel32.dll")]
private static extern Boolean GetCommModemStatus(IntPtr hFile, out uint
lpModemStat);
...
if(GetCommModemStatus(handle, out modemStatus) == true)
{
bool MS_CTS = ((modemStatus & (uint)ModemStatus.MS_CTS_ON) != 0);
bool MS_DSR = ((modemStatus & (uint)ModemStatus.MS_DSR_ON) != 0);
bool MS_RING = ((modemStatus & (uint)ModemStatus.MS_RING_ON) != 0);
bool MS_RLSD = ((modemStatus & (uint)ModemStatus.MS_RLSD_ON) != 0);
}
Gabriel Lozano-Morán
==========================
[Command Window]
> lpModemStat.ToString()
> "MS_CTS_ON,MS_RING_ON"
==========================
The actual code method is:
==========================
public void UpdateLines()
{
ModemStatus ms;
while(!GetCommModemStatus(p_Parent.hPort,out ms))
if(Win32Exception.Check(false)==NativeError.ERROR_IO_PENDING)
continue;
else
throw new Win32Exception("Error during GetCommModemStatus");
if(((ms&ModemStatus.MS_CTS_ON)!=0)!=p_CTS)
p_CTS = !p_CTS;
if(((ms&ModemStatus.MS_DSR_ON)!=0)!=p_DSR)
p_DSR = !p_DSR;
if(((ms&ModemStatus.MS_RING_ON)!=0)!=p_Ring)
p_Ring = !p_Ring;
if(((ms&ModemStatus.MS_RLSD_ON)!=0)!=p_RLSD)
p_RLSD = !p_RLSD;
}
===========================
Object events are fired as a direct result of an EV_* flag in the calling
method. This method only serves to update line status.
I've found it to make my code a lot cleaner, as long as it's not the cause
of this Memory Leak.
Any ideas on what may be causing this?
--ROBERT
"Gabriel Lozano-Morán" <gabriel...@no-spam.com> wrote in message
news:Oeb4kgoS...@TK2MSFTNGP14.phx.gbl...
Gabriel Lozano-Morán
"Robert Bouillon" <djwhi...@hotmail.com> wrote in message
news:u8kmMIpS...@tk2msftngp13.phx.gbl...
It's worth a shot. It's just difficult, as it takes me about an hour to
reproduce this error.
--ROBERT
"Gabriel Lozano-Morán" <gabriel...@no-spam.com> wrote in message
news:ebA%23eSpSF...@tk2msftngp13.phx.gbl...
private static extern bool WriteFile(IntPtr fFile, Byte[] lpBuffer,
UInt32 nNumberOfBytesToWrite, out UInt32 lpNumberOfBytesWritten,
IntPtr lpOverlapped);
private static extern bool ReadFile(IntPtr hFile, [Out] Byte[] lpBuffer,
UInt32 nNumberOfBytesToRead,
out UInt32 nNumberOfBytesRead, IntPtr lpOverlapped);
was changed to:
static extern bool WriteFile(IntPtr hFile, byte [] lpBuffer,uint
nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten,
[In] ref System.Threading.NativeOverlapped lpOverlapped);
public static extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer,
uint nNumberOfBytesToRead,
out uint lpNumberOfBytesRead, [In] ref
System.Threading.NativeOverlapped lpOverlapped);
Despite the fact that "Overlapped" is a struct, the P/Invoke prevented the
data from being freed when the variable fell out of scope.
Maybe this will help someone in the future. Thanks to everyone who posted.
--ROBERT
"Robert Bouillon" <djwhi...@hotmail.com> wrote in message
news:%23uPmGpp...@TK2MSFTNGP14.phx.gbl...