Подтвердить что ты не робот

Какой ваш любимый отзыв/трюк Windbg?

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

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

4b9b3361

Ответ 1

Моей любимой является команда .cmdtree <file> (недокументированная, но упоминаемая в предыдущих выпусках). Это может помочь открыть еще одно окно (которое можно состыковать) для отображения полезных или часто используемых команд. Это может помочь сделать пользователя более продуктивным с помощью инструмента.

Изначально обсуждался здесь, пример для параметра <file>: http://blogs.msdn.com/debuggingtoolbox/archive/2008/09/17/special-command-execute-commands-from-a-customized-user-interface-with-cmdtree.aspx

Пример: alt text http://blogs.msdn.com/photos/debuggingtoolbox/images/8954736/original.aspx

Ответ 2

Изучить утечку памяти в дампе сбоя (так как я предпочитаю 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 список распределений, группируя их по размеру:
grep "busy ([[:alnum:]]\+)" DumpHeapEntries.log \
| gawk '{ str = $8; gsub(/\(|\)/, "", str); print "0x" str " 0x" $4 }' \
| sort \
| uniq -c \
| gawk '{ printf "%10.2f %10d %10d ( %s = %d )\n", $1*strtonum($3)/1024, $1, strtonum($3), $2, strtonum($2) }' \
| 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

Это дрянной, но он работает:)

Ответ 3

Следующая команда очень удобна при просмотре стека для объектов С++ с помощью vtables, особенно при работе с версиями, когда довольно много вещей оптимизируется.

dpp esp Диапазон


Возможность загрузить произвольный файл PE в качестве дампа:

windbg -z mylib.dll


Запрос GetLastError() с помощью:

! гле


Это помогает декодировать общие коды ошибок:

! error error_number

Ответ 4

Почти 60% команд, которые я использую каждый день.

dv /i /t
?? this
kM (kinda undocumented) generates links to frames
.frame x
!analyze -v
!lmi
~

Объяснение

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

Ответ 5

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

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

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

Ответ 6

Одно слово (ну, ОК, три): DML, т.е. Язык разметки отладки.

Это довольно недавнее дополнение к WinDbg, и оно не задокументировано в файле справки. Однако существует некоторая документация в "dml.doc" в каталоге установки для средств отладки для Windows.

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

Моя ежедневная работа включает в себя техническое обслуживание метамодерера, который предоставляет общие объекты и отношения между объектами для большой части программного обеспечения на С++. Сначала, чтобы облегчить отладку, я написал простой дамп script, который извлекает релевантную информацию из этих объектов.

Теперь, с DML, я смог добавить ссылки на вывод, позволяя снова вызвать тот же самый script на связанных объектах. Это позволяет значительно быстрее исследовать модель.

Вот упрощенный пример. Предположим, что объект под интроспекцией имеет отношение, называемое ссылкой на другой объект.   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> " }

Очевидно, это довольно консервированный пример, но этот материал для меня действительно бесценен. Вместо того, чтобы охотиться вокруг в очень сложных объектах для правильных членов данных (которые обычно занимали до минуты и различного трюка кастинга и разыгрывания), все автоматизировано одним щелчком!

Ответ 7

  • .prefer_dml 1

    Это изменяет многие встроенные команды (например, lm), чтобы отобразить вывод DML, который позволяет вам нажимать ссылки вместо запуска команд. Довольно удобно...

  • .reload /f /o file.dll (/o перезапишет текущую копию символа, который у вас есть)

  • .enable_unicode 1//Переключает отладчик по умолчанию на Unicode для строк, поскольку все компоненты 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

Ответ 8

Другой ответ упомянул окно команд и 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")

После выполнения script вы можете использовать Alt + up/down для прокрутки одной строки окна вывода команды, Alt + PgDn/PgUp для прокрутки одного экрана.

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

Ответ 9

Script загрузить 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}

Ответ 10

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

Ответ 11

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

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

Ответ 12

Для командных и простых (статических или автоматизированных) подпрограмм, в которых используется отладчик, очень здорово иметь возможность запускать все команды отладчика в текстовом командном файле и запускать их как входные данные через kd.exe или cdb.exe, вызываемый через пакет script и т.д.

Запустите это, когда вам нужно сделать эту же старую рутину, без необходимости запускать WinDbg и делать что-то вручную. Жаль, что это не работает, когда вы не уверены, что вы ищете, или некоторые параметры команды нуждаются в ручном анализе, чтобы найти/получить.

Ответ 13

Независимая от сервера дамп-строка для управляемого кода, которая будет работать для x86/x64:

j $ptrsize = 8 'aS !ds .printf "%mu \n", c+';'aS !ds .printf "%mu \n", 10+'

Вот пример использования:

0:000> !ds 00000000023620b8

MaxConcurrentInstances