2010-02-11 6 views
3

.Net CF 응용 프로그램에서는 문제가 발생하지 않는 코드 부분에서 이상한 오류가 발생합니다. 예를 들어, 다음 코드 AddParm를 호출WinCE 6.0 R3. NET CF 프레임 워크 코드의 이상한 예외

public void AddParm(string str) 
{ 
    string[]  pair = str.Split('='); 
    string   key = pair[0].Trim(); 
    string   value = pair.Length > 1 ? pair[1] : ""; 
    if (key.Length > 0) 
    { 
     if (_parmTable.ContainsKey(key)) 
      _parmTable[key] = value; 
     else 
      _parmTable.Add(key, value); 
    } 
} 

루틴() 모든 예외 유형 잡기, try ... catch 블록 안에 전화를 래핑합니다.

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); 
    } 
} 

오류가 발생한 모듈을 mscoree3_5.dll로 나열하는 코어 처리되지 않은 예외가 생겼습니다. 스택 추적에 표시됩니다 :

 
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) 

이것은 작업자 스레드에서 발생합니다.

Main에 AppDomain.CurrentDomain.UnhandledException 처리기를 등록했지만 예외도 catch하지 않았습니다.

불행히도 WinCE 오류 대화 상자에는 mscoree3_5.dll 및 스택 추적에 오류 메시지가 표시되거나 오류 메시지가 표시됩니다.

우리는 AddParm에 의해 파싱되는 값을 만들고 AddParm은 Split 호출 전에 잠재적 인 문제를 잡을만큼 충분히 방어 적이라고 생각합니다. AddParm이 호출되는 방식으로 인해 null 문자열로 호출되지 않습니다. AddParm이 유효하지 않은 무언가로 호출 될 수 있다고는 생각하지 않지만 Try ... Catch는 항상 예외를 catch해야하지만 그렇지 않습니다. 이 같은

마찬가지로 우리는 또한 본 캐치되지 않는 오류 :

 
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) 

여기에 하나에서 전체 스택 추적이 아침 :

 
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() 

응용 프로그램 2 참조가 OpenNetCF.Windows의 사용에 기인 .Forms.dll. 코드의 해당 부분에서 충돌을 본 적이 없습니다. 기본적으로 무작위입니다.

IPAddress.Parse가 모든 예외 유형을 포착하는 Try ... Catch 내에서 호출되는 또 다른 경우입니다. 이 경우 파스가 빈 문자열로 호출 될 수 있다고 생각하지만 왜 처리되지 않은 예외로 나타나고 처리되지 않은 예외 처리기에 잡히지 않고 대신 WindowsCE에 걸렸습니다. 예외 처리기로 인해 전체 앱이 중단되었습니다.

R2에서 WinCE 6 R3 플랫폼 빌더로 업데이트 한 이후로 더 일반적인 것 같습니다. 나는 그들이 R2에서 일어난 적이 있는지 확실하지 않지만 확실히 덜 빈번했다. 지금도 항상 그런 것은 아닙니다. 나는 믿을 수 없을만큼 재현 할 수 없습니다.

아이디어가 있으십니까? 왜 프레임 워크의 핵심 부분이 Try..Catch에 의해 잡히지 않는 오류를 던질 것입니까?

추가 정보 : 중요한 정보를 빠뜨린 것 같습니다. ExceptionCode는 네이티브 메모리 부족 예외로 나타나는 0x80000002로 나열됩니다. 가비지 컬렉터에 따르면 우리 앱은 거의 1MB 이상의 메모리를 거의 사용하지 않습니다. coredll.dll의 GlobalMemoryStatus에 따르면 시스템의 일반적인 메모리로드는 약 29 %입니다 (57MB 중 41MB가 사용되지 않음). 시간이 지남에 따라 전체 시스템 메모리 사용을 모니터링하고 기록 할 수있는 유용한 유틸리티가 있습니까? 메모리 사용량을 측정하는 데 사용하는 기술이 내가 생각한만큼 정확하지 않은지 궁금해지기 시작했습니다. OpenNetCF.ToolHelp.ProcessEntry 사용하기.GetProcesses()는 약 3.6MB를 사용하는 프로세스와 약 2.5MB를 사용하는 NK.exe를 보여줍니다.

+0

"AddParm"메서드를 호출하는 코드와 모든 세부 정보 (전체 스택)가 포함 된 전체 예외 메시지를 포함 할 수 있습니까? –

+0

사실 저는 더 이상 전체 스택을 가지고 있지 않습니다. 내가 보여준 것 이상의 모든 호출은 내부 메소드입니다. WinCE에서이 오류가 발생하고 화면에 표시되기 때문에 더 이상 필요하지 않은 이유가 있습니다. 잡히지 않아서 기록되지 않으며 이후 여러 번 재 작업을 재부팅하여 오류가 발생하기 때문에 다시 일어난다. –

답변

3

네이티브 코드에서 버퍼 오버런 오류가 발생했습니다. C# 코드는 메서드를 호출하고 8 개의 요소가있는 바이트 배열을 전달했습니다. C++ 코드는 6 바이트를 채워서 다른 6을 0으로 덮어 썼습니다. 이 방법은 상당히 많이 호출되었고 4 바이트의 메모리를 0으로 덮어 쓸 때마다 호출되었습니다. 도!

그게 완전히 이상한 오류를 설명, 아마도 메모리의 .Net 프레임 워크의 비트를 덮어 씁니다.

관리 코드와 비 관리 코드 간의 상호 작용을주의해야합니다. 다행히도 저에게 문제의 코드는 제 것이 아니 었습니다.

(아무도 우리 코드베이스를 보지 않고서도이 질문에 답할 수 있었기 때문에 대답을 받아 들일 지 확신 할 수 없습니다.) 마찬가지로, 메모리 손상 문제 때문에 JaredPar의 대답을 "대답"으로 표시하면 안됩니다. , 정말 네이티브 예외가 아닙니다. 어쨌든 누군가 다른 사람이 비슷한 상황을 겪게 될 것이므로 아마도 네이티브 코드와의 상호 작용을 살펴볼 것입니다. 관리자 :이 스레드를 삭제하는 것이 가장 좋습니다.)

+0

당신은 당신 자신의 대답을 받아 들여야합니다;) Btw, 나는 같은 문제를 겪고 있다고 생각합니다. 이것은 내가 가진 몇 가지 의심을 확인시켜줍니다. 감사. – Stormenet

+0

1) 나는 이것에 대한 SO 응답이 어떻게 있는지를 좋아합니다. 2) 나는 사실을 알게 된 지 5 년 후에 그것을 찾아야 만한다는 것을 싫어한다. – OldTinfoil

1

나는 두 번째 추적의 메시지가 가장 유익이 네이티브 예외가 BbCore.exe

발생했습니다

네이티브 예외가 아닌 관리 예외가 있다는 표시라고 생각합니다 당신의 제품을 쓰러 뜨리십시오. 네이티브 예외는 일반적으로 관리 코드에서 catch 할 수없는 예외입니다. 어떤 경우에는 일반적으로 네이티브 예외가 치명적일 수 있습니다.

SEH 예외에 대한 catch 블록을 사용하여 해당 블록이 작동하는지 확인할 수 있습니다.

try { 
    ... 
} catch { 

} 

하지만 일반적으로 네이티브 코드가 응용 프로그램을 던지고있는 경우 불안정하고 충돌이 발생합니다.

+0

그래서 no (Exception ex)를 사용하여 catch하는 것은 관리되지 않는 예외를 catch 할 수 있습니까? 나는 그것을 깨닫지 못했다. 그것은 (Exception ex) Exception에서 파생 된 에러만을 잡아낼 수 있기 때문에 의미가 있습니다. 위대한 팁! –

+0

충돌이 일어난다면 괜찮은 것 같아요.하지만 적어도 로깅하고 싶습니다. 그래서 입력이 충돌을 일으켰다는 것을 알 수 있습니다. 이것이 일어난 때 나는 입력이 코드로 작성한 것 이외의 다른 것이었을 것이라고 믿을 이유가 없으며 매번 메소드를 호출 할 때와 다를 바가 없습니다. 메모리가 손상되고 있는지 궁금해지기 시작했습니다. 입력을 볼 수 있다면 입력이 충돌을 일으켜 야하는지, 입력이 다른 코드가 보낸 것과 다른 경우인지 알 수 있습니다. –

0

내 응용 프로그램의 새 버전에서이 오류가 발생했습니다. 마지막으로 몇 가지 시도해 보았습니다.이 버전에서 대체 된 양식 아이콘으로 256x256 및 64x64 이미지를 제거하고 작동했습니다.

관련 문제