Как получить трассировку стека при сбое программы C ++? (с использованием msvc8 / 2005) - PullRequest
6 голосов
/ 22 сентября 2008

Иногда моя программа на С ++ аварийно завершает работу в режиме отладки, и я получаю сообщение о том, что в некоторых подпрограммах управления внутренней памятью (доступ к нераспределенной памяти и т. Д.) Не выполнено утверждение. Но я не знаю, откуда это было вызвано, потому что я не получил никакой трассировки стека. Как получить трассировку стека или, по крайней мере, увидеть, где происходит сбой в моем коде (вместо библиотечных / встроенных процедур)?

Ответы [ 8 ]

7 голосов
/ 22 сентября 2008

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

Для этого вам нужно использовать файл PDB, созданный вместе с вашим EXE-файлом. Поместите файл PDB в тот же каталог, что и EXE-файл, который вылетел. Примечание. Даже если у вас один и тот же исходный код, сборка дважды и использование первого EXE-файла и второго PDB не будут работать. Вам нужно использовать именно ту PDB, которая была создана с вашим EXE-файлом.

Затем присоедините отладчик к сбою процесса. Пример: windbg или VS.

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

Если вы уже подключили отладчик VS, он автоматически перейдет к исходному коду, вызвавшему сбой.

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

3 голосов
/ 22 сентября 2008

Если вы запускаете отладочную версию на машине с VS, она должна предложить запустить ее и увидеть трассировку стека.

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

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

http://www.atalasoft.com/cs/blogs/loufranco/archive/2007/02/06/6-_2200_Pointers_2200_-on-Debugging-Unmanaged-Code.aspx

Лучший совет - использовать утилиту gflags, чтобы проблемы с указателями вызывали немедленные проблемы.

2 голосов
/ 22 сентября 2008

В этой статье описывается, как вычислить трассировку стека.

2 голосов
/ 22 сентября 2008

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

Google фактически реализовал свой собственный обработчик аварий с открытым исходным кодом под названием BreakPad , который, как мне кажется, использует mozilla (если вы хотите что-то более серьезное - богатый и надежный обработчик аварийных ситуаций).

0 голосов
/ 23 октября 2014

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

0 голосов
/ 22 сентября 2008

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

Dr. Watson на Windows можно установить, запустив: drwtsn32 -i Запуск drwtsn32 (без каких-либо опций) вызовет диалоговое окно конфигурации. Это позволит создавать файлы аварийных дампов, которые впоследствии можно будет проанализировать с помощью WinDbg или чего-либо подобного.

0 голосов
/ 22 сентября 2008

CrashFinder может помочь вам найти место исключения, учитывая DLL и адрес сообщенного исключения.
Вы можете взять этот код и интегрировать его в свое приложение, чтобы автоматически генерировать трафик стека при возникновении необработанного исключения. Обычно это выполняется с использованием __try{} __except{} или с вызовом SetUnhandledExceptionFilter , который позволяет указать обратный вызов для всех необработанных исключений.

0 голосов
/ 22 сентября 2008

Если я правильно помню, в этом окне сообщения должна быть кнопка «Повторить попытку». Это должно затем сломать программу (в отладчике) в точке, где произошло утверждение.

...