Какой твой любимый совет / прием Windbg?

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
45
0
21 751
13

Ответы 13

Мне больше всего нравится команда .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: 6.12.0002.633, когда вводится .cmdtree, появляется всплывающее окно с файлом справки.

Dyno Fu 01.09.2011 13:49

Был ли включен параметр файла? Я успешно использовал ту же версию WinDbg с этой командой.

Kris Kumler 07.09.2011 22:09

Вы правы, я пропустил параметр файла.

Dyno Fu 14.09.2011 11:55

Очень круто! Список полезных команд, которые вы, возможно, захотите добавить в этот файл, можно найти в моем сообщении здесь: ohadsoft.com/2014/10/some-windbg-tips

Ohad Schneider 05.05.2016 12:04

Следующая команда очень удобна при поиске в стеке объектов 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
~

Объяснение

  1. dv /i /t[док]
    1. dv - отображать имена и значения локальных переменных в текущей области
    2. /i - укажите тип переменной: локальная, глобальная, параметрическая, функция или неизвестная
    3. /t - отображение типа данных переменных
  2. ?? this[док]
    1. ?? - оценить выражение C++
    2. this - C++ этот указатель
  3. kM[док]
    1. k - отображение обратной трассировки стека
    2. M - режим DML. Номера кадров - это гиперссылки на конкретный кадр. Для получения дополнительной информации о км см. http://windbg.info/doc/1-common-cmds.html
  4. .frame x[док]
    1. Переключитесь на кадр номер x. 0 - это фрейм наверху стека, 1 - фрейм 1 под 0-м фреймом и так далее.
    2. Чтобы отобразить локальные переменные из другого фрейма в стеке, сначала переключитесь на этот фрейм - .frame x, затем используйте dv /i /t. По умолчанию d будет отображать информацию из верхнего кадра.
  5. !analyze -v[doc1][doc2 - Использование расширения! analysis]
    1. !analyze - расширение analyze. Отображение информации о текущем исключении или проверке ошибок. Обратите внимание, что для запуска расширения мы используем префикс !.
    2. -v - подробный вывод
  6. !lmi[док]
    1. !lmi - расширение lmi. Показать подробную информацию о модуле.
  7. ~[док]
    1. ~ - отображает состояние указанного потока или всех потоков текущего процесса.

kM, по-видимому, является поведением по умолчанию в WinDbg Preview (доступно в магазине Microsoft), поэтому k 5 и kM 5 дадут эквивалентные результаты

Sahil Singh 02.09.2019 12:04

Используйте нет команду WinDbg .heap -stat. Иногда это дает неправильный результат. Вместо этого используйте отчеты о памяти DebugDiags.

Имея правильные числа, вы можете использовать команду WinDbg .heap -flt ....

Мне нравится использовать расширенные команды точки останова, такие как использование точек останова для создания новых одноразовых точек останова.

Синтаксис команды точки останова сложно освоить. Было бы неплохо, если бы вы добавили сюда пример точки останова, которая добавляет точку останова с одним выстрелом.

JeffJ 29.01.2019 16:34

Чаще всего я использую совет, который избавит вас от необходимости так часто прикасаться к надоедливой мыши: Alt + 1

Alt + 1 переместит фокус в командное окно, чтобы вы могли ввести команду, а стрелка вверх фактически прокручивала историю команд. Однако это не сработает, если ваш фокус уже находится в прокручиваемой истории команд.

Пив: какого черта нажатия клавиш игнорируются, когда фокус находится в исходном окне? Вы не можете редактировать исходный код изнутри WinDbg. Alt + 1 спешат на помощь.

alt+2, alt+1, alt+2, ctrl+F4 Lame hack ... Будет работать, даже если курсор находится в командном окне. :П

anishsane 17.09.2014 17:41

Чтобы исследовать утечку памяти в аварийном дампе (поскольку я предпочитаю 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
  • Используйте Cygwin, чтобы найти список распределений, сгруппировав их по размеру:
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
  • Вы получите таблицу, которая выглядит так, например, в которой говорится, что 25529270 выделений размером 0x24 байта занимают почти 1,2  ГБ памяти.
   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 )
  • Затем, если у ваших объектов есть vtables, просто используйте команду dps для поиска некоторых выделений кучи размером 0x24 байта в DumpHeapEntries.log, чтобы узнать тип объектов, которые занимают всю память.
0:075> dps 3be7f7e8
3be7f7e8  00020006
3be7f7ec  090c01e7
3be7f7f0  0b40fe94 SomeDll!SomeType::`vftable'
3be7f7f4  00000000
3be7f7f8  00000000

Дрянно, но работает :)

Это эпический человек, огромное спасибо за его публикацию.

pj4533 24.04.2010 21:04

Я сам пытался реализовать это, но запутался. Как получить адрес 3be7f7e8 для выдачи dds? Это только первый столбец в выводе! Heap? Это означает, что вы ищите в исходном журнале выделение такого размера, получаете адрес, а затем выполняете на нем dds?

pj4533 25.04.2010 04:23

Точно, в журнале вы получаете строку, которая выглядит так для каждого выделения памяти: «3be7f7e8: 00038. 00040 [107] - busy (24)». 24 - это значение, которое мы ищем здесь, полученное из приведенной выше таблицы, говорящей нам о том, что большая часть памяти используется для выделения байтов 0x24. Затем я использую cygwin's less для поиска этих строк в DumpHeapEntriesStats.log с помощью команды "/ (24)", выбираю несколько совпадающих адресов и помещаю их в cdb / WinDBG.

jturcotte 25.04.2010 21:48

Одно слово (ну ладно, три): 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

Другие вопросы по теме