[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]] -[[戻る>障害対応に使用するツールの一覧]] * 目次 [#idb6826d] #contents *概要 [#ba4525a8] ダンプ解析やライブデバッグなどができます。 ダンプ解析は高度な技術を要しますが、クラッシュダンプに以下のコマンドを実行することで~ スタックトレースを取得しプロセスをクラッシュさせたプログラムの特定などができます。 **ダンプの分析例 [#of9c8a8c] [[クラッシュ・ダンプ]]をWinDbgのKコマンドで確認した所、~ 以下の様にスタックトレースが出力された。 ChildEBP RetAddr 1c2fd0b8 774a5620 ntdll!KiFastSystemCallRet 1c2fd0bc 774d3c62 ntdll!NtWaitForSingleObject+0xc 1c2fd140 774d3d4b ntdll!RtlReportExceptionEx+0x14b 1c2fd180 774efa87 ntdll!RtlReportException+0x3c 1c2fd194 774efb0d ntdll!RtlpTerminateFailureFilter+0x14 1c2fd1a0 77449bdc ntdll!RtlReportCriticalFailure+0x6b 1c2fd1b4 77444067 ntdll!_EH4_CallFilterFunc+0x12 1c2fd1dc 774a5f79 ntdll!_except_handler4+0x8e 1c2fd200 774a5f4b ntdll!ExecuteHandler2+0x26 1c2fd2b0 774a5dd7 ntdll!ExecuteHandler+0x24 1c2fd2b0 774efaf8 ntdll!KiUserExceptionDispatcher+0xf 1c2fd624 774f0704 ntdll!RtlReportCriticalFailure+0x5b 1c2fd634 774f07f2 ntdll!RtlpReportHeapFailure+0x21 1c2fd668 774afc25 ntdll!RtlpLogHeapFailure+0xa1 1c2fd694 763b9a26 ntdll!RtlFreeHeap+0x60 1c2fd6a8 76079c03 kernel32!HeapFree+0x14 Unable to load image C:\YYYYY\XXXXX.dll, Win32 error 0n2 *** WARNING: Unable to verify timestamp for XXXXX.dll *** ERROR: Module load completed but symbols could not be loaded for XXXXX.dll これにより、"C:\YYYYY\XXXXX.dll" がプロセスをクラッシュさせていることが解る。 *基本的な使い方 [#x9014443] **インストール [#t3a4b429] Debugging Tools for Windowsに同梱されているためこれをインストールする。 -Windows 用デバッグ ツールのダウンロードとインストール~ http://msdn.microsoft.com/ja-jp/windows/hardware/gg463009.aspx --32 ビット版 Debugging Tools for Windows~ http://msdn.microsoft.com/ja-jp/windows/hardware/gg463016.aspx --64 ビット版 Debugging Tools for Windows~ http://msdn.microsoft.com/ja-jp/windows/hardware/gg463012.aspx ***注意点 [#mc7508c7] -ダンプ解析は同一CPUアーキテクチャのPCを利用する。 -システム・モジュールのシンボルをインストールしてシンボルへのパスを指定する。 --UPモジュールについてはPDBファイルを配置(PDBファイルへのパス指定) --Windows シンボル パッケージのダウンロード~ http://msdn.microsoft.com/ja-jp/windows/hardware/gg463028 --ダウンロードサイト指定は、Symbol File Pathに下記を設定する。~ SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols --バージョンやHotFixなどの確認もあるためツールからシンボルサーバへ接続し自動ダウンロードが望ましい。 --lmコマンドを実行して、モジュールが名前解決(アドレス → モジュール名)されるかどうか確認する。 **ポイント解説 [#acf70cb6] ***プロダクト・チームも利用 [#g758981e] -MSのWindowsプロダクト・チームも利用している。 -VSデバッガは言語+ブレークの機能が中心だが、~ WinDbgはカーネルモードのプロセス、スレッドスタックの分析まで可能。 ***[[カーネルモード・ユーザモード]] [#h54e70e0] ユーザモードのデバッグでも、カーネルモードのデバッグでも利用可能。 -裏で動いているデバッグ・エンジン(dbgeng.dll→COM)は変わらない。 -[[カーネル・モード]]は使用する拡張コマンドが違うだけ。 -なお、dbgeng.dll(デバッグ・エンジン)は、~ 他の色々なツールで利用されている。 --ntsd.exe --cdb.exe --kd.exe --dbgsrv.exe --userdump.exe --drwtsn32.exe ***非侵入的アタッチ [#kcc8c746] 非侵入的アタッチが可能。 -侵入的アタッチ --DebugActiveProcessが呼び出される --break-inスレッドが生成される --Windows XP以前では、デバッガ終了時やデタッチ時に、デバッグ対象アプリケーションが強制終了される --侵入的デバッガとしてアタッチできるのは、プロセス当たり一度にひとつだけ -非侵入的アタッチ --OpenProcessが呼び出される --break-inスレッドは生成されない --プロセスに対し、デバッガとして真のアタッチをするわけではない --デバッグ対象アプリケーションのスレッドはすべて凍結状態 --メモリの内容の変更や確認は可能 --ブレークポイントはセットできない --アプリケーションのステップ実行はできない --デバッグ対象アプリケーションを終了することなく、デバッガの終了やデタッチが可能 --ひとつのプロセスに、複数の非侵入的デバッガ( + ひとつの侵入的デバッガ)をアタッチできる --こんな場合に便利... ---Visual Studioなどの侵入的デバッガでアプリケーションをデバッグ中でも、~ WinDbgを非侵入的デバッガとしてアタッチし、追加の情報を取得できる。 ---デバッグ対象アプリケーションは完全に凍結しており、~ 真のアタッチに必要なbreak-inスレッドが生成されることはない。 *コマンド [#ua04ee93] **コマンドの種類 [#l58a3b0c] ***標準コマンド [#ie30cc83] -プロセスのデバッグに使われる -例 : k, lm, g -参考リファレンス --Commands~ http://msdn.microsoft.com/en-us/library/ff539170.aspx ***メタコマンド(ドットコマンド) [#udea2111] -通常、デバッガの制御に使われる。 -例 : .sympath, .cls, .lastevent, .detach, .if -参考リファレンス --Meta-Commands~ http://msdn.microsoft.com/en-us/library/ff552199.aspx ***拡張コマンド [#gb1e1730] -独自に拡張DLLを開発することも可能 -拡張DLLに、エクスポート関数として実装。 -以下の拡張DLL一式がインストール済み --exts.dll --ntsdexts.dll --uext.dll --wow64exts.dll --kdexts.dll --,etc. -拡張DLLとそのヘルプ --!exts.help一般的な拡張コマンド --!Uext.helpユーザーモードの拡張コマンド(OS非依存) --!Ntsdexts.helpユーザーモードの拡張コマンド(OS依存) --!Kdexts.helpカーネルモードの拡張コマンド --!logexts.helpログ取得拡張コマンド --!clr10¥sos.helpマネージコードのデバッグ --!wow64exts.helpWow64デバッガ拡張 -WinDbgが協力なデバッガである大きな理由 --例 : !analyze, !address, !handle, !peb -参考リファレンス --General Extension Commands~ http://msdn.microsoft.com/en-us/library/ff545544.aspx --Kernel-Mode Extension Commands~ http://msdn.microsoft.com/en-us/library/ff551891.aspx --User-Mode Extension Commands~ http://msdn.microsoft.com/en-us/library/ff560035.aspx --Specialized Extension Commands~ http://msdn.microsoft.com/en-us/library/ff558779.aspx **取得情報別コマンド [#xdca720e] ***システム情報取得コマンド [#l3d60ce3] -コマンド --!vm~ システムの仮想メモリ使用統計要約情報を表示 --!process~ 指定プロセスの情報を表示(一覧も可能) -参考リファレンス --Kernel-Mode Extension Commands~ http://msdn.microsoft.com/en-us/library/ff551891.aspx --!process~ http://msdn.microsoft.com/en-us/library/ff564717.aspx ---!process 0 0:プロセス一覧・概要 ---!process 0 1:プロセス一覧・詳細 ---!process addr or pid 7:プロセス詳細・スタックトレース ***プロセス、モジュール情報取得コマンド(PEB) [#z1a20b8d] -PEB(Process Environment Block : プロセス環境ブロック)~ カーネルモード:EPROCESS ---> ユーザモード:PEB --イメージ基本情報 --プロセスヒープの情報 --環境変数、コマンドライン引数 --DLL検索パス -コマンド --!peb~ PEBの情報を整形して表示 --dt nt!_PEB addr~ PEBの全ダンプ --lm~ ロードモジュール、アンロードモジュールの一覧 --lmD~ 上記をデバッガマークアップで出力 --lmvm kernel32~ kernel32の詳細を出力。kernel32はモジュール名 --!lmi kernel32~ 上記のDLL拡張コマンド --!dlls~ ロードモジュールの一覧、ローダに関する情報 --!dlls -c kernel32~ 上記のkernel32のみ。kernel32はモジュール名 --imgreloc~ 再配置情報の表示 --!dh kernel32~ kernel32ヘッダを表示kernel32はモジュール名 -参考リファレンス --lm (List Loaded Modules)~ http://msdn.microsoft.com/en-us/library/ff552026.aspx --以下は、プロセスの変更と、シンボルのリロードを行う場合のコマンド。 ---.process (Set Process Context)~ http://msdn.microsoft.com/en-us/library/ff564723.aspx ---.reload (Reload Module)~ http://msdn.microsoft.com/en-us/library/ff564805.aspx ***スレッド情報取得コマンド(TEB) [#yccbbf0e] -TEB(Thread Environment Block : スレッド環境ブロック)~ カーネルモード:ETHREAD ---> ユーザモード:TEB --スタック情報 --TLS配列 -コマンド --「~」~ プロセス内の全スレッドのスレッド状態 --「~0」~ スレッド0(主スレッド)のスレッド状態 ---> ~Number --「~.」~ カレントのアクティブなスレッド状態 --「~*」~ プロセス内の全スレッドのスレッド状態( + 追加情報) --「~*k」~ プロセス内の全スレッドのコールスタック(~、!uniqstack) --「~<thread>s」~ カレントスレッドの設定 --!gle~ ラストエラーの取得 --runaway~ 各スレッドの消費時間を表示。 --!teb~ TEBの情報を整形して表示 --dt nt!_TEB addr~ TEBの全ダンプ -参考リファレンス --「~」 (Thread Status)~ http://msdn.microsoft.com/en-us/library/ff566245.aspx ***コールスタックのサイズ取得コマンド [#s9419527] -!teb >↓ -dt ntdll!_TEB DeallocationStack xxxxx~ TEB at xxxx の値を指定。 >↓ -!address esp~ esp(ESPレジスタ)は、カレントスレッドのスタック位置 >↓ -? xxxx - yyyy --xxxx = stackbase --yyyy = stacklimit --スタックがコミットしたバイト数 >↓ -? xxxx - zzzz --zzzz = DeallocationStack --スタックの予約したバイト数 -補足説明 --Stackbaseスタックの始点 --Stacklimitスタックの使用量(コミット・サイズ) --DeallocationStackスタックの終点(予約サイズ) --?コマンドは、さまざまな計算が可能。また10進数の表示ができる。 ***コールスタックの情報取得コマンド [#e037387e] -コマンド --!uniqstack~ プロセス内の全スレッドのコールスタック(~、~*k) --!findstack MySymbol 2~ MySymbolを含む全コールスタックを探して表示。 --K~ カレントスレッドのコールスタックを表示。 --kP~ + 呼び出しの全パラメータ --Kf~ + 隣接フレーム(サブルーチン毎にコールスタックに格納する情報)との距離 --Kv~ + FOP(frame pointer omission)情報と呼び出し規約を表示。 --Kb~ + first three parameters情報を表示。 --kM~ 上記をデバッガマークアップで出力 -参考リファレンス --k, kb, kc, kd, kp, kP, kv (Display Stack Backtrace)~ http://msdn.microsoft.com/en-us/library/ff551943.aspx ***トラップフレームのコマンド [#a22bce5f] -コマンド --.trap~ kvコマンドで取得したFOPのアドレスを入力してトラップフレームを復元する。 トラップフレームとは・・・ ***プロセスのメモリ情報、操作コマンド [#hb454314] -コマンド --d~ メモリ表示 --dd~ メモリ表示:ダブルワード --da~ メモリ表示:ASCIII --du~ メモリ表示:UNICODE --f~ メモリを指定の値で埋める --!vprot addr~ 指定アドレスの仮想メモリ保護情報 --!address addr~ 指定アドレスのメモリ情報(タイプ、保護、使用状況など) --!address -RegionUsageStack~ プロセスの全スレッドスタック領域を表示 --dds~ メモリ内容と対応するシンボル --ddp~ メモリ内容と参照先メモリ内容、またそのシンボル。 -参考リファレンス --d, da, db, dc, dd, dD, df, dp, dq, du, dw (Display Memory)~ http://msdn.microsoft.com/en-us/library/ff542790.aspx --dda, ddp, ddu, dpa, dpp, dpu, dqa, dqp, dqu (Display Referenced Memory)~ http://msdn.microsoft.com/en-us/library/ff540451.aspx --dds, dps, dqs (Display Words and Symbols)~ http://msdn.microsoft.com/en-us/library/ff540455.aspx ***ヒープ情報取得コマンド [#h5586131] 下記コマンドを実行する場合、[[グローバルフラグを設定>クラッシュ・ダンプ#g2aa5c94]]する。 -コマンド --!heap -?~ ヘルプ --!heap -h~ ヒープのインデックスの範囲(開始-終了アドレス)を一覧 --!heap -s 0~ 全ヒープの要約(=予約メモリ、コミットメモリ) --!heap -flt s Size~ 指定サイズに一致する割り当てを表示。 --!heap -stat~ ヒープのハンドルを一覧表示 --!heap -stat -h 0~ メモリ割り当てサイズ毎に使用状況の統計を表示。 --!heap -l~ デバッガにリーク原因とされたheapエントリを知らせる。 --!heap -p~ Gflagsの設定と、ヒープハンドルの一覧 --!heap -p -all~ プロセスの全ヒープの割り当ての詳細(全てのHeapAlloc呼び出しの一覧 --!heap -p -a heapentryaddr~ heapentryaddr(HeapAllocの返却アドレス)を含むヒープ割り当ての詳細(スタックトレース)~ ※ リークのチェックの際は「!heap -l」で取得したheapentryaddr(Entry列)を指定する。 -参考リファレンス --!heap~ http://msdn.microsoft.com/en-us/library/ff563189.aspx ***シンボルの設定など [#fe49ec8d] -.sympath~ シンボルの検索パスの取得と設定 -.sympath+ XY~ シンボルの検索パスに、XY -!sym noisy~ シンボルの検索パス情報を表示 -ld kernel32~ kernel32.dllのシンボルを読み込む。 -ld *~ 全モジュールのシンボルを読み込む。 -.reload~ シンボル情報を読み直す。 -x kernel32!*~ kernel32.dllのシンボルを一覧表示。 -x kernel32!*LoadLibrary*~ kernel32.dllの(例)「LoadLibrary」文字列を含むシンボルを一覧表示。 -dt ntdll!*~ ntdll.dll内の全変数を表示。 *スレッド・スタック、例外分析 [#e05ec6f7] **アンマネージでもマネージでも利用可能。 [#ed7fa0e9] ***「!analyze -v」コマンド [#s3eb6f80] クラッシュ分析ヒューリスティックにより現在の例外に関する詳細情報を表示 ***「~」コマンド [#nb8451f9] スレッド一覧表示 ***「~*k」コマンド [#n866c6b0] スレッドのコール・スタックを表示 ***~<thread>s [#p0110f41] カレント・スレッドの設定 ***「KN, .Frame , DV, and DT 」コマンド [#y8f70925] 現在のコール・スタックの引数、ローカル変数を確認できる。 -Windbg Tip KN, .Frame , DV, and DT - It's so easy - Ntdebugging Blog - Site Home - MSDN Blogs~ http://blogs.msdn.com/b/ntdebugging/archive/2008/06/06/windbg-tip-kn-frame-dv-and-dt-it-s-so-easy.aspx **マネージで利用可能 [#e1f60dac] ***「!PrintException -nested」コマンド [#la6dbd9e] クラッシュ分析ヒューリスティックにより現在の例外に関する詳細情報を表示 ***「!thread」コマンド [#n20e1098] スレッドの状態を表示 -アンマネージスレッドか? -マネージスレッドか? --ファイナライザスレッドか? --ステータス情報を確認できる。 ---Appendix~ http://msdn.microsoft.com/en-us/library/ee817657.aspx~ ・Thread State Values ***「!ClrStack -a」コマンド [#b176bc5a] -マネージドコードのコールスタック -「~*k」コマンドより若干詳しい。 なお、ここに表示される -引数 -ローカル変数 は、以下のコマンドを使用して値を確認できる。 -変数がStringである場合、~ !DumpObjコマンドに指定すれば、文字列情報を取得できる。 -変数が配列である場合、~ !DumpArrayコマンドを使用して、各要素の情報を取得できる。 -参照渡しの引数である場合~ ddコマンドを使用してアドレス情報を確認できる。~ (ddコマンドではポインタ(オブジェクト参照)の指す値を確認できる) *メモリ・リーク分析 [#r14b7f86] -プロセスのスレッドのヒープの使用状況のログを取得できる。 -このログを比較することで、どのスタックトーレスが[[メモリ・リーク]]に関係しているかを絞り込むことができる。 -javaや.netのマネージ・リソースの[[メモリ・リーク]]は検出できないことがあるので注意する。 -これは、マネージド・ヒープがガベージ・コレクタによって管理されているため。 **準備 [#tb07cdd5] ヒープマネージャに管理されるヒープ内の利用状況に関する情報を所得したい場合、ダンプ取得コマンドを実行する前に、[[グローバルフラグを設定>クラッシュ・ダンプ#g2aa5c94]]する。 >※ [ダンプの種類と概要、取得ツール]のシートの[メモリリーク分析用のダンプ]を参照のこと。~ なお、リークを疑っている場合、同じダンプを見ても解らないので、差分を見るなどする。~ 若しくは、[[UMDH]]ツールを使用してログ出力してヒープの差分を確認するなどする。 **ダンプ取得 [#x6d0af1f] 任意のツールを使用してユーザモード・プロセスダンプを取得する。 **ダンプ分析 [#k4e7b041] ***仮想アドレス空間の情報 [#e0876dd6] -!addressコマンドから仮想アドレス空間の全情報を取得できる。 --!address~ プロセスの仮想アドレス空間の全情報を表示 --!address -summary~ プロセスの仮想アドレス空間のサマリを表示 --!address –RegionUsageStack~ プロセスの全スレッドのスタック領域を表示 -ただし、ヒープ・マネージャに管理される~ ヒープ内のメモリ利用状況に関する情報は取得できない。 ***ヒープ内の利用状況の情報 [#a38479a8] 下記を実行してヒープ内のメモリ利用状況を確認する。 -ヒープリーク検出(ページ ヒープ)~ !heap -p -a コマンドコマンドでstacktraceを出力 -ユーザモード スタックトレース データベース~ !heap -a コマンドでstacktraceを出力 *[[カーネル・ダンプ]](完全メモリ・ダンプ)分析 [#i36f4dfe] **準備と取得 [#ve97b358] ***[[準備>カーネル・ダンプ#m64be791]] [#t6be2148] ***[[取得>カーネル・ダンプ#be65c218]] [#x6f23ebc] **分析 [#dc142064] ***参考 [#lbed644f] -STOPエラーの原因解析~ http://www.nextftp.com/to-i/analyze.htm -Windowsダンプの極意(書籍)~ http://ascii.asciimw.jp/books/books/detail/978-4-04-867509-3.shtml >[[カーネル・ダンプ]](完全メモリ・ダンプ)から、~ ノートパッド(notepad.exe)の「変更を保存しますか?」ダイアログを表示するための~ USER32!MessageBoxW関数へ渡されている引数を特定するサンプルが記載されている。 *[[+SOS拡張によるマネージ・ライブ・デバック>.NETのメモリ・リーク#mfaa3ea9]] [#a301f79a] *参考 [#peffdc7b] **WinDbg. From A to Z! [#v980747d] WinDbg_A_to_Z_mono_JP.pdf~ http://windbg.info/download/doc/pdf/WinDbg_A_to_Z_mono_JP.pdf **Debugger Commands [#o579f9c4] http://msdn.microsoft.com/en-us/library/ff540507.aspx **WinDbg入門 [#v2f1dce9] http://www.ttoyota.com/php/install_intro.php -WinDbgについて -WinDbgの適応範囲 -WinDbgのインストール -WinDbgの基本設定 -WinDbgの動作確認(ユーザーモード) -WinDbgの動作確認(カーネルモード) -!analyze -vコマンドの実行 -クラッシュダンプ自動解析入門 **Windbg Hoster-JP [#d659e59b] http://www.hoster.jp/tag/windbg -[Windbg 第1回] Windbgを知っていますか? -[Windbg 第2回] Windbgはどこにありますか? -[Windbg 第3回] ツールはどのようにインストールしますか。 -[Windbg 第4回] カーネルメモリ空間のダンプを取得する。 -[Windbg 第5回] ユーザメモリ空間のダンプを取得する。 -[Windbg 第6回] 取得したダンプをWindbgで開く -[Windbg 第7回] 取得したダンプをkanalyzeで開く -[Windbg 第8回] Windbgでよく使うコマンド --(その1)クラッシュ時に起動しているアプリケーションを確認する --(その2)クラッシュ時に読み込まれていたドライバーを確認する --(その3)クラッシュしたサーバのハードウェア情報を確認する **現場で使えるWinDbgカーネルコマンド [#ac1b1a4d] -現場で使えるWinDbgカーネルコマンド:EnterpriseZine (EZ)~ http://enterprisezine.jp/article/corner/69 --システム管理とWinDbgカーネルデバッガー --WinDbgのインストールと3つのコマンド --システム管理者のためのプロセス構造体入門 --プロセスはオブジェクトである」の意味は --プロセスと!objectコマンド **[Debugging] Windbg を使ってご機嫌ナナメな彼女の心を激しくデバッグ! [#sd67da4c] -(1)~ http://blogs.technet.com/jpilmblg/archive/2009/02/21/debugging-windbg-1.aspx -(2) Ver 1.1~ http://blogs.technet.com/jpilmblg/archive/2009/02/25/debugging-windbg-2.aspx -(3)~ http://blogs.technet.com/jpilmblg/archive/2009/03/06/debugging-windbg-3-tips.aspx **技術-Windows-WinDbgメモ [#de3b73b1] 技術-Windows-WinDbgメモ - Glamenv-Septzen.net~ http://www.glamenv-septzen.net/view/706 **Hyper-Vなどの仮想OSにwindbgをアタッチする方法 [#q6dbf3e0] -Hyper-Vなどの仮想OSにwindbgをアタッチする方法 | Japan WDK Support Blog~ https://blogs.msdn.microsoft.com/jpwdkblog/2009/03/18/hyper-voswindbg/ **DKOMベースのWindowsメモリダンプ解析技術オンサイトセミナー~ [#zcd705db] http://www.ttoyota.com/php/onsiteseminar_ver1.php ---- Tags: [[:障害対応]], [[:性能]], [[:デバッグ]]