Re: StackOverflowException.
- From: "Robert Bouillon" <djwhizzard@xxxxxxxxxxx>
- Date: Mon, 25 Apr 2005 20:06:00 -0400
Willy,
Thanks for the reply :)
My call stack is only 27 calls deep: 17 of them are Windows Forms calls (via
"Show non-user code"). I checked all of my threads as well and they're all
behaving normally. To-date, on StackOverflows caused by recursion, I've
always gotten an exception. I've tried to reproduce this error 3 times, and
only once did I get this exception. The other 2 times I got obscure errors
and was unable to view my local variables, leading me to believe that lack
of stack space caused my VM to go screwy.
I narrowed it down to what I believe may be the culprit. I recently added a
"Status" subclass to my Rs232Stream class. The Status object monitors the
Serial Port in an infinite loop, on background thread, making calls to
win32. Disabling this thread alleviates the problem.
Here's a snippet (C#):
=====================================
/// <summary>
/// Monitors the Serial Port opened by the parent stream for events
/// </summary>
/// <remarks>
/// Sits directly on the m_StatusThread
/// <see cref="Parent"/>
/// <see cref="m_StatusThread"/>
/// </remarks>
private void Monitor()
{
InitEventMask();
while(true)
{
if(!WaitCommEvent(p_Parent.hPort, m_UnmanagedCurrentEvent,
m_UnmanagedOverlappedHandle))
{
NativeError err = Win32Exception.Check(false);
if (err!= NativeError.ERROR_IO_PENDING)
throw new IOException("Error setting comm event handle", new
Win32Exception());
}
m_StatusChangeEvent.WaitOne();
Requery(p_Parent.hPort);
}
}
public Rs232Status(Rs232Stream parent)
{
p_Parent = parent;
Overlapped wo = new Overlapped();
wo.hEvent = m_StatusChangeEvent.Handle;
m_UnmanagedOverlappedHandle =
Marshal.AllocHGlobal(Marshal.SizeOf(wo));
Marshal.StructureToPtr(wo, m_UnmanagedOverlappedHandle, true);
m_UnmanagedCurrentEvent =
Marshal.AllocHGlobal(Marshal.SizeOf(Type.GetType("System.UInt32")));
Marshal.WriteInt32(m_UnmanagedCurrentEvent,0);
}
/// <summary>
/// Checks the status of the Flow Control Lines
/// </summary>
/// <param name="portHandle">Handle to the opened port</param>
/// <remarks>Called by Requery</remarks>
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");
{...} //---> Event Calls and Field Updates
}
===============================
InitEventMask encapsulates the Win32 SetCommMask call. Requery is a lot of
bloated code that checks the Event Flags and calls some OnXXXX methods to
fire events and update some local fields.
It's pretty cut-and-dry. It's an infinite loop that makes a few minor calls
to unmanaged IO code. No unmanaged memory is allocated outside of the ctor,
so I'm really at a total loss as to where I'm leaking stack memory.
I don't mind posting the entire status class here, but I know how painful
that is so I'm going to just post the calls I make to unmanaged code or the
marshaller. Perhaps you'll see a function that manipulates memory or catch
something I'm missing?
[DllImport("kernel32.dll")]
EscapeCommFunction
ClearCommError
GetOverlappedResult
WaitCommEvent
SetCommMask
GetCommModemStatus
[.NET Interop]
Marshal.ReadInt32
Marshal.StructureToPtr
Here's an idea: My EscapeCommFunction has the following declaration:
[DllImport("kernel32.dll")]
private static extern bool EscapeCommFunction(IntPtr hFile, CommFunction
dwFunc);
CommFunction is a private managed struct I use in the class. I prefer to let
..NET interop marshal my variables for me to save time / code. Is it possible
that in this scenario, the dwFunc is never being destroyed? I'm not
destroying it explicitly.
Thanks.
--ROBERT
P.S. Good to know about arrays. I could have sworn I read something that
said blittable-typed arrays were stored on the stack. At least that gives
stackalloc a little more prominence :) I wish there was a way that
strong-typed streams could access stackalloc arrays, but we all know the
rules about pointers in the CLR :-/
.
- References:
- StackOverflowException.
- From: Robert Bouillon
- Re: StackOverflowException.
- From: Willy Denoyette [MVP]
- StackOverflowException.
- Prev by Date: Re: Array.Find<> example
- Next by Date: How to make multiple or consecutive webrequests using the same connection or session
- Previous by thread: Re: StackOverflowException.
- Next by thread: RE: StackOverflowException.
- Index(es):
Relevant Pages
|