Отладка приложений для Microsoft .NET и Microsoft Windows [Джон Роббинс] (pdf) читать постранично, страница - 236

-  Отладка приложений для Microsoft .NET и Microsoft Windows  3.21 Мб, 731с. скачать: (pdf) - (pdf+fbd)  читать: (полностью) - (постранично) - Джон Роббинс

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]

Hexadecimal
Address(es) (шестнадцатеричные адреса) и нажмите кнопку Find (найти).
Поток из нашего фрагмента оказался потоком, вызвавшим ошибку. Об этом
свидетельствует только указатель FAULT> (СБОЙ>) в середине дизассемблиро
ванного листинга. Пару раз я видел журналы Dr. Watson, в которых не было ука
зателя FAULT>. Если вы не можете найти в журнале этот указатель, изучите со

ПРИЛОЖЕНИE A

Чтение журналов Dr. Watson

691

стояние каждого потока и введите каждый адрес EIP в CrashFinder, чтобы узнать,
какую команду выполнял поток в момент ошибки.
Если вы читали главу 7, дизассемблированный листинг должен быть вам по
нятен. Новыми элементами будут только значения, показанные после команд. Чтобы
вы могли узнать, какие значения использовались командой, дизассемблер Dr. Watson
пытается просмотреть эффективный адрес ссылки на память. Адреса, начинаю
щиеся с букв ss, свидетельствуют о том, что происходил доступ к сегменту стека;
ds — к сегменту данных. В Windows XP/Server 2003 эффективный адрес будет указан
только после строки, на которую указывал регистр EIP в момент ошибки.
В журналах Dr. Watson из Windows 2000 эффективные адреса будут указаны
после каждой ассемблерной команды. Однако при этом гарантируется правиль
ность только того адреса, что указан в строке, на которой находился указатель
команд. Другие адреса могут быть неверны, так как значения, используемые коман
дой, могли измениться. Допустим, первая дизассемблированная команда в состо
янии потока ссылалась на память при помощи регистра EBX. Если ошибка случи
лась после выполнения еще 10 команд, то одна из промежуточных команд легко
могла изменить EBX. Однако, когда Dr. Watson в Windows 2000 дизассемблирует
программу, для преобразования эффективного адреса он использует текущее зна
чение EBX — то, которое имело место в момент ошибки. Поэтому эффективный
адрес, показанный в дизассемблированном коде, может быть неверным. Итак,
прежде чем поверить в значения эффективных адресов, убедитесь, что нужные
регистры не были изменены никакой командой.
Благодаря недавно приобретенным навыкам работы с ассемблером, вы долж
ны легко узнать, почему этот поток потерпел крах. Читая ассемблерный листинг
Dr. Watson (или отладчика), большинство программистов допускает серьезную
ошибку: они изучают его сверху вниз. Настоящая хитрость в том, чтобы начать
исследование с места ошибки и постепенно подниматься вверх в поисках коман
ды, присвоившей значения регистрам, использованным в команде, вызвавшей
ошибку.
В нашем случае поток потерпел крах на команде 00410144 MOV ECX, [EAX+0x4], при
которой регистр EAX имел значение 0. В Microsoft Windows все адреса, располо
женные ниже 64 кб, отмечены как не имеющие доступа, поэтому попытка чтения
памяти по адресу 0x00000004 — не лучшая идея. Итак, мы должны найти коман
ду, заносящую 0 в EAX. Поднявшись на одну строку, вы увидите команду MOV EAX,
[EBP+0xC]. Помните, что второй операнд, источник, помещается в первый операнд,
приемник (иначе говоря, помните про правило «от источника к приемнику»). Это
значит, что в EAX было скопировано значение, находившееся по адресу [EBP+0xC].
Следовательно, по адресу [EBP+0xC] располагался 0.
В этот момент вы должны вспомнить еще одну хитрость, которую я описал в
главе 7: «параметры располагаются по положительным смещениям»! Параметры
располагаются по положительным смещениям от регистра EBP, причем первый
находится по адресу [EBP+0x8], а каждый следующий отстоит от предыдущего на
4 байта. Так как 0xC на 4 байта больше, чем 0x8, я могу предположить, что ошиб
ка была вызвана тем, что второй параметр этой функции был равен NULL (наде
юсь, прочитав эти два абзаца, вы поняли, как важно знать ассемблер в достаточ
ном объеме для чтения журналов Dr. Watson!).

692

ЧАСТЬ V

Приложения

Ниже вы можете увидеть вторую часть состояния потока: раздел Stack Back Trace
(обратная трассировка стека) Заметьте: я вывожу имена функций на двух строках,
чтобы они помещались на странице. При помощи двух символов подчеркивания
(__) Dr. Watson отображает операцию разрешения области видимости (::).

*——> Stack Back Trace (Обратная трассировка стека) Обратная трассировка стека Копия необработанного стека