Странные исключения в .NET CF framework code под WinCE 6.0 R3 - PullRequest
3 голосов
/ 11 февраля 2010

В нашем приложении .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);
    }
}

Подпрограмма, которая вызывает AddParm (), упаковывает вызов в блок 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)

Это происходит в рабочем потоке.

Я зарегистрировал обработчик в AppDomain.CurrentDomain.UnhandledException в Main, но он также не перехватывает исключение.

К сожалению, в появившемся диалоговом окне ошибок WinCE не указывается тип ошибки и не выдается сообщение об ошибке, а только то, что это было в mscoree3_5.dll и трассировке стека.

Мы создаем значения, которые анализируются AddParm, и я думаю, что AddParm достаточно защищен, чтобы он мог уловить любые потенциальные проблемы перед вызовом Split. Из-за способа вызова AddParm он никогда не будет вызываться с пустой строкой. Несмотря на то, что я не верю, что AddParm мог бы быть вызван с чем-то недопустимым, Try ... 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()

Ссылки Application2 связаны с использованием OpenNetCF.Windows.Forms.dll. Я никогда не видел сбоев в этой части кода, это в основном случайное.

Это еще один случай, когда IPAddress.Parse вызывается из попытки Try ... Catch, которая перехватывает все типы исключений. В этом случае я считаю, что Parse можно было вызывать с пустой строкой, но я не понимаю, почему он обнаружился как необработанное исключение и даже не попал в наш обработчик необработанного исключения, а вместо этого был пойман WindowsCE обработчик исключений и вызвал сбой всего приложения.

Похоже, что они более распространены, так как мы обновились до сборщика платформ WinCE 6 R3 из R2. Я не уверен, что они когда-либо случались под R2, но они, конечно, были реже. Даже сейчас они не всегда случаются - я не могу их достоверно воспроизвести.

Есть идеи? Почему основные части фреймворка генерируют ошибки, которые не попадают в Try..Catch?

Дополнительная информация: Похоже, я пропустил важную информацию. Код ExceptionCode указан как 0x80000002, который выглядит как собственное исключение из-за нехватки памяти. По словам сборщика мусора, наше приложение редко использует более 1 МБ памяти. Согласно GlobalMemoryStatus coredll.dll типичная загрузка памяти для системы составляет около 29% (41 МБ свободно из 57 МБ). Существуют ли какие-либо полезные утилиты, которые могли бы отслеживать и регистрировать общее использование системной памяти с течением времени? Я начинаю задаваться вопросом, не являются ли методы, которые я использую для измерения использования памяти, не такими точными, как я думал. Использование OpenNetCF.ToolHelp.ProcessEntry.GetProcesses () показывает наш процесс с использованием около 3,6 МБ и NK.exe с использованием около 2,5 МБ.

Ответы [ 3 ]

3 голосов
/ 23 февраля 2010

Оказалось, что это была ошибка переполнения буфера в нативном коде. код C # вызывал метод и передавал байтовый массив с 8 элементами. Код C ++ заполнял 6 байтов, а затем перезаписывал еще шесть нулей. Этот метод вызывается довольно часто, и каждый раз он перезаписывает 4 байта памяти нулями. Doh!

Это объясняет совершенно странные ошибки, вероятно, перезаписывающие биты .Net framework в памяти.

Должен следить за тем взаимодействием между управляемым и неуправляемым кодом. К счастью для меня, рассматриваемый код не был моим.

(Не уверен, должен ли я принять свой собственный ответ в качестве ответа, поскольку никто не мог бы ответить на этот вопрос, не взглянув на нашу кодовую базу. Аналогичным образом я не должен отмечать ответ JaredPar как «ответ», поскольку проблема заключалась в повреждении памяти, на самом деле не является собственным исключением. Думаю, я опубликую это в любом случае, поскольку, возможно, у кого-то еще будет похожая ситуация, и, возможно, они рассмотрят взаимодействие с нативным кодом. Администраторы: не стесняйтесь удалять эту ветку, если считаете, что это лучше.)

1 голос
/ 11 февраля 2010

Я думаю, что сообщение о вашем втором следе является наиболее поучительным

Произошло собственное исключение на BbCore.exe

Похоже, что это нативное исключение, а не управляемое исключение, которое уничтожает ваш продукт. Собственные исключения, как правило, не распознаются управляемым кодом. В некоторых случаях это возможно, но, вообще говоря, местные исключения являются фатальными.

Вы можете попробовать использовать блок catch для исключений SEH и посмотреть, работает ли он.

try { 
  ...
} catch { 

}

Но в целом, если исходный код генерирует ваше приложение нестабильно, и оно должно аварийно завершить работу.

0 голосов
/ 21 мая 2014

Я просто столкнулся с этой ошибкой в ​​новой версии моего приложения. Попробовал несколько вещей, в последнем я удалил изображения 256x256 и 64x64 в значке формы, которые заменены в этой версии, и это сработало.

...