Вопрос

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

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

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

(Советы типа «проверьте приложение, чтобы оно не зависало» бесполезны!- во всех нетривиальных программах будут ошибки)

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

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

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

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

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

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

Видеть http://www.ddj.com/architect/185300443

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

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

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

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

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

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

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

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

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

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

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

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

Это приводит к полному сбою или зависанию дампа.Когда у вас есть дамп, на помощь придет Windbg.Сопоставьте правильные PDB и символы, и все готово для анализа дампа.Для начала используйте команду «!analyze -v»

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top