Как увидеть код С#, вызвавший аварийный дамп в clr.dll?

У меня есть приложение Windows Forms (.NET 4), которое отлично работает на моей машине для разработки, но дает сбой на двух других тестовых машинах. Я могу загрузить минидамп, который он создает в VS2010.

Выбор «Отладка со смешанным» приводит к, по-видимому, бесконечному (я убил devenv примерно через 20 минут) злоупотреблению ЦП Visual Studio.

Когда я «Отлаживаю только с помощью Native», он не может найти источник (хотя я отразил источник в той же папке, что и на тестовой машине). Он просто говорит:

Необработанное исключение по адресу 0x793f5b8c в файле YourWinApp.exe.hdmp: 0xC0000409: 0xc0000409.

А потом показывает мне

Расположение стека вызовов: clr.dll!793f5b8c()

Как узнать, что вызывает сбой приложения? Могу ли я сделать полный аварийный дамп, пока отображается диалоговое окно «Уведомить Microsoft», и поможет ли это?


person Bernhard Hofmann    schedule 23.07.2010    source источник


Ответы (2)


Отладка минидампа должна была быть значительно улучшена в VS2010. Сам еще не видел много доказательств этого, отладка в смешанном режиме выглядит так же неловко, как и раньше, когда я проводил несколько быстрых тестов. Хотя не верьте мне на слово. Однако Native-only никогда не покажет вам управляемый стек вызовов.

Займитесь этим в источнике. Напишите обработчик событий для AppDomain.CurrentDomain.UnhandledException и зарегистрируйте его в методе Main(). Пусть он отображает значение e.ExceptionObject.ToString(), скажем, в окне сообщения. Это дает вам управляемую трассировку стека исключения. Пока отображается это окно сообщения, вы также можете сделать мини-дамп, который должен приблизить вас к месту сбоя.

Однако конкретное исключение, которое вы получаете, определенно указывает на собственный код C/C++. Переполнение буфера, повреждающее стек. Убедитесь, что у вас есть файлы .pdb для любого машинного кода, который использует ваше приложение. И настройте сервер символов Microsoft, чтобы получить хорошую собственную трассировку стека из минидампа.

Изменить: тот факт, что вы не получаете UnhandledException, определенно указывает на проверку целостности стека в CRT. Он был разработан, чтобы не вызывать исключение, а немедленно завершать работу программы. Необходимое поведение, поскольку стек скомпрометирован, код не может предположить, что его можно безопасно раскрутить. Учитывая место сбоя, вполне вероятно, что эта проверка действительно выполняется в коде CLR. Я знаю, что это не было сделано в предыдущих версиях CLR, но это может быть по-другому в версии CLR, включенной в .NET 4.0.

Это затруднит получение управляемой трассировки стека. Вы можете многое перепроектировать из неуправляемой трассировки стека, если вы настроите сервер символов так, чтобы вы получали имена идентификаторов из фреймов стека CLR. Опубликуйте эту трассировку стека в своем вопросе, если вам нужна помощь в ее интерпретации. Ошибка в коде CLR не является маловероятной, кстати, вы можете подумать о том, чтобы позвонить в службу поддержки Microsoft. Однако им потребуется последовательное воспроизведение. Они могут обойтись всей этой важной трассировкой стека, если трудно найти репродукцию. Настройте сервер символов, чтобы получить хорошую трассировку неуправляемого стека. Легко в VS2010: Инструменты + Параметры, Отладка, Символы, отметьте «Серверы символов Microsoft».

person Hans Passant    schedule 23.07.2010
comment
Я не могу вставить код в этот комментарий, потому что он слишком мал, поэтому я разместил его здесь: pastebin.com/WPvB05NV Я попытался последовать вашему предложению и зарегистрировать обработчик для UnhandledException, но исключение по-прежнему возникает без возбуждения события. - person Bernhard Hofmann; 26.07.2010
comment
Извините, я забыл понять: ошибка переполнения буфера стека немедленно завершает работу программы, она не генерирует исключение. Я почти уверен, что этих проверок не было в CLR 2.0, но в CLR 4.0 это может быть по-другому. Грубо говоря, вам может понадобиться помощь службы поддержки Microsoft. Получение последовательного воспроизведения имеет важное значение. - person Hans Passant; 26.07.2010

Вы настраиваете procdump для получения полного дампа памяти, если приложение имеет необработанное исключение. , который вы можете отлаживать в VS или Windbg

И минидамп имеет информацию о стеке вызовов в виде ведерок Ватсона, вот один из CLR и я написали об одном и том же.

Краткое объяснение информации о ведре watson, которую вы видите в средстве просмотра событий для необработанного исключения.

  1. ExeFileName
  2. Версия сборки Exe
  3. Отметка времени сборки Exe
  4. ФИО
  5. Неверная версия сборки
  6. Неверная временная метка сборки
  7. Неверный метод сборки
  8. Неверный метод инструкции IL, вызвавший исключение
  9. Тип исключения
person Naveen    schedule 27.07.2010