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


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

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

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

Во-первых, используйте команду 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
ОШИБКА_НЕПРАВИЛЬНЫЙ_ФОРМАТ

0x3
ОШИБКА_ПУТЬ_НЕ_НАЙДЕН

0x35
ОШИБКА_НЕИСПРАВЕН_СЕТЕВОЙ_ПУТЬ

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

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

Пусть "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 noisy
Включает подробный режим для загрузки символов. Это можно использовать для получения сведений о загрузке модуля. Дополнительные сведения см. в разделе "Параметры символов ".

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

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

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

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

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

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

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

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

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

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

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

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

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

Вопросы и неправильные представления

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

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

Вопрос. Будет ли отладчик работать с неправильными символами?

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

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

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

Вопрос. Что означает следующее сообщение?

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

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