Отладка мини-дампа в Visual Studio, где стек вызовов равен нулю - PullRequest
7 голосов
/ 02 марта 2010

У меня есть клиент, который получает 100% воспроизводимый сбой, который я не могу воспроизвести в моей программе, скомпилированной в Visual Studio 2005. Я отправил им отладочную сборку моей программы и сохранил все файлы PDB и DLL под рукой. Мне прислали файл минидампа, но когда я его открываю, я получаю:

"Необработанное исключение в 0x00000000 в MiniDump.dmp: 0xC0000005: расположение чтения нарушения доступа 0x00000000."

Тогда в стеке вызовов отображается только «0x00000000 ()», а при разборке - дамп памяти в 0x0. Я установил сервер символов, загрузил свои символы PDB и т. Д. Но я не вижу способа узнать, какая из многих библиотек DLL фактически привела к переходу на ноль. Это большой проект с множеством зависимостей, и некоторые из них являются двоичными файлами, для которых у меня нет источника или PDB, поскольку я использую API в качестве стороннего производителя.

Так как же полезен этот минидамп? Как узнать, какая DLL вызвала сбой? Я никогда раньше не использовал мини-дампы для отладки, но все прочитанные мной уроки, по-видимому, по крайней мере отображают имя функции или что-то еще, что дает подсказку в стеке вызовов. Я просто получаю одну строку, указывающую на ноль.

Я также пытался использовать «Зависит», чтобы увидеть, была ли какая-то зависимость от DLL, которая не была разрешена; однако на моих трех тестовых машинах с различными ОС Windows, я, кажется, получаю три разных набора зависимостей ОС DLL (и все же не могу воспроизвести сбой); так что это не кажется особенно надежным методом для диагностики проблемы.

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

Ответы [ 6 ]

5 голосов
/ 03 марта 2010

Что ж, похоже, ответ в этом случае был «Использовать WinDbg вместо Visual Studio для отладки мини-дампов». Я не смог получить никакой полезной информации от VS, но WinDbg дал мне много информации о цепочке вызовов функций, которые привели к сбою.

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

Полагаю, если кто-то еще видит подобную проблему с бесполезным стеком вызовов при отладке мини-дампа, лучше всего открыть его с помощью WinDgb, а не Visual Studio. Кажется странным, что лучшим инструментом для работы является бесплатный продукт Microsoft, а не коммерческий.

Другим уроком здесь, вероятно, является «любая программа, использующая стороннюю библиотеку, должна написать файл журнала».

2 голосов
/ 02 марта 2010

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

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

Я написал об этом статью из двух частей на ddj.com:

.

О файлах журналов, часть 1

О файлах журналов, часть 2

0 голосов
/ 21 июня 2016

Возможно, вы вызвали нулевой указатель на функцию. Информация о текущей выполняемой функции необходима для отображения информации стека вызовов. Принудительно установите указатель инструкции на запуск любой простой функции, и вы снова увидите информацию о стеке вызовов.

void SimpleFunc()
{  // <- set next statement here
} 
0 голосов
/ 02 марта 2010

Возможно, вы уже знаете это, но вот некоторые моменты, касающиеся отладки мини-дампов: 1. Вам нужно иметь точно такие же исполняемые файлы и файлы PDB, как и на клиентском компьютере, на котором был создан мини-дамп, и они должны находиться точно в тех же каталогах. Просто пересоздание той же версии не поможет. 2. Отладчик должен быть подключен к серверу MS Symbols. 3. Когда запускается отладчик, он печатает журнал загрузки процесса в окне вывода. Как правило, все библиотеки должны быть успешно загружены с отладочной информацией. Библиотеки без отладочной информации также загружаются, но «без отладочной информации» печатается. Изучите этот журнал - он может дать вам некоторую информацию.

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

Попробуйте создать мини-дамп на своем компьютере, добавив код, который создает необработанное исключение, и немедленно отладьте его. Это работает? Сравните журнал загрузки в успешных и неудачных сеансах отладки.

0 голосов
/ 02 марта 2010

Вы пытались установить WinDbg на компьютере клиента и использовать его в качестве отладчика по умолчанию для любого приложения, вызывающего сбой? Вам просто нужно добавить файлы pdb в папку, где находится ваше приложение. Когда происходит сбой, запускается WinDbg, и вы можете попытаться получить стек вызовов.

0 голосов
/ 02 марта 2010

Просто наблюдение, но стек усекается или перезаписывается, это может быть простой случай использования неинициализированного поля или переполнение буфера?

Это может быть довольно легко найти.

...