簡體   English   中英

尋找調試棘手的Windows服務啟動gremlin的想法

[英]Looking for ideas debugging a tricky windows service startup gremlin

在過去的幾個月里,我收到了QA關於我們的一項服務的報告。 在使用WinDbg檢查掛起轉儲時,每次我發現同樣的事情:Loader鎖定臨界區被鎖定但擁有線程無處可尋。 由於線程已經消失並且我能看到的唯一跟蹤是它留下的全局關鍵部分,我沒有看到在線程線程上運行了什么代碼,甚至是線程來自哪個DLL,它甚至可能不是我們的(即第三方供應商)。

這個問題是非常零星的,在過去的6個月中,它看起來可能是野外自然發生的3-4次。 所有其他時間,服務運行完美。 所以這讓我相信這是某種時機/競爭條件的事情。

最近,我決定自己去做這個。 我設置了一個帶有WinTask腳本的機器,該腳本不斷啟動/停止所述服務。 好消息是,我可以在5-6小時內重現問題。

現在為下一部分:我如何隔離它?

這是我到目前為止所嘗試的:

  1. 在gflags圖像設置中使用“調試器”字段,以便在cdb啟動時自動運行cdb下的服務。 到目前為止,這已經運行了兩天而且從未掛起,因此我認為調試器引入了足夠的時序更改以使問題不可見。

  2. 下載了應用程序驗證程序並將進程配置為與之一起運行。 找到一個完全不相關的錯誤,我們創建CComBSTR臨時變量,將其分配給VARIANT並將變量傳遞給函數調用,即使CComBSTR長時間刪除了分配的字符串。 不要相信這個bug是相關的,因為string是只讀的,並且它運行的線程不是那個正在死的線程。

我正在發帖子,以防你們想到我不考慮的事情。

我雖然有一個Windows實用程序人為地加載CPU並做了其他事情以使競爭條件彈出,我認為應用程序驗證程序做了這樣的事情,但顯然它沒有。 有誰知道我正在采取什么,或者我只是夢想了嗎?

除非在周末發生某些事情,否則我的下一步將是禁用所有調試器,返回庫存並破解其中一個DllMains以記錄THREAD_ATTACH / THREAD_DETACH事件。 至少我能夠攔截創建時死亡的線程。 這可能會有所啟發。

我可能嘗試的是附加內核調試器,然后在Appilcation Verifier下運行該過程。 AV在它持有CS並終止仍保持CS的線程時檢查是否卸載了DLL。 所以這些斷點應該在內核調試器中觸發,然后希望你可以在行為中捕獲它。 希望在KD下運行它不會像用戶模式調試器那樣減慢速度。

事實證明,我比解決方案更接近解決方案。 隨着服務在cdb下運行,它改變了時間,然后用應用程序驗證程序運行它,這更改了時間(頁面堆啟用使分配更慢),我丟失的秘密成分是prime95.exe。 以高於正常優先級的方式運行prime95.exe,確實搞砸了我試圖不改變的任何時間,但它使問題出現在15分鍾內。

原因:

第三方SDK,用於從硬件板獲取數據。 當我們的服務啟動時,我們會查詢不同的捕獲組件的功能。 查詢完成后,我們釋放組件實例。 顯然這個DLL啟動了一個單獨的線程,它獲取了一個加載器鎖,然后繼續在該線程中進行一堆初始化。 如果在那段時間內,我們的功能查詢完成並且我們發布了組件,他們的代碼將在另一個線程上調用TerminateThread(),使加載器鎖永久鎖定。 Prime95減慢了所有內容,足以讓我抓住這個競爭條件並得到以下驗證者停止消息:

=======================================
VERIFIER STOP 00000200: pid 0x1A8C: Thread cannot own a critical section. 

0000091C : Thread ID.
77E17340 : Critical section address.
00000000 : Critical section debug information address.
00000000 : Critical section initialization stack trace.

有趣的是,這個線程正在“消失”,沒有任何異常,所以調試器甚至不會抓住任何機會。 誰使用TerminateThread ????

謝謝大家的建議和支持。 我實際上開始期待在午餐期間駕駛Radioshack購買串行電纜,然后花幾天時間玩KD。 看起來這將要等到下一次:)

一些隨機的想法:如果附加調試器沒有幫助,那么下一步就是檢測(最后一點)。 但是如果一個線程如何在不降低整個過程的情況下死掉,你是否會在某處捕獲異常? 您可能也希望在那里登錄。 如果有幫助,您還可以將WinDbg設置為中斷所有第一次機會異常。 即使你沒有中斷,WinDbg輸出窗口也會顯示第一次機會異常。

我會嘗試一個非侵入式調試器,看看怎么回事,雖然你將無法停止進程,你應該能夠看到任何調試消息以及任何啟動和停止的線程,它應該有對過程績效的影響最小。 我通常使用windbg進行調試,但我認為cbd也有類似的選項。 這很可能會讓你看到這個過程中發生了什么,至少開始幫助縮小范圍。 您可能希望確保做的一件事是重定向輸出(windbg中的.logopen)以確保沒有任何內容超出緩沖區。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM