Я понял, что Windbg - очень мощный отладчик для платформы Windows, и время от времени я узнаю о нем что-то новое. Могут ли другие пользователи Windbg поделиться своими безумными навыками?
ps: Я не ищу отличных команд, их можно найти в документации. Как насчет того, чтобы поделиться советами, как сделать то, что иначе невозможно было бы сделать с помощью windbg? например Какой-то способ генерировать статистику распределения памяти при запуске процесса под windbg.





Мне больше всего нравится команда .cmdtree <file> (недокументирована, но упоминается в предыдущих примечаниях к выпуску). Это может помочь открыть другое окно (которое можно закрепить) для отображения полезных или часто используемых команд. Это может помочь повысить продуктивность работы пользователя с инструментом.
Изначально о нем говорилось здесь на примере параметра <file>:
http://blogs.msdn.com/debuggingtoolbox/archive/2008/09/17/special-command-execute-commands-from-a-customized-user-interface-with-cmdtree.aspx
Пример: альтернативный текст http://blogs.msdn.com/photos/debuggingtoolbox/images/8954736/original.aspx
Был ли включен параметр файла? Я успешно использовал ту же версию WinDbg с этой командой.
Вы правы, я пропустил параметр файла.
Очень круто! Список полезных команд, которые вы, возможно, захотите добавить в этот файл, можно найти в моем сообщении здесь: ohadsoft.com/2014/10/some-windbg-tips
Следующая команда очень удобна при поиске в стеке объектов C++ с vtables, особенно при работе с релизными сборками, когда многие вещи оптимизируются.
dpp esp Range
Возможность загрузить произвольный PE-файл в качестве дампа - это удобно:
windbg -z mylib.dll
Запросить GetLastError () с помощью:
!gle
Это помогает расшифровать общие коды ошибок:
!error error_number
Почти 60% команд я использую каждый день.
dv /i /t
?? this
kM (kinda undocumented) generates links to frames
.frame x
!analyze -v
!lmi
~
Объяснение
dv /i /t[док]dv - отображать имена и значения локальных переменных в текущей области/i - укажите тип переменной: локальная, глобальная, параметрическая, функция или неизвестная/t - отображение типа данных переменных?? this[док]?? - оценить выражение C++this - C++ этот указательkM[док]k - отображение обратной трассировки стекаM - режим DML. Номера кадров - это гиперссылки на конкретный кадр. Для получения дополнительной информации о км см. http://windbg.info/doc/1-common-cmds.html.frame x[док].frame x, затем используйте dv /i /t. По умолчанию d будет отображать информацию из верхнего кадра.!analyze -v[doc1][doc2 - Использование расширения! analysis]!analyze - расширение analyze. Отображение информации о текущем исключении или проверке ошибок. Обратите внимание, что для запуска расширения мы используем префикс !.-v - подробный вывод!lmi[док]!lmi - расширение lmi. Показать подробную информацию о модуле.~[док]~ - отображает состояние указанного потока или всех потоков текущего процесса.kM, по-видимому, является поведением по умолчанию в WinDbg Preview (доступно в магазине Microsoft), поэтому k 5 и kM 5 дадут эквивалентные результаты
Используйте нет команду WinDbg .heap -stat. Иногда это дает неправильный результат. Вместо этого используйте отчеты о памяти DebugDiags.
Имея правильные числа, вы можете использовать команду WinDbg .heap -flt ....
Мне нравится использовать расширенные команды точки останова, такие как использование точек останова для создания новых одноразовых точек останова.
Синтаксис команды точки останова сложно освоить. Было бы неплохо, если бы вы добавили сюда пример точки останова, которая добавляет точку останова с одним выстрелом.
Чаще всего я использую совет, который избавит вас от необходимости так часто прикасаться к надоедливой мыши: Alt + 1
Alt + 1 переместит фокус в командное окно, чтобы вы могли ввести команду, а стрелка вверх фактически прокручивала историю команд. Однако это не сработает, если ваш фокус уже находится в прокручиваемой истории команд.
Пив: какого черта нажатия клавиш игнорируются, когда фокус находится в исходном окне? Вы не можете редактировать исходный код изнутри WinDbg. Alt + 1 спешат на помощь.
alt+2, alt+1, alt+2, ctrl+F4 Lame hack ... Будет работать, даже если курсор находится в командном окне. :П
Чтобы исследовать утечку памяти в аварийном дампе (поскольку я предпочитаю UMDH для живых процессов). Стратегия заключается в том, что объекты одного типа выделяются одинакового размера.
!heap -h 0 в версию командной строки WinDbg cdb.exe (для большей скорости), чтобы получить все распределения кучи:"C:\Program Files\Debugging Tools for Windows\cdb.exe" -c "!heap -h 0;q" -z [DumpPath] > DumpHeapEntries.log
grep "busy ([[:alnum:]]\+)" DumpHeapEntries.log \ | gawk '{ str = ; gsub(/\(|\)/, "", str); print "0x" str " 0x" }' \ | sort \ | uniq -c \ | gawk '{ printf "%10.2f %10d %10d ( %s = %d )\n", *strtonum()/1024, , strtonum(), , strtonum() }' \ | sort > DumpHeapEntriesStats.log
8489.52 707 12296 ( 0x3000 = 12288 ) 11894.28 5924 2056 ( 0x800 = 2048 ) 13222.66 846250 16 ( 0x2 = 2 ) 14120.41 602471 24 ( 0x2 = 2 ) 31539.30 2018515 16 ( 0x1 = 1 ) 38902.01 1659819 24 ( 0x1 = 1 ) 40856.38 817 51208 ( 0xc800 = 51200 ) 1196684.53 25529270 48 ( 0x24 = 36 )
dps для поиска некоторых выделений кучи размером 0x24 байта в DumpHeapEntries.log, чтобы узнать тип объектов, которые занимают всю память.0:075> dps 3be7f7e8 3be7f7e8 00020006 3be7f7ec 090c01e7 3be7f7f0 0b40fe94 SomeDll!SomeType::`vftable' 3be7f7f4 00000000 3be7f7f8 00000000
Дрянно, но работает :)
Это эпический человек, огромное спасибо за его публикацию.
Я сам пытался реализовать это, но запутался. Как получить адрес 3be7f7e8 для выдачи dds? Это только первый столбец в выводе! Heap? Это означает, что вы ищите в исходном журнале выделение такого размера, получаете адрес, а затем выполняете на нем dds?
Точно, в журнале вы получаете строку, которая выглядит так для каждого выделения памяти: «3be7f7e8: 00038. 00040 [107] - busy (24)». 24 - это значение, которое мы ищем здесь, полученное из приведенной выше таблицы, говорящей нам о том, что большая часть памяти используется для выделения байтов 0x24. Затем я использую cygwin's less для поиска этих строк в DumpHeapEntriesStats.log с помощью команды "/ (24)", выбираю несколько совпадающих адресов и помещаю их в cdb / WinDBG.
Одно слово (ну ладно, три): DML, то есть Язык разметки отладчика.
Это довольно недавнее дополнение к WinDbg, и оно не задокументировано в файле справки. Тем не менее, некоторая документация находится в "dml.doc" в каталоге установки для инструментов отладки для Windows.
По сути, это HTML-подобный синтаксис, который вы можете добавить в свои сценарии отладчика для форматирования и, что более важно, связывания. Вы можете использовать ссылки для вызова других сценариев или даже того же сценария.
Моя повседневная работа включает обслуживание мета-моделировщика, который предоставляет общие объекты и отношения между объектами для большой части программного обеспечения C++. Сначала, чтобы облегчить отладку, я написал простой сценарий дампа, который извлекает соответствующую информацию из этих объектов.
Теперь, с помощью DML, я могу добавлять ссылки к выходным данным, что позволяет снова вызывать тот же сценарий для связанных объектов. Это позволяет намного быстрее исследовать модель.
Вот упрощенный пример. Предположим, что объект, подвергаемый интроспекции, имеет отношение, называемое «ссылкой» на другой объект. r @ $ t0 = $ arg1 $$ arg1 - адрес объекта для проверки
$$ dump some information from $t0
$$ allow the user to examine our reference
aS /x myref @@(&((<C++ type of the reference>*)@$t0)->reference )
.block { .printf /D "<link cmd=\"$$>a< <full path to this script> ${myref}\">dump Ref</link> " }
Очевидно, это довольно консервативный пример, но для меня это действительно бесценно. Вместо того, чтобы искать нужные элементы данных в очень сложных объектах (что обычно занимало до минуты и различные уловки приведения типов и разыменования), все автоматизируется одним щелчком мыши!
В другом ответе упоминалось командное окно и Alt + 1, чтобы сосредоточиться на окне ввода команд. Кому-нибудь сложно прокрутить окно вывода команд без использования мыши?
Что ж, недавно я использовал AutoHotkey для прокрутки окна вывода команд с помощью клавиатуры и не выходя из окна ввода команд.
; WM_VSCROLL = 0x115 (277)
ScrollUp(control = "")
{
SendMessage, 277, 0, 0, %control%, A
}
ScrollDown(control = "")
{
SendMessage, 277, 1, 0, %control%, A
}
ScrollPageUp(control = "")
{
SendMessage, 277, 2, 0, %control%, A
}
ScrollPageDown(control = "")
{
SendMessage, 277, 3, 0, %control%, A
}
ScrollToTop(control = "")
{
SendMessage, 277, 6, 0, %control%, A
}
ScrollToBottom(control = "")
{
SendMessage, 277, 7, 0, %control%, A
}
#IfWinActive, ahk_class WinDbgFrameClass
; For WinDbg, when the child window is attached to the main window
!UP::ScrollUp("RichEdit50W1")
^k::ScrollUp("RichEdit50W1")
!DOWN::ScrollDown("RichEdit50W1")
^j::ScrollDown("RichEdit50W1")
!PGDN::ScrollPageDown("RichEdit50W1")
!PGUP::ScrollPageUp("RichEdit50W1")
!HOME::ScrollToTop("RichEdit50W1")
!END::ScrollToBottom("RichEdit50W1")
#IfWinActive, ahk_class WinBaseClass
; Also for WinDbg, when the child window is a separate window
!UP::ScrollUp("RichEdit50W1")
!DOWN::ScrollDown("RichEdit50W1")
!PGDN::ScrollPageDown("RichEdit50W1")
!PGUP::ScrollPageUp("RichEdit50W1")
!HOME::ScrollToTop("RichEdit50W1")
!END::ScrollToBottom("RichEdit50W1")
После запуска этого сценария вы можете использовать Alt + up / down для прокрутки одной строки окна вывода команд, Alt + PgDn / PgUp для прокрутки одного экрана.
Примечание: похоже, что разные версии WinDbg будут иметь разные имена классов для окна и элементов управления, поэтому вы можете использовать инструмент для шпионажа окон, предоставляемый AutoHotkey, чтобы сначала найти фактические имена классов.
.prefer_dml 1
Это изменяет многие встроенные команды (например, lm) для отображения вывода DML, который позволяет вам щелкать ссылки вместо запуска команд. Довольно удобно ...
.reload /f /o file.dll (/o перезапишет текущую копию имеющегося у вас символа)
.enable_unicode 1 // Переключает отладчик по умолчанию на Юникод для строк, так как все компоненты Windows внутренне используют Unicode, это очень удобно.
.ignore_missing_pages 1 // Если вы выполните много анализа дампа ядра, вы увидите много ошибок, связанных с выгружаемой памятью. Эта команда скажет отладчику прекратить выдачу этого предупреждения.
псевдоним псевдоним псевдоним ...
Сэкономьте время в отладчике. Вот некоторые из моих:
aS !p !process;
aS !t !thread;
aS .f .frame;
aS .p .process /p /r
aS .t .thread /p /r
aS dv dv /V /i /t //make dv do your favorite options by default
aS f !process 0 0 //f for find, e.g. f explorer.exe
Для командных и простых (статических или автоматических) подпрограмм, в которых используется отладчик, очень здорово иметь возможность помещать все команды отладчика для выполнения в текстовый командный файл и запускать их как ввод через kd.exe или cdb.exe. , вызывается с помощью пакетного сценария и т. д.
Запускайте его всякий раз, когда вам нужно выполнить ту же самую старую процедуру, без необходимости запускать WinDbg и делать что-то вручную. Жаль, что это не работает, если вы не уверены, что ищете, или если некоторые параметры команды требуют ручного анализа для поиска / получения.
Скрипт для загрузки SOS на основе версии .NET framework (v2.0 / v4.0):
!for_each_module .if (($sicmp( "@#ModuleName" , "mscorwks") = 0) )
{.loadby sos mscorwks} .elsif ($sicmp( "@#ModuleName" , "clr") = 0)
{.loadby sos clr}
Независимая от платформы строка дампа для управляемого кода, который будет работать для x86 / x64:
j $ptrsize = 8 'aS !ds .printf "%mu \n", c+';'aS !ds .printf "%mu \n", 10+'
Вот пример использования:
0:000> !ds 00000000023620b8
MaxConcurrentInstances
не знаю почему, но похоже, что он недоступен в WinDbg: 6.12.0002.633, когда вводится .cmdtree, появляется всплывающее окно с файлом справки.