none
Как вернуть вывод отладочной информации при аварийном падении приложения как это было в WinXP? RRS feed

  • Вопрос

  • Сначала задавал вопрос в теме windows 7, но мне посоветовали его отправить сюда:

    Раньше, в WinXP, когда приложение, написанное на .NET падало, то вылетало окошко, в котором была вся информация о ошибке (строка кода, вызвавший метод, стек вызовов и т.д.), что было очень полезно. А сейчас, когда приложение падает, вылетает только маленькое окошко, где система сначала пытается найти решение сама (что ей, естественно, не удается), а затем появляются две кнопки - закрыть и отдебажить.

    Так вот - как вернуть окошко с отладочной информацией, что бы при падении она выводил информацию о исключении, если это исключение не было обработано корректно?

     

    Приложение написано на .NET 4.0

    • Перемещено Tagore Bandlamudi 2 октября 2010 г. 21:09 MSDN Forums consolidation (От:Разработка Windows-приложений)
    16 сентября 2010 г. 7:45

Ответы

  • При дебаге, даже если не подтянулся код, можно посмотреть в окно StackTrace и на детали текущего исключения в окне Watch/Quick Watch, как переменную $exception или @exception.

    $exception.ToString() - это и будет текст из диалога винформ.

    Если очень хочется увидеть именно окно - подпишись в приложении на события AppDomain.CurrentDomain.UnhandledException и System.Windows.Forms.Application.ThreadException. Туда придет почти любой необработанный Exception как раз перед падением приложения.

     

     

    • Помечено в качестве ответа Abolmasov Dmitry 20 декабря 2010 г. 16:50
    18 сентября 2010 г. 20:16
  • Ну вот, по документации - все, кроме определенных исключений в 4-ом фреймворке. И даже в 4-ом можно включить "ловлю всего" без изменений в коде. Отдельный вопрос - нужно ли, т.к. при corrupted state может быть небезопасно даже message box показывать. :)

    В целом - лучше заранее продумывать обработку исключений, без расстановки try/catch наугад по всему коду. Есть официальные гайдлайны и Exception Handling App Block в Enterprise Library. Там в документации подробно расписано когда и что ловить. :)

    • Помечено в качестве ответа Abolmasov Dmitry 20 декабря 2010 г. 16:49
    19 сентября 2010 г. 18:09
  • Просто я вспомнил, что похожая проблема где-то была описана и был вариант решения =) Вот и скопировал его сюда =)

    Кстати в документации сказано следующее:

    Начиная с .NET Framework 4 это событие не возникает для исключений, которые повреждают состояние процесса, таких как переполнения стека или нарушения доступа, если только обработчик событий не является критичным с точки зрения безопасности и не содержит атрибут HandleProcessCorruptedStateExceptionsAttribute.

    и следующее:

    На платформе .NET Framework версий 1.0 и 1.1 необработанное исключение, произошедшее в потоке, отличном от главного потока приложения, перехватывается средой CLR и поэтому не вызывает завершения работы приложения.Поэтому событие UnhandledException может быть сгенерировано без завершения работы приложения.Начиная с .NET Framework версии 2.0 эта поддержка необработанных исключений в дочерних потоках удалена из-за кумулятивного эффекта таких "тихих" сбоев, включающего снижение производительности, повреждение данных и блокировки, поскольку все эти аспекты с трудом поддаются отладке.

    Что у меня вызвало сомнение, что одним им можно все перехватить. И как оказалось, еще и код надо под конкретную версию платформы адаптировать.


    E-mail: Svatoslav.Pankratov@gmail.com
    • Помечено в качестве ответа Abolmasov Dmitry 20 декабря 2010 г. 16:50
    18 сентября 2010 г. 20:38

Все ответы

  • Вот так вот это можно сделать:
      try
      {
      // Тут какой-то код, за которым надо следить и в случае чего перехватывать исключения
      }
      catch (Exception e)
      {
      MessageBox.Show("Приложение или объект, вызвавший исключение: " + e.Source + "\n\n" +
        	  "Метод, вызвавший исключение: " + e.TargetSite + "\n\n" +
        	  "Сообщение исключения: " + e.Message,
        	  "Исключение");
      }

    E-mail: Svatoslav.Pankratov@gmail.com
    16 сентября 2010 г. 20:01
  • Это все я понимаю. Но моя программа падает от какого-то исключения, которое я не могу узнать.

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

     

    Раньше, когда программа падала от необработанного исключения, выводилось окно .NET'а  о этом исключении, стек и т.д., но в windows7 или в .net 4 (я так и не выяснил от чего это зависит), выводит просто окно с закрытием программы без какой-либо информации.

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

    17 сентября 2010 г. 13:06
  • Сделайте, чтобы ваша программа делала логи во время своей работы. Думаю это может помочь найти проблемное место. И еще, думаю, что тут надо внимательно изучать код.
    E-mail: Svatoslav.Pankratov@gmail.com
    17 сентября 2010 г. 14:02
  • Можно сделать, что бы при необрабатываемом исключении вылетало вот такое окно?

     

    http://i296.photobucket.com/albums/mm169/kumar_arvind/Feb-Mar-Jan/May-June-July-Aug/W7BCbug.png

    17 сентября 2010 г. 17:21
  • Такое окно показывается в приложениях winforms, в том числе и под .net 4.0 и win 7. Не показывается во всех остальных видах приложений - win service, console app, wpf. 

    Для winform окно можно отключить, выставив в конфиге jitDebugging=true, как и показано на картинке :). Этот параметр указывает приложению на то, что в системе есть полноценный отладчик, и нужно предложить пользователю отладить, а не просто показать message box.

    Если явно вписать в app.config флаг jitDebugging=false, то приложение начнет падать в нужное окно. Вот только непонятно - зачем включать неудобное окно, если можно прямо на месте отдебагать.

    17 сентября 2010 г. 23:03
  • При дебаге он дизасемблирует код, и показывает его только так.

    Значит в WPF подобного окна не получится?

    18 сентября 2010 г. 19:59
  • Вот тут было сказано:

    У WPF-приложений есть очень интересная особенность: если оно обнаруживает необработанное исключение, то поступает не как WinForms-приложение (которое рапортует об этом исключении окном), а просто закрывает приложение... и всё. Тут есть два момента:

    1. Если исключение возникло в основном thread-е программы (то есть в треде, который обрабатывается диспетчером приложения), то тогда можно повешаться на событие приложения UnhandledException (точно не помню название), и посмотреть, что там. Можно отобразить исключение на экран и пометить событие как Handled (если не пометить, то приложение опять-таки закроется).
    2. Если исключение возникло в любом другом thread-е, то тут можно только одно советовать - использовать блоки try...catch, потому что если исключение выпадет из потока, то оно прекрасным образом аварийно завершит всё приложение. С доп. потоками надо осторожно.

    И ещё один очень полезный совет дам: в WPF-приложении делайте что-либо в событии приложения OnStartap абсолютно по минимуму. Пользование объектами WPF-приложения из этого события очень чревато, проверено на себе.


    E-mail: Svatoslav.Pankratov@gmail.com
    18 сентября 2010 г. 20:15
  • При дебаге, даже если не подтянулся код, можно посмотреть в окно StackTrace и на детали текущего исключения в окне Watch/Quick Watch, как переменную $exception или @exception.

    $exception.ToString() - это и будет текст из диалога винформ.

    Если очень хочется увидеть именно окно - подпишись в приложении на события AppDomain.CurrentDomain.UnhandledException и System.Windows.Forms.Application.ThreadException. Туда придет почти любой необработанный Exception как раз перед падением приложения.

     

     

    • Помечено в качестве ответа Abolmasov Dmitry 20 декабря 2010 г. 16:50
    18 сентября 2010 г. 20:16
  • Там оно конечено написано, но AppDomain.UnhandledException ловит эксепшены из всех потоков. Не стоит копипастить не проверив :)
    18 сентября 2010 г. 20:23
  • Просто я вспомнил, что похожая проблема где-то была описана и был вариант решения =) Вот и скопировал его сюда =)

    Кстати в документации сказано следующее:

    Начиная с .NET Framework 4 это событие не возникает для исключений, которые повреждают состояние процесса, таких как переполнения стека или нарушения доступа, если только обработчик событий не является критичным с точки зрения безопасности и не содержит атрибут HandleProcessCorruptedStateExceptionsAttribute.

    и следующее:

    На платформе .NET Framework версий 1.0 и 1.1 необработанное исключение, произошедшее в потоке, отличном от главного потока приложения, перехватывается средой CLR и поэтому не вызывает завершения работы приложения.Поэтому событие UnhandledException может быть сгенерировано без завершения работы приложения.Начиная с .NET Framework версии 2.0 эта поддержка необработанных исключений в дочерних потоках удалена из-за кумулятивного эффекта таких "тихих" сбоев, включающего снижение производительности, повреждение данных и блокировки, поскольку все эти аспекты с трудом поддаются отладке.

    Что у меня вызвало сомнение, что одним им можно все перехватить. И как оказалось, еще и код надо под конкретную версию платформы адаптировать.


    E-mail: Svatoslav.Pankratov@gmail.com
    • Помечено в качестве ответа Abolmasov Dmitry 20 декабря 2010 г. 16:50
    18 сентября 2010 г. 20:38
  • Ну вот, по документации - все, кроме определенных исключений в 4-ом фреймворке. И даже в 4-ом можно включить "ловлю всего" без изменений в коде. Отдельный вопрос - нужно ли, т.к. при corrupted state может быть небезопасно даже message box показывать. :)

    В целом - лучше заранее продумывать обработку исключений, без расстановки try/catch наугад по всему коду. Есть официальные гайдлайны и Exception Handling App Block в Enterprise Library. Там в документации подробно расписано когда и что ловить. :)

    • Помечено в качестве ответа Abolmasov Dmitry 20 декабря 2010 г. 16:49
    19 сентября 2010 г. 18:09
  • Ну вот, по документации - все, кроме определенных исключений в 4-ом фреймворке. И даже в 4-ом можно включить "ловлю всего" без изменений в коде. Отдельный вопрос - нужно ли, т.к. при corrupted state может быть небезопасно даже message box показывать. :)

    В целом - лучше заранее продумывать обработку исключений, без расстановки try/catch наугад по всему коду. Есть официальные гайдлайны и Exception Handling App Block в Enterprise Library. Там в документации подробно расписано когда и что ловить. :)

    Спасибо за линки =) Ша почитаю =)
    E-mail: Svatoslav.Pankratov@gmail.com
    19 сентября 2010 г. 18:36