Поделиться через


Проверка символов

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

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

Сначала используйте команду lm (Список загруженных модулей), чтобы отобразить список загруженных модулей с символьными данными. Наиболее полезной формой этой команды является следующая:

0:000> lml 

Если вы используете WinDbg, отладка | Команда меню "Модули " также позволяет просмотреть эти сведения.

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

Если нужные файлы символов не отображаются, сначала необходимо проверка путь к символам:

0:000> .sympath
Current Symbol Path is: d:\MyInstallation\i386\symbols\retail

Если путь к символам неправильный, исправьте его. Если вы используете отладчик ядра, убедитесь, что локальный %WINDIR% не указан в пути к символам.

Затем перезагрузите символы с помощью команды .reload (Reload Module):

0:000> .reload ModuleName 

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

Ниже приведен пример "шумной" перезагрузки символов Microsoft Windows:

kd> !sym noisy
kd> .reload nt
 1: Kernel Version 2081 MP Checked
 2: Kernel base = 0x80400000 PsLoadedModuleList = 0x80506fa0
 3: DBGHELP: FindExecutableImageEx-> Looking for D:\MyInstallation\i386\ntkrnlmp.exe...mismatched timestamp
 4: DBGHELP: No image file available for ntkrnlmp.exe
 5: DBGHELP: FindDebugInfoFileEx-> Looking for
 6: d:\MyInstallation\i386\symbols\retail\symbols\exe\ntkrnlmp.dbg... no file
 7: DBGHELP: FindDebugInfoFileEx-> Looking for
 8: d:\MyInstallation\i386\symbols\retail\symbols\exe\ntkrnlmp.pdb... no file
 9: DBGHELP: FindDebugInfoFileEx-> Looking for d:\MyInstallation\i386\symbols\retail\exe\ntkrnlmp.dbg... OK
10: DBGHELP: LocatePDB-> Looking for d:\MyInstallation\i386\symbols\retail\exe\ntkrnlmp.pdb... OK
11: *** WARNING: symbols checksum and timestamp is wrong 0x0036a4ea 0x00361a83 for ntkrnlmp.exe

Обработчик символов сначала ищет изображение, соответствующее модулю, который он пытается загрузить (строки три и четыре). Само изображение не всегда требуется, но при наличии неправильного обработчика символов часто происходит сбой. Эти строки показывают, что отладчик нашел изображение вD:\MyInstallation\i386\ntkrnlmp.exe, но метка даты времени не совпадает. Так как метка даты и времени не совпадает, поиск продолжается. Затем отладчик ищет DBG-файл и PDB-файл, которые соответствуют загруженного образа. Они находятся в строках с 6 по 10. Строка 11 указывает, что даже если символы были загружены, метка даты и времени для изображения не совпадала (то есть символы были неправильными).

Если поиск символов столкнулся с катастрофическим сбоем, вы увидите сообщение следующего вида:

ImgHlpFindDebugInfo(00000000, module.dll, c:\MyDir;c:\SomeDir, 0823345, 0) failed

Это может быть вызвано такими элементами, как сбои файловой системы, сетевые ошибки и поврежденные DBG-файлы.

Диагностика ошибок загрузки символов

В шумном режиме отладчик может выводить коды ошибок, если ему не удается загрузить файл символов. Коды ошибок для DBG-файлов перечислены в файле winerror.h. Коды ошибок PDB поступают из другого источника, и наиболее распространенные ошибки печатаются в виде обычного текста на английском языке.

Ниже приведены некоторые распространенные коды ошибок для DBG-файлов из winerror.h:

0xB
ERROR_BAD_FORMAT

0x3
ERROR_PATH_NOT_FOUND

0x35
ERROR_BAD_NETPATH

Возможно, файл символов не удается загрузить из-за ошибки сети. Если вы видите ERROR_BAD_FORMAT или ERROR_BAD_NETPATH и загружаете символы с другого компьютера в сети, попробуйте скопировать файл символов на главный компьютер и поместить его путь в путь к символам. Затем попробуйте перезагрузить символы.

Проверка пути поиска и символов

Let "c:\MyDir; c:\SomeDir" представляет путь к символу. Где следует искать отладочную информацию?

В случаях, когда двоичный файл был лишен отладочной информации, например бесплатных сборок Windows, сначала найдите DBG-файл в следующих расположениях:

c:\MyDir\symbols\exe\ntoskrnl.dbg
c:\SomeDir\symbols\exe\ntoskrnl.dbg
c:\MyDir\exe\ntoskrnl.dbg
c:\SomeDir\exe\ntoskrnl.dbg
c:\MyDir\ntoskrnl.dbg
c:\SomeDir\ntoskrnl.dbg
current-working-directory\ntoskrnl.dbg

Затем найдите PDB-файл в следующих расположениях:

c:\MyDir\symbols\exe\ntoskrnl.pdb
c:\MyDir\exe\ntoskrnl.pdb
c:\MyDir\ntoskrnl.pdb
c:\SomeDir\symbols\exe\ntoskrnl.pdb
c:\SomeDir\exe\ntoskrnl.pdb
c:\SomeDir\ntoskrnl.pdb
current-working-directory\ntoskrnl.pdb

Обратите внимание, что при поиске DBG-файла отладчик чередует поиск по каталогам MyDir и SomeDir, а в PDB - нет.

В Windows XP и более поздних версиях Windows не используются dbg-файлы символов. Дополнительные сведения см. в разделе Символы и файлы символов .

Несовпадение сборок

Одной из наиболее распространенных проблем при отладке сбоев на компьютере, который часто обновляется, является несоответствие символов из разных сборок. Три распространенные причины этой проблемы: указание на символы для неправильной сборки, использование закрытого двоичного файла без соответствующих символов, а также использование уровня аппаратной абстракции однопроцессора (HAL) и символов ядра на многопроцессорном компьютере. Первые два являются просто вопросом сопоставления двоичных файлов и символов; третий можно исправить, переименовав hal*.dbg и ntkrnlmp.dbg в hal.dbg и ntoskrnl.dbg.

Чтобы узнать, какая сборка Windows установлена на целевом компьютере, используйте команду vertarget (Показать версию целевого компьютера):

kd> vertarget 
Windows XP Kernel Version 2505 UP Free x86 compatible
Built by: 2505.main.010626-1514
Kernel base = 0x804d0000 PsLoadedModuleList = 0x80548748
Debug session time: Mon Jul 02 14:41:11 2001
System Uptime: 0 days 0:04:53 

Тестирование символов

Проверить символы сложнее. Она включает проверку трассировки стека в отладчике и проверку правильности выходных данных отладки. Вот один из примеров:

kd> u videoprt!videoportfindadapter2
Loading symbols for 0xf2860000     videoprt.sys ->   videoprt.sys

VIDEOPRT!VideoPortFindAdapter2:
f2856f42 55               push    ebp
f2856f43 8bec             mov     ebp,esp
f2856f45 81ecb8010000     sub     esp,0x1b8
f2856f4b 8b4518           mov     eax,[ebp+0x18]
f2856f4e 53               push    ebx
f2856f4f 8365f400         and     dword ptr [ebp-0xc],0x
f2856f53 8065ff00         and     byte ptr [ebp-0x1],0x0
f2856f57 56               push    esi

Команда u разбирает строку videoportfindadapter в videoprt.sys. Символы правильные в отладчике, так как в стеке отображаются распространенные команды стека, такие как push и mov . Большинство функций начинаются с операции добавления, добавления или отправки с помощью базового указателя (ebp) или указателя стека (esp).

Обычно это очевидно, если символы работают неправильно. Glintmp.sys в этом примере не содержит символов, так как рядом с glintmp нет функции:

kd> kb
Loading symbols for 0xf28d0000     videoprt.sys ->   videoprt.sys
Loading symbols for 0xf9cdd000      glintmp.sys ->   glintmp.sys
*** ERROR: Symbols could not be loaded for glintmp.sys
ChildEBP RetAddr  Args to Child
f29bf1b0 8045b5fa 00000001 0000a100 00000030 ntoskrnl!RtlpBreakWithStatusInstruction
f29bf1b0 8044904e 00000001 0000a100 00000030 ntoskrnl!KeUpdateSystemTime+0x13e
f29bf234 f28d1955 f9b7d000 ffafb2dc f9b7d000 ntoskrnl!READ_REGISTER_ULONG+0x6
f29bf248 f9cde411 f9b7d000 f29bf2b0 f9ba0060 VIDEOPRT!VideoPortReadRegisterUlong+0x27
00000002 00000000 00000000 00000000 00000000 glintMP+0x1411 [No function listed.] 

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

1: kd> 
1: kd> kb                      [Local        9:50 AM]
Loading symbols for 0xf22b0000       agpcpq.sys ->   agpcpq.sys
*** WARNING: symbols checksum is wrong 0x0000735a 0x00000000 for agpcpq.sys
*** ERROR: Symbols could not be loaded for agpcpq.sys
Loading symbols for 0xa0000000       win32k.sys ->   win32k.sys
*** WARNING: symbols checksum is wrong 0x00191a41 0x001995a9 for win32k.sys
ChildEBP RetAddr  Args to Child
be682b18 f22b372b 82707128 f21c1ffc 826a70f8 agpCPQ+0x125b [No function listed.]
be682b4c a0140dd4 826a72f0 e11410a8 a0139605 agpCPQ+0x372b [No function listed.]
be682b80 a00f5646 e1145100 e1cee560 e1cee560 win32k!vPatCpyRect1_6x6+0x20b
00000001 00000000 00000000 00000000 00000000 win32k!RemoteRedrawRectangle+0x32 

Вот правильная трассировка стека. Проблема действительно в AGP440.sys. Первый элемент, появляющийся в трассировке стека, как правило, неисправен. Обратите внимание, что ошибка прямоугольника win32k.sys исчезла:

1: kd> kb                      [Local        9:49 AM]
ChildEBP RetAddr  Args to Child
be682b18 f22b372b 82707128 f21c1ffc 826a70f8 agpCPQ!AgpReleaseMemory+0x88
be682b30 f20a385c 82703638 e183ec68 00000000 agpCPQ!AgpInterfaceReleaseMemory+0x8b
be682b4c a0140dd4 826a72f0 e11410a8 a0139605 VIDEOPRT!AgpReleasePhysical+0x44
be682b58 a0139605 e1cee560 e11410a8 a00e5f0a win32k!OsAGPFree+0x14
be682b64 a00e5f0a e1cee560 e11410a8 e1cee560 win32k!AGPFree+0xd
be682b80 a00f5646 e1145100 e1cee560 e1cee560 win32k!HeapVidMemFini+0x49
be682b9c a00f5c20 e1cee008 e1cee008 be682c0c win32k!vDdDisableDriver+0x3a
be682bac a00da510 e1cee008 00000000 be682c0c win32k!vDdDisableDirectDraw+0x2d
be682bc4 a00da787 00000000 e1843df8 e1843de8 win32k!PDEVOBJ__vDisableSurface+0x27
be682bec a00d59fb 00000000 e1843de8 00000000 win32k!PDEVOBJ__vUnreferencePdev+0x204
be682c04 a00d7421 e1cee008 82566a98 00000001 win32k!DrvDestroyMDEV+0x30
be682ce0 a00a9e7f e1843e10 e184a008 00000000 win32k!DrvChangeDisplaySettings+0x8b3
be682d20 a008b543 00000000 00000000 00000000 win32k!xxxUserChangeDisplaySettings+0x106
be682d48 8045d119 00000000 00000000 00000000 win32k!NtUserChangeDisplaySettings+0x48
be682d48 77e63660 00000000 00000000 00000000 ntkrnlmp!KiSystemService+0xc9 

Полезные команды и расширения

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

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

!dh image-header-base
Отображает сведения о заголовке загруженного изображения, начиная с image-header-base.

.reload /n
Перезагружает все символы ядра.

.reload [image-name]
(только CDB или WinDbg) Перезагружает символы для image-name. Если имя изображения не указано, перезагружает символы для всех изображений. (После изменения пути к символам необходимо перезагрузить символы.)

!sym шумно
Включает подробный режим для загрузки символов. Это можно использовать для получения сведений о нагрузках модуля. Дополнительные сведения см . в разделе Настройка параметров символов .

.sympath [new-symbol-path]
Задает новый путь к символам или отображает текущий путь к символам. Дополнительные сведения см. в разделе Путь к символам .

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

X*!
Появится список модулей, в которых сейчас загружены символы. Это полезно, если символы ядра верны.

.reload /user
Будет предпринята попытка перезагрузить все символы пользовательского режима. Это необходимо при выполнении отладки ядра, если символы были загружены во время выполнения одного процесса, а позже произошел перерыв в другом процессе. В этом случае символы пользовательского режима из нового процесса не будут загружены, если не будет выполнена эта команда.

X wdmaud!*start\*
При этом будут перечислены только символы в модуле wdmaud , имена которых содержат начальную строку. Это имеет преимущество в том, что он принудительно перезагружает все символы в wdmaud, но отображает только те, с "start" в них. (Это означает более короткий список, но так как всегда есть некоторые символы с "start" в них, будет проверяться, была ли загрузка.)

Еще один полезный метод проверки символов — разборка кода. Большинство функций начинаются с операции добавления, добавления или отправки с помощью базового указателя (ebp) или указателя стека (esp или sp). Попробуйте выполнить разобрание (функция U) некоторых функций в стеке (от нуля смещения), чтобы проверить символы.

Проблемы с сетью и портами

При подключении к отладчику будут возникать проблемы с файлами символов. При возникновении проблем следует помнить о нескольких вещах.

  • Определите, к какому COM-порту подключен отладочный кабель в тестовой системе.

  • Проверьте параметры boot.ini тестовой системы. Найдите параметр /debug и проверка скорость передачи данных и параметры COM-порта.

  • Проблемы с сетью могут помешать отладке, если доступ к файлам символов осуществляется через сеть.

  • .dll и .sys файлы с одинаковыми именами (например, mga64.sys и mga64.dll) спутают отладчик, если они не разделены на соответствующие каталоги дерева символов.

  • Отладчик ядра не всегда любит заменять файлы символов сборки частными файлами символов. Дважды проверка путь к символу и выполнить reloadFileName для неправильного символа. Иногда полезно использовать команду !dlls .

Вопросы и заблуждения

Q: Я успешно загрузил символы, но стек кажется неправильным. Не работает ли отладчик?

A: Не обязательно. Наиболее вероятная причина проблемы заключается в том, что у вас есть неправильные символы. Выполните действия, описанные в этом разделе, чтобы определить, загружены ли допустимые символы. Не предполагайте, что, поскольку некоторые вещи работают, у вас есть допустимые символы. Например, вы можете выполнить dd nt!ntbuildnumber или u nt! KeInitializeProcess с неправильными символами. Убедитесь, что они верны, используя описанные выше процедуры.

Q: Будет ли отладчик по-прежнему работать с неправильными символами?

A: Да и нет. Часто вы можете обойтись символами, которые не соответствуют строго. Например, символы из предыдущей сборки Windows часто работают в определенных случаях, но нет правила, когда это будет работать, а когда нет.

Q: Я остановлен в отладчике ядра и хочу просмотреть символы для процесса в пользовательском режиме. Могу ли я это сделать?

A: Основном. Поддержка этого сценария неудовлетворительна, так как отладчик ядра не хранит достаточно информации для отслеживания загрузки модулей для каждого процесса, но есть разумный обходной путь. Чтобы загрузить символы для модуля пользовательского режима, выполните команду .reload -user . При этом будут загружены модули пользовательского режима для текущего контекста.

Q: Что означает следующее сообщение?

*** WARNING: symbols checksum and timestamp is wrong 0x0036d6bf 0x0036ab55 for ntkrnlmp.exe

A: Это означает, что ваши символы для ntkrnlmp.exe неверны.