Использование WinDBG для определения дефектной функции

Я установил WinDBG из 7.1 Windows SDK. Затем с VС++ 2008 я создал программу "CleanPayload.exe", которая содержит только "главный" и вызов функции, которая преднамеренно содержит дефект. Это сборка релиза, которая включает в себя символы отладки. Я открыл эту программу в WindDBG, а затем

  • сделал .sympath+, чтобы указать, где был PDB для этой программы.
  • сделал ld * для загрузки всех символов
  • сделал a lm, чтобы проверить, что все символы были загружены (частные символы для моей программы, общедоступные символы для библиотек Windows).

Затем я запустил программу и выбрал исключение из первого шанса, которое ожидалось. Как показано ниже:

(910.12a0): WOW64 breakpoint - code 4000001f (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll32!LdrpDoDebuggerBreak+0x2c:
771e0f2b cc              int     3 

Но когда я прошу WinDBG показать мне стек, это не показывает мне ничего о моей программе "CleanPayload.exe". Вместо этого он показывает мне следующее:

0:000:x86> kb
ChildEBP RetAddr  Args to Child              
004bf5ec 771c122b 7efdd000 7efde000 7724206c ntdll32!LdrpDoDebuggerBreak+0x2c
004bf764 77192187 004bf7d8 77140000 7c185e6a ntdll32!LdrpInitializeProcess+0x132f
004bf7b4 77179e89 004bf7d8 77140000 00000000 ntdll32!_LdrpInitialize+0x78
004bf7c4 00000000 004bf7d8 77140000 00000000 ntdll32!LdrInitializeThunk+0x10

Что мне нужно сделать, чтобы он показывал мне трассировку стека, которая (1) включает мою программу, и (2) функцию, в которой было выбрано исключение?

Обновление. Я последовал за предложением Ларри, пропустив первое исключение и получив следующие результаты:

0:000:x86> g
ntdll!NtTerminateProcess+0xa:
00000000`76faf97a c3              ret
0:000> kb
RetAddr           : Args to Child                                                           : Call Site
00000000`74c6601a : 00000000`00000000 00000000`000de600 00000000`000ddc80 00000000`74c60304 : ntdll!NtTerminateProcess+0xa
00000000`74c5cf87 : 00000000`0030f988 00000000`0030dba8 00000000`7efdb000 00000000`0030f934 : wow64!whNtTerminateProcess+0x46
00000000`74be276d : 00000000`77150190 00000000`74c50023 00000000`00000000 00000000`0030fab8 : wow64!Wow64SystemServiceEx+0xd7
00000000`74c5d07e : 00000000`00000000 00000000`74be1920 00000000`000de820 00000000`76f93501 : wow64cpu!TurboDispatchJumpAddressEnd+0x24
00000000`74c5c549 : 00000000`00000000 00000000`00000000 00000000`74c54ac8 00000000`7ffe0030 : wow64!RunCpuSimulation+0xa
00000000`76faae27 : 00000000`004a3100 00000000`00000000 00000000`7707a1e0 00000000`7efdf000 : wow64!Wow64LdrpInitialize+0x429
00000000`76fa72f8 : 00000000`00000000 00000000`76fa8641 00000000`76fb84e0 00000000`00000000 : ntdll!LdrpInitializeProcess+0x1780
00000000`76f92ace : 00000000`000df1b0 00000000`00000000 00000000`7efdf000 00000000`00000000 : ntdll! ?? ::FNODOBFM::`string'+0x2af20
00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!LdrInitializeThunk+0xe

Таким образом, к сожалению, я до сих пор не вижу соответствующей информации о трассировке стека. Я также попробовал команду .effmach x86, прежде чем шаги, описанные выше, и это, похоже, не повлияло. Кстати, я также повторил весь тест с верификатором приложения, активированным для целевой программы, которую я тестирую. У меня очень противоречивые результаты:

0:000> g
ModLoad: 00000000`76d40000 00000000`76e5f000   WOW64_IMAGE_SECTION
ModLoad: 00000000`74f90000 00000000`75090000   WOW64_IMAGE_SECTION
ModLoad: 00000000`76d40000 00000000`76e5f000   NOT_AN_IMAGE
ModLoad: 00000000`76e60000 00000000`76f5a000   NOT_AN_IMAGE
ModLoad: 00000000`71160000 00000000`711c0000   C:\Windows\syswow64\verifier.dll
Page heap: pid 0x1A54: page heap enabled with flags 0x3.
AVRF: CleanPayload.exe: pid 0x1A54: flags 0x80643027: application verifier enabled
ModLoad: 00000000`71130000 00000000`7115b000   C:\Windows\SysWOW64\vrfcore.dll
ModLoad: 00000000`710d0000 00000000`71128000   C:\Windows\SysWOW64\vfbasics.dll
ModLoad: 00000000`74f90000 00000000`75090000   C:\Windows\syswow64\kernel32.dll
ModLoad: 00000000`76830000 00000000`76876000   C:\Windows\syswow64\KERNELBASE.dll
ModLoad: 00000000`715c0000 00000000`7164e000   C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4926_none_508ed732bcbc0e5a\MSVCP90.dll
ModLoad: 00000000`73dc0000 00000000`73e63000   C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4926_none_508ed732bcbc0e5a\MSVCR90.dll
(1a54.17dc): WOW64 breakpoint - code 4000001f (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll32!LdrpDoDebuggerBreak+0x2c:
771e0f2b cc              int     3

0:000:x86> !avrf
*************************************************************************
***                                                                   ***
***                                                                   ***
***    Your debugger is not using the correct symbols                 ***
***                                                                   ***
***    In order for this command to work properly, your symbol path   ***
***    must point to .pdb files that have full type information.      ***
***                                                                   ***
***    Certain .pdb files (such as the public OS symbols) do not      ***
***    contain the required information.  Contact the group that      ***
***    provided you with these symbols if you need this command to    ***
***    work.                                                          ***
***                                                                   ***
***    Type referenced: wow64!_TEB32                                  ***
***                                                                   ***
*************************************************************************
Application verifier is not enabled for this process.
Use appverif.exe tool to enable it.

В приведенном выше исполнении указано AVRF: Cleanpayload.exe ... application verifier enabled, что указывает на то, что он заблокирован для цели. Но затем последующая команда !avrf показывает, что символы отладки плохие, хотя команда lm показывает, что все они правильно загружены! Что здесь происходит здесь?

Ответ 1

Вы используете 64-битную версию windbg и 32-битное приложение. Начальная точка останова работает в 64-битном коде.

Если вы нажмете "g", вы должны нажать начальную точку останова для 32-битного приложения, вы должны уйти оттуда.

Чтобы переключиться с 64-разрядной отладки на 32-разрядную отладку (если вы нажали CTRL-C, например), введите:

.effmach x86

который переключит отладчик с 64-битного режима на 32-битный.

Ответ 2

Вы пытаетесь выяснить, как отлаживать реальные проблемы после того, как ваше программное обеспечение упаковано и отправлено в QA или клиенты? Если да, то есть другой инструмент, который вы могли бы использовать, adplus. Adplus запускает отладчик под капотом и имеет только одну цель (фактически две, если вы запускаете режим зависания, но это не то, что вы хотите здесь), что должно ждать исключений. Когда произойдет исключение, он будет генерировать файл дампа памяти процесса, который можно загрузить в WinDbg.

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

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