Strange exceptions in .Net CF framework code under WinCE 6.0 R3
In our .Net CF app we are getting weird errors from parts of the code that shouldn't be having problems. For instance, the following code:
public void AddParm(string str)
{
string[] pair = str.Split('=');
string key = pair[0].Trim();
string value = pair.Length > 1 ? pair[1] : "";
if (key.Length >开发者_StackOverflow社区; 0)
{
if (_parmTable.ContainsKey(key))
_parmTable[key] = value;
else
_parmTable.Add(key, value);
}
}
The routine that calls AddParm() wraps the call in a Try...Catch block, catching all Exception types.
public void Unpack(string txn)
{
try
{
// split out strings like: "EVENTLABEL:x=1,y=2,z=3"
char chEvent = ':';
char chSeparator = ',';
_parmTable = new Hashtable();
int iEvent = txn.IndexOf(chEvent);
if (iEvent == -1)
_eventLabel = txn;
else
{
_eventLabel = txn.Substring(0, iEvent);
string parms = txn.Substring(iEvent + 1).TrimEnd('\n');
string[] items = parms.Split(chSeparator);
if (items.Length <= 0)
AddParm(parms);
else
foreach (string item in items)
AddParm(item);
}
}
catch (Exception ex)
{
AppLog.logException(string.Format("UnpackedTask.Unpack: Error parsing '{0}'", txn), ex);
}
}
I just got a core unhandled exception listing the faulting module as mscoree3_5.dll. The stack trace shows:
at ArrayList.InternalSetCapacity(Int32 value, Boolean updateVersion) at ArrayList.EnsureCapacity(Int32 min) at ArrayList.Add(Object value) at String.Split(Char[] separator) at AddParm(String str)
This is happening on a worker thread.
I did register a handler with AppDomain.CurrentDomain.UnhandledException in Main but it doesn't catch the exception either.
Unfortunately the WinCE error dialog that comes up does not state the type of error or give an error message, just that it was in mscoree3_5.dll and the stack trace.
We create the values that get parsed by AddParm and I think AddParm is defensive enough that it would catch any potential problems before the Split call. Due to the way AddParm is called it wouldn't ever be called with a null string. Even though I don't believe AddParm could ever be called with something that is invalid, the Try...Catch wrapping the call should always catch the exception but it doesn't.
Similarly we have also seen uncaught errors like this:
A native exception has occurred on BbCore.exe At RuntimeType.InternalGetField(rt…) At RuntimeType.InternalGetField(rt…) At SRSupport.GetString() At SRSupport.GetString() At IPAddress.Parse(String ipString)
Here's a full stack trace from one this morning:
At CurrentSystemTimeZone.GetDaylightChanges(Int32 year) At CurrentSystemTimeZone.GetUtcOffsetFromUniversalTime(DateTime time, Boolean& isAmbiguousLocalDst) At CurrentSystemTimeZone.ToLocalTime(DateTime time) At DateTime.ToLocalTime() At DateTime.get_Now() At MainLoop.timer1_Tick(Object sender, EventArgs e) At Timer._WnProc(WM wm, Int32 wParam, Int32 lParam) At ApplicationThreadContext._InternalContextMessages(WM wm, Int32 wParam, Int32 lParam) At NativeMethods.GetMessage(MSG& lpMsg, IntPtr hWnd, UInt32 wMsgFilterMin, UInt32 wMsgFilterMax) At Application2.Pump() At Application2.RunMessageLoop(Boolean showForm) At Application2.Run(Form mainForm, Boolean runAsSingletonApp, Boolean displayMainForm) At Startup.Main()
The Application2 references are due to the use of OpenNetCF.Windows.Forms.dll. I have never seen a crash in that part of the code, it's basically random.
That's another case where IPAddress.Parse is called from within a Try...Catch that catches all Exception types. In that case I believe it was possible for Parse to be called with an empty string but I don't understand why it showed up as an unhandled exception and didn't even get caught by our unhandled exception handler but instead got caught by the WindowsCE exception handler and caused the whole app to crash.
It seems like these are more common since we updated to WinCE 6 R3 platform builder from R2. I'm not sure if they ever happened under R2 but they certainly were less frequent. Even now they don't always happen - I can't reliably reproduce them.
Any ideas? Why would core parts of the framework throw errors that don't get caught by Try..Catch?
Extra info: It appears I left out a critical piece of information. The ExceptionCode is listed as 0x80000002 which appears to be a native out of memory exception. According to the garbage collector our app rarely uses more than 1MB of memory. According to coredll.dll's GlobalMemoryStatus the typical memory load for the system is about 29% (41MB free out of 57MB). Are there any good utilities out there that might be able to monitor and log the total system memory use over time? I'm starting to wonder if the techniques I'm using to measure memory use aren't as accurate as I thought. Using OpenNetCF.ToolHelp.ProcessEntry.GetProcesses() shows our process using about 3.6MB and NK.exe using about 2.5 MB.
Turned out it was a buffer overrun error in native code. the C# code was calling into a method and passing a byte array with 8 elements. The C++ code was filling 6 bytes then overwriting another 6 with zeroes. This method got called quite a lot and every time it was overwriting 4 bytes of memory with zeroes. Doh!
That explains the utterly strange errors, probably was overwriting bits of the .Net framework in memory.
Gotta watch out for those interactions between managed and unmanaged code. Fortunately for me, the code in question wasn't mine.
(Not sure if I should accept my own answer as the answer since no one could have answered this without looking at our code base. Likewise I shouldn't mark JaredPar's answer as "the answer" since the problem was memory corruption, not really a native exception. I guess I'll post this anyway since maybe someone else will have a similar situation and maybe they'll look into interactions with native code. Admins: feel free to delete this thread if you think that's best.)
I think the message on your second trace is the most instructive
A native exception has occurred on BbCore.exe
It appears that it's a native exception not a managed exception that is taking down your product. Native exceptions are as a general rule not catchable by managed code. It is possible in certain cases but generally speaking native exceptions are fatal.
You can try to use the catch block for SEH exceptions and see if that works.
try {
...
} catch {
}
But in general if the native code is throwing your application is unstable and it should crash.
I just run into this error in a new version of my application. Tried several things, in the last, I removed the 256x256 and 64x64 images in the form icon which are replaced in this version, and it worked.
精彩评论