通過WinDbg條件斷點收集Log

2021-06-18 21:01:59 字數 1571 閱讀 8450

前段時間花了幾天一直在用windbg除錯乙個比較棘手的bug。這個bug是c# team那邊發現的,他們的testcase跑大概10分鐘左右會出乙個在clr內部的assert。比較難除錯的主要原因在於assert表明乙個全域性的資料結構出現了問題,本來不應該用完的陣列卻已經用完了(因為按照設計,這個陣列是邊使用邊清理的,是不會用完的)。初步想到的有下面幾種方案來除錯:

1. 設定資料斷點

2. 一步一步除錯

3. 新增log**

第一步:在乙個或者多個可疑處設定斷點

bu[id] [options] [address [passes]] ["commandstring"]

.echo [function a]; dv this; kb; g

這幾條命令意思是:列印[function a],列印this指標的值,列印當前呼叫棧,然後繼續執行。大家可以根據實際情況新增一些其他命令列印一些自己所需要的資訊。通過上面這套命令列印的內容大致如下:

[functiona]

this = 0xabcdefg

module!funca

module!funcb

module!funcc

…可以看出,這條斷點如果反覆被斷,那麼在windbg的命令視窗中便會把每次斷點被hit的相關資訊通過剛才定義的命令列印出來。如果定義了很多這樣的斷點,那麼在命令視窗中就會把整個程式執行的情況列印出來,起到log的作用,而且可以顯示呼叫棧等資訊,比一般的log要強大許多。

第二步:設定log

預設情況下,windbg的buffer大小是有限的,如果程式執行時間比較長,那麼buffer可能會不夠,我們通過條件斷點打出的資訊會被截斷。幸好,windbg提供了將命令視窗的內容輸出到log中的功能。選擇edit->open/close log file選單項,windbg會顯示如下對話方塊:

第三步:分析log

當獲得了log資訊之後,下一步就需要分析log的內容了,這是一件需要耐心、對資料的敏感、以及一點點運氣的事情。分析的時候可能發現log的資訊不足,這時就需要新增新的斷點或者修改列印的資訊,重新收集log,再加以分析,直到log資訊足夠為止。這時windbg設定條件斷點的優勢就出來了,因為不需要修改**,編譯**,部署**這樣的乙個過程,而是只需要鍵入不同的命令而已。經過幾次調整斷點位置和列印的資訊並重新收集log,我最終通過分析發現這個bug是只有可能在特定情況下rcw沒有被gc,並且建立執行緒退出的時候才會出現,具體的內容因為涉及到.net 4.0中還沒有發布的新功能,這裡就不多說了。可以看到,如果採用常規的方法,對於這種在特定的條件下才會重現的問題是很難發現的。

總之,使用windbg來設定條件斷點,列印相關資訊,並且輸出到log檔案是一種非常強大的除錯方法,可以除錯一些非常複雜的bug,而且具有不需要修改**的靈活性,可以自由定義自己想需要列印的資訊和斷點設定的位置,主要的缺點是方法稍顯複雜,不過如果適應了之後還是很方便的。我強烈推薦大家在遇到比較複雜的bug的時候,可以嘗試使用一下這種方法,可能具有意想不到的效果哦。

windbg條件斷點

條件斷點 condition breakpoint 的是指在上面3種基本斷點停下來後,執行一些自定義的判斷。在基本斷點命令後加上自定義除錯命令,可以讓偵錯程式在斷點觸發停下來後,執行偵錯程式命令。每個命令之間用分號分割。語法格式如 0 000 bpaddress j condition option...

windbg設定條件斷點

一直以為windbg的bp斷點只是簡單的在某個位址上下斷點,後來才發現bp斷點功能很強大 除了可以設定條件斷點還是windbg指令碼的基礎.使用方法很簡單 bp address if condition else 具體例子形如 bp 4dbg.cpp 18 if hfile 0 else 這裡是對原...

windbg字串比較條件斷點

當暫存器指向字串為與某個字串相同時,斷下程式。問題關鍵 需要把暫存器指向的字串取出來比較,而別名可以做到這一點。測試原始碼 void main 斷點 1 e 0040141f e hello test2 test2.cpp 30 0001 0001 0 test2 main 0x3f 指令碼e sc...