Один из наших пользователей, имеющих Исключение на нашем запуске продукта. Она отправила нам следующее сообщение об ошибке от 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 сгенерирован.
Я надеюсь, что мой вопрос не слишком наивен.
Да, это возможно. Начните отладку с теми же двоичными файлами, которые запущены вашим пользователем, убедитесь, что DLL загружена и у вас есть соответствующий PDB-файл для нее. Найдите в Debug + Windows + Modules базовый адрес DLL. Добавьте смещение. Debug + Windows + Disassembly и введите вычисленный адрес в поле Address (префикс с 0x). Это показывает вам точную инструкцию машинного кода, которая вызвала исключение. Щелкните правой кнопкой мыши + Перейти к исходному коду, чтобы увидеть соответствующую строку исходного кода.
Хотя это и показывает вам утверждение, обычно этого недостаточно для диагностики причины. Исключение 0xc0000005 - нарушение прав доступа, у него много возможных причин. Часто вы даже не получаете никакого кода, программа могла уйти в небытие из-за поврежденного стека. Или настоящая проблема находится далеко, какая-то манипуляция с указателем, которая повредила кучу. Вам также обычно действительно нужна трассировка стека, которая показывает, как программа попала в провалившийся оператор.
Что вам нужно, так это мини-дамп. Вы можете легко получить его от своего пользователя, если он работает под Vista или Win7. Запустите TaskMgr.exe, вкладка «Процессы», выберите взорванную программу, пока она все еще отображает диалоговое окно сбоя. Щелкните его правой кнопкой мыши и создайте файл дампа.
Чтобы сделать это гладко, вы действительно хотите автоматизировать эту процедуру. Вы найдете подсказки в моем ответе в этой ветке .
Информация об исходном коде не сохраняется в скомпилированном коде C ++, в отличие от языков времени выполнения, поддерживающих метаданные (таких как .NET или Java). Файл PDB представляет собой индекс символа, который может помочь отладчику отобразить скомпилированный код обратно в исходный код, но это должно быть сделано во время выполнения программы, а не из аварийного дампа. Даже с PDB код, скомпилированный с помощью Release, подвергается ряду оптимизаций, которые могут помешать отладчику идентифицировать исходный код.
Отладка проблем, которые проявляются только на машинах конечных пользователей, обычно сводится к тщательной регистрации состояния и тщательному изучению источника времени и усилий. В зависимости от ваших взаимоотношений с пользователем (например, если вы занимаетесь внутренним ИТ-разработкой компании), вы можете создать образ виртуальной машины для машины пользователя и использовать его для отладки, что может значительно ускорить процесс за счет точной тиражирование установленного программного обеспечения и стандартных запущенных процессов на рабочую станцию пользователя.
Если у вас есть минидамп, откройте его в Visual Studio, установите MODPATH на соответствующие папки с исходными двоичными файлами и PDB, и скажите ему "запустить". Вам также может потребоваться указать ему загрузить символы с серверов символов Microsoft. Программа отобразит стек вызовов в месте ошибки. Если вы попытаетесь просмотреть исходный код для определенного места стека, программа может спросить вас, где находится исходный код; если это так, выберите соответствующую папку с исходным кодом. MODPATH устанавливается в свойствах командной строки отладки для "проекта", который имеет имя файла минидампа.