Windows/C++: действительно ли возможно найти строку кода, где исключение было выдано, сместив “Исключение”

Один из наших пользователей, имеющих Исключение на нашем запуске продукта. Она отправила нам следующее сообщение об ошибке от Windows:

  Problem Event Name:                        APPCRASH
  Application Name:                          program.exe
  Application Version:                       1.0.0.1
  Application Timestamp:                     4ba62004
  Fault Module Name:                         agcutils.dll
  Fault Module Version:                      1.0.0.1
  Fault Module Timestamp:                    48dbd973
  Exception Code:                            c0000005
  Exception Offset:                          000038d7
  OS Version:                                6.0.6002.2.2.0.768.2
  Locale ID:                                 1033
  Additional Information 1:                  381d
  Additional Information 2:                  fdf78cd6110fd6ff90e9fff3d6ab377d
  Additional Information 3:                  b2df
  Additional Information 4:                  a3da65b92a4f9b2faa205d199b0aa9ef

Действительно ли возможно определить местоположение точного места в исходном коде, где исключение произошло, имея эту информацию?

Какова общая техника для программистов на C++ в Windows для определения местоположения места ошибки, которая произошла на компьютере пользователей?

Наш проект компилируется с конфигурацией Выпуска, файл PDB сгенерирован.

Я надеюсь, что мой вопрос не слишком наивен.

43
задан Pavel 27 March 2010 в 09:42
поделиться

3 ответа

Да, это возможно. Начните отладку с теми же двоичными файлами, которые запущены вашим пользователем, убедитесь, что DLL загружена и у вас есть соответствующий PDB-файл для нее. Найдите в Debug + Windows + Modules базовый адрес DLL. Добавьте смещение. Debug + Windows + Disassembly и введите вычисленный адрес в поле Address (префикс с 0x). Это показывает вам точную инструкцию машинного кода, которая вызвала исключение. Щелкните правой кнопкой мыши + Перейти к исходному коду, чтобы увидеть соответствующую строку исходного кода.

Хотя это и показывает вам утверждение, обычно этого недостаточно для диагностики причины. Исключение 0xc0000005 - нарушение прав доступа, у него много возможных причин. Часто вы даже не получаете никакого кода, программа могла уйти в небытие из-за поврежденного стека. Или настоящая проблема находится далеко, какая-то манипуляция с указателем, которая повредила кучу. Вам также обычно действительно нужна трассировка стека, которая показывает, как программа попала в провалившийся оператор.

Что вам нужно, так это мини-дамп. Вы можете легко получить его от своего пользователя, если он работает под Vista или Win7. Запустите TaskMgr.exe, вкладка «Процессы», выберите взорванную программу, пока она все еще отображает диалоговое окно сбоя. Щелкните его правой кнопкой мыши и создайте файл дампа.

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

68
ответ дан 26 November 2019 в 22:55
поделиться

Информация об исходном коде не сохраняется в скомпилированном коде C ++, в отличие от языков времени выполнения, поддерживающих метаданные (таких как .NET или Java). Файл PDB представляет собой индекс символа, который может помочь отладчику отобразить скомпилированный код обратно в исходный код, но это должно быть сделано во время выполнения программы, а не из аварийного дампа. Даже с PDB код, скомпилированный с помощью Release, подвергается ряду оптимизаций, которые могут помешать отладчику идентифицировать исходный код.

Отладка проблем, которые проявляются только на машинах конечных пользователей, обычно сводится к тщательной регистрации состояния и тщательному изучению источника времени и усилий. В зависимости от ваших взаимоотношений с пользователем (например, если вы занимаетесь внутренним ИТ-разработкой компании), вы можете создать образ виртуальной машины для машины пользователя и использовать его для отладки, что может значительно ускорить процесс за счет точной тиражирование установленного программного обеспечения и стандартных запущенных процессов на рабочую станцию ​​пользователя.

1
ответ дан 26 November 2019 в 22:55
поделиться

Если у вас есть минидамп, откройте его в Visual Studio, установите MODPATH на соответствующие папки с исходными двоичными файлами и PDB, и скажите ему "запустить". Вам также может потребоваться указать ему загрузить символы с серверов символов Microsoft. Программа отобразит стек вызовов в месте ошибки. Если вы попытаетесь просмотреть исходный код для определенного места стека, программа может спросить вас, где находится исходный код; если это так, выберите соответствующую папку с исходным кодом. MODPATH устанавливается в свойствах командной строки отладки для "проекта", который имеет имя файла минидампа.

4
ответ дан 26 November 2019 в 22:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: