1. 程式人生 > >用Windbg解決一個Bug

用Windbg解決一個Bug

     今天QA發現在他一臺機器上啟動我們的軟體的時會提示某個DLL(a.dll)找不到(a.dll是b.dll內部用到的一個DLL, 我們軟體直接用的是b.dll)。 

    剛開始我們懷疑是不是a.dll沒有下載下來或是沒有下載完整,但是到安裝目錄下看了,a.dll在那邊,用dependency看了下,DLL的匯出函式也都是正常的。既然DLL本身沒有問題,那就是搜尋路徑的問題了,可以修改的搜尋路徑一般包括當前路徑(current directory)和DLL路徑(dll directory), 正好我們這2項在我們的Trace中都有記錄。通過檢視Trace,發現dll directory在後面確實被修改成了我們另外一個軟體的路徑。

    那麼究竟是誰改了這個路徑? 這就需要藉助Windbg了。我們知道修改DLL路徑的API是SetDllDirectory,所以我們可以通過設定API斷點,然後檢視堆疊就可以了。因為我們這個程式這裡是由其他程式呼叫啟動的,所以我們可以通過子程序的方式來除錯。

    在QA的機器上安裝windbg, 首先將Windbg Attach到父程序,輸入命令 .childdbg 1, 表示允許除錯子程序,然後F5,繼續執行。接下來觸發父程序建立子程序的動作,我們可以看到Windbg會中斷下來, 我們可以通過命令|. 檢視是不是我們的目標程序建立起來了,接下來輸入斷點命令bp Kernel32!SetDllDirectoryA 和 bp Kernel32!SetDllDirectoryW, 然後F5執行。果然很快Windbg又被中斷下來了,通過命令kv檢視堆疊,我們可以看到果然有人呼叫SetDllDirectoryA,原來是我們的底層通訊模組觸發的, 另外我們可以通過da poi(esp+4)檢視SetDllDirectory傳入路徑的值。

     那麼是不是隻要我們把DLL路徑改回原來的NULL,就不會有這個Bug了呢?我們可以在呼叫SetDllDirectory中斷時,直接輸入ed esp+4 0修改傳入引數成0,然後F5執行,果然後面dll的載入就都正常了。

    找到原因後,接下來就是讓QA給對應的模組開發人員報Bug,讓他們把DLL路徑用完後改回來。
    
    可以看到無論對於開發還是測試人員,windbg很多時候可以幫我們快速的定位問題, 如果藉助符號檔案,Windbg完全可以實現比VC IDE更強大的除錯供功能, 並且有時候我們不需要原始碼,不需要重新編譯,直接就可以通過windbg除錯和解決問題。 posted on 2012-06-26 20:33
Richard Wei
閱讀(2800) 評論(3)  編輯 收藏 引用 所屬分類: windbg