Как извлечь отладочную информацию из аварии - PullRequest
11 голосов
/ 12 мая 2009

Если мое приложение C ++ дает сбой в Windows, я хочу отправить полезную информацию об отладке на наш сервер.

В Linux я бы использовал функцию GNU backtrace() - есть ли эквивалент для Windows?

Есть ли способ извлечь полезную отладочную информацию после сбоя программы? Или только изнутри процесса?

(Советы по принципу «протестируйте свое приложение, чтобы оно не зависало» не помогают!

Ответы [ 9 ]

7 голосов
/ 12 мая 2009

Функция Stackwalk64 может использоваться для привязки трассировки стека в Windows.

Если вы намереваетесь использовать эту функцию, вы должны обязательно скомпилировать свой код с отключенной FPO - без символов StackWalk64 не сможет правильно просматривать кадры FPO.

Вы можете получить некоторый код, выполняющийся в процессе во время сбоя через блок верхнего уровня __try/__except, вызвав SetUnhandledExceptionFilter. Это немного ненадежно, поскольку требует, чтобы код выполнялся внутри аварийного процесса. Кроме того, вы можете просто встроить отчеты об ошибках Windows для сбора данных о сбоях. Это более надежно, поскольку не требует добавления кода, работающего внутри скомпрометированного, аварийного процесса. Единственной ценой является получение сертификата для подписи кода, поскольку вы должны отправить подписанный двоичный файл в службу. https://sysdev.microsoft.com/en-US/Hardware/signup/ имеет больше деталей.

3 голосов
/ 12 мая 2009

Вы можете использовать вызов Windows API MiniDumpWriteDump , если хотите свернуть свой собственный код. И Windows XP, и Vist автоматизируют этот процесс, и вы можете зарегистрироваться на https://winqual.microsoft.com, чтобы получить доступ к отчетам об ошибках.

Также проверьте http://kb.mozillazine.org/Breakpad и http://www.codeproject.com/KB/debug/crash_report.aspx для других решений.

2 голосов
/ 13 мая 2009

Позвольте мне описать, как я обрабатываю сбои в моем приложении C ++ / WTL.

Во-первых, в основной функции я вызываю _set_se_translator и передаю функцию, которая вызывает исключение C ++ вместо использования исключений структурированных окон. Эта функция получает код ошибки, для которого вы можете получить сообщение об ошибке Windows через FormatMessage и аргумент PEXCEPTION_POINTERS, который вы можете использовать для записи минидампа ( код здесь ). Вы также можете проверить код исключения для определенных ошибок «расплавления», от которых вы должны просто избавиться, например, EXCEPTION_NONCONTINUABLE_EXCEPTION или EXCEPTION_STACK_OVERFLOW :) (Если это исправимо, я предлагаю пользователю отправить мне этот мини-дамп по электронной почте.)

Сам файл minidump может быть открыт в Visual Studio, как обычный проект, и, если вы создали файл .pdb для вашего исполняемого файла, вы можете запустить проект, и он перейдет к точному месту сбоя, вместе со стеком вызовов и регистрами, которые можно просмотреть в отладчике.

2 голосов
/ 12 мая 2009

Довольно просто сбросить адреса текущего стекового фрейма в файл журнала. Все, что вам нужно сделать, это получить такую ​​функцию, которая вызывается при сбоях программы (то есть обработчике прерываний в Windows) или утверждает. Это можно сделать и в выпущенных версиях. После этого файл журнала можно сопоставить с файлом карты, что приведет к стеку вызовов с именами функций.

Я опубликовал статью об этом несколько лет назад.

См. http://www.ddj.com/architect/185300443

2 голосов
/ 12 мая 2009

Создать файл минидампа. Затем вы можете загрузить его в windbg или Visual Studio и проверить весь стек, где произошел сбой.

Вот хорошее место для начала чтения.

2 голосов
/ 12 мая 2009

Этот веб-сайт предоставляет довольно подробный обзор поиска стека на Win32 после исключения C ++:

http://www.eptacom.net/pubblicazioni/pub_eng/except.html

Конечно, это будет работать только изнутри процесса, поэтому, если процесс завершается или падает до точки, в которой он завершается до запуска этого кода, он не будет работать.

1 голос
/ 13 мая 2009

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

Затем вы можете загрузить файл дампа на сервер для дальнейшего анализа, используя анализаторы дампа, такие как windbg.

1 голос
/ 12 мая 2009

Если вы хотите захватить стек вызовов (плюс другую полезную информацию) для сбоя во время выполнения, при сборке релиза даже на сайте, то вам нужно настроить Dr Watson (запустить DrWtsn32.exe). Если вы выберете опцию «генерировать дампы при сбое», при сбое приложения оно запишет файл мини-дамп по указанному пути (так называемый user.dmp).

Вы можете взять это, объединить его с символами, которые вы создали при сборке вашего сервера (установите это в компиляторе / компоновщике для генерации файлов pdb - храните их дома, используйте их для соответствия дампу, чтобы они могли работать источник, где произошел сбой)

Получите себя windbg , откройте его и используйте опцию меню для загрузки аварийного дампа. Когда все загружено, вы можете набрать '~ # kp', чтобы получить стек вызовов для каждого потока (или нажать кнопку вверху для текущего потока).

Есть хорошие статьи, чтобы узнать, как это сделать, по всему Интернету, Этот мой любимый, и вы захотите прочитать это , чтобы получить представление о том, как Помочь себе управлять символами очень легко.

0 голосов
/ 27 мая 2010

Возможно, вы захотите использовать adplus для захвата стека вызовов.

Вы можете загрузить и установить средства отладки для Windows.

Использование adplus упоминается здесь: Использование Adplus

Это создает полный сбой или зависание дампа. Как только у вас есть свалка, Windbg приходит на помощь. Сопоставьте правильные pdbs и символы, и все готово для анализа дампа. Для начала используйте команду "! Analyse -v"

...