Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
В этом руководстве показано, как использовать WinDbg для отладки приложений в пользовательском режиме. Вы практикуете основные навыки отладки, присоединение к запущенным процессам, настройке точек останова и диагностике сбоев приложений.
В этой статье:
- Присоединение WinDbg к Блокноту и изучение базовой отладки
- Отладка собственного приложения и анализ сбоя
- Овладейте основными командами отладки
Что вы узнаете
- Присоединение WinDbg к запущенным процессам
- Настройка файлов символов для доступных для чтения выходных данных отладки
- Установка точек останова и управление исполнением программы
- Анализ сбоев приложения
- Навигация по потокам и стекам вызовов
Предпосылки
- На вашем компьютере установлен WinDbg. Инструкции по установке см. в разделе "Скачать и установить отладчик Windows WinDbg".
- Базовое знакомство с интерфейсами командной строки
- (Необязательно) Скомпилированное приложение с символами отладки для второго упражнения
Предполагаемое время завершения: 30 минут
Откройте Блокнот и подключите WinDbg
Перейдите в каталог установки и откройте WinDbg.exe.
В меню файла
выберите Запустить исполняемый файл . В диалоговом окне запуска исполняемого файла перейдите в папку, содержащую notepad.exe. (Обычно файл notepad.exe находится вC:\Windows\System32.) В поле "Имя файла" введите notepad.exe. Выберите Открыть.
Настройте файлы символов, чтобы WinDbg отображал доступные для чтения имена функций и переменных.
В командной строке в нижней части окна WinDbg введите следующую команду:
Результат аналогичен следующему примеру:
Symbol search path is: srv* Expanded Symbol search path is: cache*;SRVЧто такое символы? Файлы символов (PDB) содержат сведения о модулях кода, таких как имена функций и имена переменных. Без символов отображаются только адреса памяти.
Затем введите следующую команду:
Команда
.reloadсообщает WinDbg выполнить свой первоначальный поиск для поиска и загрузки файлов символов.Чтобы просмотреть символы модуля notepad.exe , введите следующую команду:
Заметка
Если выходные данные не отображаются, введите
.reload /f, чтобы попытаться принудительно загрузить символ. Используйте команду !sym noisy для показа дополнительной информации о загрузке символов.Чтобы просмотреть символы в модуле notepad.exe , которые содержатся
main, используйте команду проверки символов для перечисления модулей, соответствующих маске:x notepad!wWin*Результат аналогичен следующему примеру:
00007ff6`6e76b0a0 notepad!wWinMain (wWinMain) 00007ff6`6e783db0 notepad!wWinMainCRTStartup (wWinMainCRTStartup)Чтобы поместить точку останова в
notepad!wWinMain, введите следующую команду:Чтобы убедиться, что вы установили точку останова, введите следующую команду:
Результат аналогичен следующему примеру:
0 e Disable Clear 00007ff6`6e76b0a0 0001 (0001) 0:**** notepad!wWinMainЧтобы запустить процесс Блокнота, введите следующую команду:
Блокнот запускается до тех пор, пока не появится функция
WinMain, а затем она переходит в отладчик.Breakpoint 0 hit notepad!wWinMain: 00007ff6`6e76b0a0 488bc4 mov rax,rspЧтобы просмотреть список модулей кода, загруженных в данный момент в процессе Блокнота, введите следующую команду:
Результат аналогичен следующему примеру:
0:000> lm start end module name 00007ff6`6e760000 00007ff6`6e798000 notepad (pdb symbols) C:\ProgramData\Dbg\sym\notepad.pdb\BC04D9A431EDE299D4625AD6201C8A4A1\notepad.pdb 00007ff8`066a0000 00007ff8`067ab000 gdi32full (deferred) 00007ff8`067b0000 00007ff8`068b0000 ucrtbase (deferred) 00007ff8`06a10000 00007ff8`06aad000 msvcp_win (deferred) 00007ff8`06ab0000 00007ff8`06ad2000 win32u (deferred) 00007ff8`06b40000 00007ff8`06e08000 KERNELBASE (deferred) 00007ff8`07220000 00007ff8`072dd000 KERNEL32 (deferred) 00007ff8`07420000 00007ff8`07775000 combase (deferred) 00007ff8`07820000 00007ff8`079c0000 USER32 (deferred) 00007ff8`079c0000 00007ff8`079f0000 IMM32 (deferred) 00007ff8`07c00000 00007ff8`07c2a000 GDI32 (deferred) 00007ff8`08480000 00007ff8`085ab000 RPCRT4 (deferred) 00007ff8`085b0000 00007ff8`0864e000 msvcrt (deferred) 00007ff8`08c40000 00007ff8`08cee000 shcore (deferred) 00007ff8`08db0000 00007ff8`08fa5000 ntdll (pdb symbols) C:\ProgramData\Dbg\sym\ntdll.pdb\53F12BFE149A2F50205C8D5D66290B481\ntdll.pdb 00007fff`f8580000 00007fff`f881a000 COMCTL32 (deferred)Чтобы просмотреть трассировку стека, введите следующую команду:
Результат аналогичен следующему примеру:
0:000> k 00 000000c8`2647f708 00007ff6`6e783d36 notepad!wWinMain 01 000000c8`2647f710 00007ff8`07237034 notepad!__scrt_common_main_seh+0x106 02 000000c8`2647f750 00007ff8`08e02651 KERNEL32!BaseThreadInitThunk+0x14 03 000000c8`2647f780 00000000`00000000 ntdll!RtlUserThreadStart+0x21Чтобы снова запустить Блокнот, введите следующую команду:
Далее: Вы прервёте выполнение и изучите загруженные модули.
Чтобы перейти в Блокнот, в меню "Файл" выберите "Разорвать".
Чтобы задать и проверить точку останова в
ZwWriteFile, введите следующие команды:Чтобы снова запустить Блокнот, введите g. В окне Блокнота введите текст. В меню "Файл" выберите Сохранить. Выполнение кода прерывается, когда доходит до
ZwCreateFile. Введите команду k, чтобы просмотреть трассировку стека.
В окне WinDbg слева от командной строки отображаются номера процессора и потока. В этом примере текущий номер процессора равен 0, а текущий номер потока — 11 (
0:011>). В окне отображается трассировка стека для потока 11, работающего на процессоре 0.Чтобы просмотреть список всех потоков в процессе Блокнота, введите следующую команду (тильда):
Результат аналогичен следующему примеру:
0:011> ~ 0 Id: 5500.34d8 Suspend: 1 Teb: 000000c8`262c4000 Unfrozen 1 Id: 5500.3960 Suspend: 1 Teb: 000000c8`262c6000 Unfrozen 2 Id: 5500.5d68 Suspend: 1 Teb: 000000c8`262c8000 Unfrozen 3 Id: 5500.4c90 Suspend: 1 Teb: 000000c8`262ca000 Unfrozen 4 Id: 5500.4ac4 Suspend: 1 Teb: 000000c8`262cc000 Unfrozen 5 Id: 5500.293c Suspend: 1 Teb: 000000c8`262ce000 Unfrozen 6 Id: 5500.53a0 Suspend: 1 Teb: 000000c8`262d0000 Unfrozen 7 Id: 5500.3ca4 Suspend: 1 Teb: 000000c8`262d4000 Unfrozen 8 Id: 5500.808 Suspend: 1 Teb: 000000c8`262da000 Unfrozen 10 Id: 5500.3940 Suspend: 1 Teb: 000000c8`262dc000 Unfrozen . 11 Id: 5500.28b0 Suspend: 1 Teb: 000000c8`262de000 Unfrozen 12 Id: 5500.12bc Suspend: 1 Teb: 000000c8`262e0000 Unfrozen 13 Id: 5500.4c34 Suspend: 1 Teb: 000000c8`262e2000 UnfrozenВ этом примере 14 потоков имеют индексы от 0 до 13.
Чтобы просмотреть трассировку стека для потока 0, введите следующие команды:
Результат аналогичен следующему примеру:
0:011> ~0s 0:011> ~0s win32u!NtUserGetProp+0x14: 00007ff8`06ab1204 c3 ret 0:000> k # Child-SP RetAddr Call Site 00 000000c8`2647bd08 00007ff8`07829fe1 win32u!NtUserGetProp+0x14 01 000000c8`2647bd10 00007fff`f86099be USER32!GetPropW+0xd1 02 000000c8`2647bd40 00007ff8`07d12f4d COMCTL32!DefSubclassProc+0x4e 03 000000c8`2647bd90 00007fff`f8609aba SHELL32!CAutoComplete::_EditWndProc+0xb1 04 000000c8`2647bde0 00007fff`f86098b7 COMCTL32!CallNextSubclassProc+0x9a 05 000000c8`2647be60 00007ff8`0782e858 COMCTL32!MasterSubclassProc+0xa7 06 000000c8`2647bf00 00007ff8`0782de1b USER32!UserCallWinProcCheckWow+0x2f8 07 000000c8`2647c090 00007ff8`0782d68a USER32!SendMessageWorker+0x70b 08 000000c8`2647c130 00007ff8`07afa4db USER32!SendMessageW+0xdaЧтобы выйти из отладки и отсоединиться от процесса Блокнота, введите эту команду:
Откройте собственное приложение и подключите WinDbg
Например, предположим, что вы написали и создали это небольшое консольное приложение:
...
void MyFunction(long p1, long p2, long p3)
{
long x = p1 + p2 + p3;
long y = 0;
y = x / p2;
}
void main ()
{
long a = 2;
long b = 0;
MyFunction(a, b, 5);
}
В этом упражнении предполагается, что встроенное приложение (MyApp.exe) и файл символов (MyApp.pdb) находятся в C:\MyApp\x64\Debug. Также предположим, что исходный код приложения находится в C:\MyApp\MyApp and that the target machine compiled MyApp.exe.
Откройте WinDbg.
В меню файла
выберите Запустить исполняемый файл . В диалоговом окне запуска исполняемого файла перейдите в раздел C:\MyApp\x64\Debug. Для имени файла введите MyApp.exe. Выберите Открыть.Введите следующие команды:
.sympath+ C:\MyApp\x64\Debug
Эти команды сообщают WinDbg, где найти символы и исходный код приложения. В этом случае вам не нужно задавать расположение исходного кода с помощью Srcpath , так как символы имеют полные пути к исходным файлам.
Введите следующие команды:
Ваше приложение переключается на отладчик, когда оно достигает своей функции
main.WinDbg отображает исходный код и окно командной строки.
В меню Отладка выберите Войти в (или выберите F11). Продолжайте шагать, пока вы не войдете в
MyFunction. При переходе на строкуy = x / p2приложение падает и включается в отладчик.Результат аналогичен следующему примеру:
(1450.1424): Integer divide-by-zero - code c0000094 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. MyApp!MyFunction+0x44: 00007ff6`3be11064 f77c2428 idiv eax,dword ptr [rsp+28h] ss:00000063`2036f808=00000000Введите следующую команду:
WinDbg отображает анализ проблемы (в данном случае деление на 0).
FAULTING_IP: MyApp!MyFunction+44 [c:\myapp\myapp\myapp.cpp @ 7] 00007ff6`3be11064 f77c2428 idiv eax,dword ptr [rsp+28h] EXCEPTION_RECORD: ffffffffffffffff -- (.exr 0xffffffffffffffff) ExceptionAddress: 00007ff63be11064 (MyApp!MyFunction+0x0000000000000044) ExceptionCode: c0000094 (Integer divide-by-zero) ExceptionFlags: 00000000 NumberParameters: 0 ... STACK_TEXT: 00000063`2036f7e0 00007ff6`3be110b8 : ... : MyApp!MyFunction+0x44 00000063`2036f800 00007ff6`3be1141d : ... : MyApp!main+0x38 00000063`2036f840 00007ff6`3be1154e : ... : MyApp!__tmainCRTStartup+0x19d 00000063`2036f8b0 00007ffc`b1cf16ad : ... : MyApp!mainCRTStartup+0xe 00000063`2036f8e0 00007ffc`b1fc4629 : ... : KERNEL32!BaseThreadInitThunk+0xd 00000063`2036f910 00000000`00000000 : ... : ntdll!RtlUserThreadStart+0x1d STACK_COMMAND: dt ntdll!LdrpLastDllInitializer BaseDllName ;dt ntdll!LdrpFailureData ;.cxr 0x0 ;kb FOLLOWUP_IP: MyApp!MyFunction+44 [c:\myapp\myapp\myapp.cpp @ 7] 00007ff6`3be11064 f77c2428 idiv eax,dword ptr [rsp+28h] FAULTING_SOURCE_LINE: c:\myapp\myapp\myapp.cpp FAULTING_SOURCE_FILE: c:\myapp\myapp\myapp.cpp FAULTING_SOURCE_LINE_NUMBER: 7 FAULTING_SOURCE_CODE: 3: void MyFunction(long p1, long p2, long p3) 4: { 5: long x = p1 + p2 + p3; 6: long y = 0; > 7: y = x / p2; 8: } 9: 10: void main () 11: { 12: long a = 2; ...
Дальнейшие шаги
После отладки системного приложения и собственного кода можно изучить более сложные сценарии отладки:
- Начало работы с WinDbg (режим ядра) — отладка ядра Windows и драйверов
- Операция отладчика — сведения о концепциях операций отладчика
- Методы отладки — изучение расширенных методов отладки
Сводка команд
Ниже приведены основные команды, которые вы используете в этом руководстве:
Настройка и символы:
- .sympath (Задать путь к символам) — настройка, в которой WinDbg находит файлы символов
- .reload (Reload Module) — загрузка файлов символов
Управление выполнением:
- g (Go) — продолжение выполнения программы
- bu (Установка точки останова) — приостановка выполнения на определенной функции
-
Step Into(F11) — выполнение одной инструкции и вход в функции
Проверка программы:
- x (проверка символов) — перечисление функций и переменных
- lm (список загруженных модулей) — отображение всех загруженных библиотек DLL и исполняемых программ
- k (Display Stack Backtrace) — просмотр трассировки стека вызовов
- ~ (состояние потока) — вывод списка всех потоков
- !analyze -v — автоматическое анализ сбоев
Ссылка:
- bl (список точек останова)
- ~s (задать текущий поток)
- .sympath+
- .srcpath (задать исходный путь)
- qd (Выход и отсоединение)
См. также
Начало работы с WinDbg (режим ядра)
Скачайте и установите отладчика WinDbg Для Windows