關於DML的一些使用


DML是一種非常簡單的標記語言,它幫助基於現有命令的輸出發現和執行新命令。許多WinDbg命令(以及擴展命令)都支持DML。例如,下面是lm D命令,它顯示DML輸出:

 

在上面的命令輸出中,當我單擊“SillyThreadPool”鏈接時,調試器為我執行了另一個命令lmDvmSillyThreadPool,它顯示模塊信息。同樣,還有一個鏈接缺陷可以幫助我探索該模塊中的符號和函數。

第一件事。您不必記住一堆奇怪的命令后綴就可以得到DML輸出。有一個全局開關可以打開,.prefer_dml 1,這會導致許多內置命令和擴展命令顯示dml輸出。例如,下面是打開該開關后kn命令的輸出:

 

單擊時,此處的鏈接將切換到該幀並顯示源代碼和本地變量(執行的命令是.frame 0nN;dv/t/v)。
調試器腳本和擴展也可以生成DML輸出。在調試器腳本中,只需使用.printf/D命令,並在其中嵌入DML鏈接。在調試器擴展中,可以使用IDebugClient::ControlledOutput函數輸出DML。例如,下面顯示單擊時執行另一個命令的鏈接:

.printf /D "<exec cmd=\"lm m ntdll\">lm ntdll</exec>\n\n"

 

我敢打賭你不知道。應用程序本身可以向調試器輸出DML命令!只需要使用outputDebugStringAPI,並在其中嵌入神奇的字符串<?dml?>. 該魔法令牌之后的所有內容都將被解釋為DML字符串,並相應地顯示在調試器中。例如,假設我們的應用程序中有以下代碼:

OutputDebugString(L"Entered thread pool demo app.\n<?dml?><exec cmd=\"!uniqstack\">Dump unique stacks</exec>\n");

然后,調試器遇到此調試輸出時將顯示命令鏈接:

 

下一個命令是.dml_flow。此命令旨在通過將反匯編函數拆分為代碼塊並幫助使用DML鏈接在塊之間導航,使其更易於讀取。你自己試驗這個命令比我用語言解釋要容易得多,但總的來說,你提供了兩個地址——一個開始地址和一個目標地址——這個命令幫助你理解從開始地址可以到達目標的代碼路徑。

 

前一個屏幕截圖中的鏈接指向進入和退出屏幕上顯示的基本代碼塊的跳轉路徑。

與DML有關的最后一個命令是discovery命令,.DML_start。此命令接受一個包含許多DML鏈接和命令描述的文件,並將其顯示在調試器窗口中(這與命令瀏覽器窗口結合使用非常方便)。例如,假設您有以下文件:

Load SOS according to the CLR version that is currently in the process.
    <link cmd=".loadby sos clr; .loadby sos mscorwks">Load SOS</link>

Display the last event and CLR exception.
    <link cmd=".lastevent">Last debugger event</link>
    <link cmd="!PrintException">Last CLR exception</link>

Display the CLR call stack for a specific thread.
    <b>~<i>N</i>s; !CLRStack</b>
    Example: <link cmd="~0s; !CLRStack">~0s; !CLRStack</link>

執行.browse.dml_start dn.dml會產生以下結果:

 

這是一個方便的命令瀏覽器,您可以使用它開始調查。我還認為它對於解釋您在dump分析會話中所采取的步驟非常有用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM