45

私は、Windbg が Windows プラットフォーム用の非常に強力なデバッガーであることを認識しており、時々それについて新しいことを学びます。仲間の Windbg ユーザーは、彼らのマッド スキルの一部を共有できますか?

ps: 気の利いたコマンドを探しているわけではありません。これらはドキュメントに記載されています。Windbg を使用すると想像もつかないことを行うためのヒントを共有してみませんか? たとえば、windbg の下でプロセスが実行されているときにメモリ割り当てに関する統計を生成する方法。

4

13 に答える 13

30

私のお気に入りはコマンドです.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

于 2008-09-24T15:28:29.573 に答える
28

クラッシュ ダンプのメモリ リークを調査するため (ライブ プロセスには UMDH の方が断然好きなので)。戦略は、同じタイプのオブジェクトがすべて同じサイズで割り当てられることです。

  • コマンドを WinDbg のコマンド ライン バージョンの cdb.exe にフィードして!heap -h 0(速度を上げるため)、すべてのヒープ割り当てを取得します。
"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
  • たとえば、次のようなテーブルが得られ、0x24 バイトの 25529270 の割り当てが 1.2 GB 近くのメモリを消費することがわかります。
   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 )
  • 次に、オブジェクトに vtable がある場合は、このdpsコマンドを使用して、DumpHeapEntries.log で 0x24 バイトのヒープ割り当ての一部を探し、すべてのメモリを消費しているオブジェクトの種類を確認します。
0:075> dps 3be7f7e8
3be7f7e8  00020006
3be7f7ec  090c01e7
3be7f7f0  0b40fe94 SomeDll!SomeType::`vftable'
3be7f7f4  00000000
3be7f7f8  00000000

安っぽいですが、うまくいきます:)

于 2009-02-11T16:37:34.583 に答える
20

次のコマンドは、vtables を使用して C++ オブジェクトのスタックを調べる場合、特にリリース ビルドで作業する場合に非常に便利です。

dpp esp範囲


任意の PE ファイルをダンプとしてロードできるのは素晴らしいことです。

windbg -z mylib.dll


GetLastError() に対して次のクエリを実行します。

!gle


これは、一般的なエラー コードを解読するのに役立ちます。

!エラー エラー番号
于 2008-10-01T19:50:56.080 に答える
18

私が日常的に使用するコマンドのほぼ 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 モード。フレーム番号は、特定のフレームへのハイパーリンクです。kM の詳細については、http://windbg.info/doc/1-common-cmds.html を参照してください。
  4. .frame x [ドキュメント]
    1. フレーム番号 x に切り替えます。0 はスタックの一番上のフレーム、1 は 0 番目のフレームの下のフレーム 1 などです。
    2. スタック上の別のフレームからローカル変数を表示するには、まずそのフレームに切り替えてから.frame x、 を使用しますdv /i /t。デフォルトでdは、トップ フレームからの情報が表示されます。
  5. !analyze -v [doc1] [doc2 - !analyze 拡張機能の使用]
    1. !analyze-analyze延長。現在の例外またはバグ チェックに関する情報を表示します。拡張機能を実行するには、接頭辞を付けることに注意してください!
    2. -v- 詳細出力
  6. !lmi [ドキュメント]
    1. !lmi-lmi延長。モジュールに関する詳細情報を表示します。
  7. ~ [ドキュメント]
    1. ~- 指定されたスレッドまたは現在のプロセスのすべてのスレッドのステータスを表示します。
于 2008-10-01T20:12:09.230 に答える
10

Alt私が最も頻繁に使用する「ヒント」は、厄介なマウスに頻繁に触れる必要がないようにするためのものです。1

Alt+1はコマンド ウィンドウにフォーカスを置き、実際にコマンドを入力できるようにし、上矢印キーでコマンド履歴を実際にスクロールできるようにします。ただし、フォーカスがスクロール可能なコマンド履歴に既にある場合は機能しません。

Peeve: フォーカスがソース ウィンドウにある間、キーの押下が無視されるのはなぜですか? WinDbg 内からソース コードを編集できるわけではありません。Alt+1救助に。

于 2009-02-11T06:15:59.820 に答える
8

一言 (まあ、OK、3 つ) : DML、つまりDebugger Markup Language

これは WinDbg にかなり最近追加されたもので、ヘルプ ファイルには記載されていません。ただし、Windows 用デバッグ ツールのインストール ディレクトリにある "dml.doc" には、いくつかのドキュメントがあります。

基本的に、これは 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> " }

明らかに、これはかなり缶詰の例ですが、これは私にとって非常に貴重です。適切なデータ メンバーを探すために非常に複雑なオブジェクトを探し回る代わりに (通常は最大 1 分かかり、さまざまなキャストと逆参照のトリックが必要でした)、すべてがワンクリックで自動化されます。

于 2009-08-03T10:38:36.057 に答える
7
  • .prefer_dml 1

    これにより、多くの組み込みコマンド ( などlm) が変更され、コマンドを実行する代わりにリンクをクリックできる DML 出力が表示されます。かなり便利...

  • .reload /f /o file.dll(/oあなたが持っているシンボルの現在のコピーを上書きします)

  • .enable_unicode 1//すべての Windows コンポーネントが内部で Unicode を使用するため、文字列のデフォルトを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
于 2010-04-28T16:10:33.670 に答える
4

別の答えは、コマンドウィンドウとコマンド入力ウィンドウに焦点を当てるための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")

このスクリプトの実行後、+ /を使用してコマンド出力ウィンドウの1行をスクロールし、+/を使用Altupdown1Alt画面PgDnPgUpスクロールできます。

注:WinDbgのバージョンが異なれば、ウィンドウとコントロールのクラス名も異なるようです。そのため、AutoHotkeyが提供するウィンドウスパイツールを使用して、最初に実際のクラス名を見つけることをお勧めします。

于 2009-11-28T22:50:46.110 に答える
4

.NET Framework バージョン (v2.0 / v4.0) に基づいてSOSをロードするスクリプト:

!for_each_module .if(($sicmp( "@#ModuleName" , "mscorwks") = 0) ) 
{.loadby sos mscorwks} .elsif ($sicmp( "@#ModuleName" , "clr") = 0) 
{.loadby sos clr}
于 2010-09-13T14:30:14.950 に答える
3

ブレークポイントを使用して新しいワンショット ブレークポイントを作成するなど、高度なブレークポイント コマンドを使用するのが好きです。

于 2008-12-22T20:37:43.660 に答える
1

デバッガーが使用されるコマンドおよび単純な(静的または自動化可能な)ルーチンの場合、すべてのデバッガーコマンドをテキストコマンドファイルに入れて、kd.exeまたはcdb.exeを介した入力として実行できるのは非常に便利です。 、バッチスクリプトなどを介して呼び出すことができます。

WinDbgを起動して手動で実行することなく、これと同じ古いルーチンを実行する必要があるときはいつでもそれを実行します。残念ながら、これは、探しているものがわからない場合や、一部のコマンドパラメータを検索/取得するために手動で分析する必要がある場合には機能しません。

于 2010-07-16T15:19:58.113 に答える
1

WinDbg のコマンドは使用しないでください。.heap -stat間違った出力が表示されることがあります。代わりに、DebugDiags メモリ レポートを使用してください。

正しい番号があれば、WinDbg の.heap -flt ...コマンドを使用できます。

于 2008-10-05T12:59:56.833 に答える
1

x86/x64 で動作するマネージド コードのプラットフォームに依存しないダンプ文字列:

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

使用例を次に示します。

0:000> !ds 00000000023620b8

MaxConcurrentInstances
于 2011-02-02T01:33:14.590 に答える