Анализ сбоя в Windows: что говорит нам сообщение об ошибке? - PullRequest
25 голосов
/ 23 августа 2009

Небольшая моя утилита, которую я создал для личного использования (написана на C ++), вчера случайно вышла из строя (я использовал ее более 100 часов без проблем), и хотя я обычно не делаю этого, я был чувствовал себя немного предприимчивым и хотел попытаться узнать больше о проблеме. Я решил зайти в Event Viewer и посмотреть, что Windows записала о сбое:

Faulting application StraightToM.exe, version 0.0.0.0, time stamp 0x4a873d19 
Faulting module name : StraightToM.exe, version 0.0.0.0, time stamp 0x4a873d19
Exception code : 0xc0000005
Fault offset : 0x0002d160,
Faulting process id: 0x17b4
Faulting application start time: time 0x01ca238d9e6b48b9.

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

  1. Что означает смещение ошибки? Означает ли это расположение в файле, где произошла ошибка, или это означает сборочную «линию», где произошла ошибка? Зная смещение ошибки, как бы я использовал такую ​​программу, как OllyDbg, чтобы найти соответствующий код сборки, вызвавший ошибку? Или, что еще лучше, можно (легко) определить, какая строка кода в источнике C ++ вызвала эту ошибку?
  2. Очевидно, что отметка времени соответствует 32-битному времени UNIX во время сбоя, но что означает время запуска 64-битного приложения? Почему это было бы 64-битным, если отметка времени 32?

Обратите внимание, что я в основном программист на C ++, поэтому, хотя я кое-что знаю о сборке, мои знания об этом очень ограничены. Кроме того, это действительно не серьезная проблема, требующая решения (и также не легко воспроизводимая, учитывая характер программы), я просто использую это как предлог, чтобы узнать больше о том, что означают эти сообщения об ошибках. Большая часть информации об этих журналах сбоев, которую я нашел в Интернете, обычно предназначена для конечного пользователя, поэтому они не очень помогли мне (как программисту).

Заранее спасибо

Ответы [ 4 ]

17 голосов
/ 23 августа 2009

64-битная метка времени - это основной поток приложения времени, созданный с интервалом 100 наносекунд с 1 января 1601 года (UTC) (он известен как FILETIME). 32-битная временная метка действительно имеет формат time_t (она сообщает время создания модуля и хранится в заголовке модуля).

Я бы сказал, что 0x0002d160 - это смещение от адреса загрузки модуля (он кажется слишком низким для абсолютного адреса). Запустите Visual Studio, запустите отладчик, взгляните на окно отладки «модулей». Ваш exe-файл должен быть указан там. Найдите адрес, куда загружен модуль, добавьте 0x0002d160 к этому адресу и посмотрите на разборку полученного адреса. Visual Studio показывает исходный код, смешанный со сборкой, у вас не должно возникнуть проблем с выяснением того, какая исходная строка вызвала проблему.

7 голосов
/ 23 августа 2009

Мало что вы сможете сделать посмертно с этой информацией.

Полезный бит информации - это код исключения, 0xc0000005, который в данном случае означает нарушение прав доступа. Таким образом, вы разыменовали null или какой-то другой фрагмент памяти, который вам не принадлежал.

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

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

6 голосов
/ 23 августа 2009

Бог отладки Джон Роббинс создал небольшой инструмент под названием CrashFinder, чтобы помочь в таких ситуациях: https://www.wintellect.com/crashfinder-2-8-yes-native-code-still-lives/

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

1 голос
/ 05 мая 2014

похоже, что здесь все еще нет хорошего ответа, что если сбой произойдет вне среды разработки. Я думаю, что off set - это адрес, где происходит сбой кода сборки. Но вам нужно знать, где находится начало ассемблерного кода этой библиотеки DLL. или, может быть, вам не нужно знать начальный адрес, потому что вы можете использовать инструмент сборки, чтобы открыть dll, и найти код сборки, добавив смещение к начальному адресу

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