Windows / C ++: возможно ли найти строку кода, в которой было сгенерировано исключение, с "Exception Offset" - PullRequest
43 голосов
/ 27 марта 2010

Один из наших пользователей имеет исключение при запуске нашего продукта. Она отправила нам следующее сообщение об ошибке из 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

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

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

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

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

Ответы [ 4 ]

67 голосов
/ 27 марта 2010

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

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

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

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

4 голосов
/ 27 марта 2010

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

2 голосов
/ 09 февраля 2016

Я знаю, что эта ветка очень старая, но это был лучший ответ Google, поэтому я хотел добавить свои $ .02.

Хотя мини-дамп наиболее полезен, если вы скомпилировали свой код с включенными символами (просто отправьте файл без .pdb и сохраните .pdb!), Вы можете посмотреть, какая строка использовалась с помощью MSVC Debugger или Windows Debugger. Статья MSN об этом:

http://blogs.msdn.com/b/danielvl/archive/2010/03/03/getting-the-line-number-for-a-faulting-application-error.aspx

1 голос
/ 27 марта 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...