Подтвердить что ты не робот

Анализ сбоя в Windows: что сообщение об ошибке сообщает нам?

Небольшая утилита, которую я сделал для личного использования (написанная на С++), вчера разбилась случайным образом (я использовал ее примерно через 100 часов без каких-либо проблем), и, хотя я обычно этого не делаю, я был чувствовал себя немного предприимчивым и хотел попробовать и узнать больше о проблеме. Я решил пойти в Средство просмотра событий и посмотреть, что 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 - нарушение доступа к памяти (пытался получить доступ к памяти, которой он не принадлежал). Мне особенно интересно узнать больше о следующем:

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

Существует не так много, что вы сможете сделать посмертно с этой информацией.

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

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

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

Ответ 3

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

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

Ответ 4

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