有時候,當我調試一個問題的時候,我會特意忽略掉某些線程。
這個時候,有人就問了:”這些線程是干什么的?你為什么知道要忽略它們?”
我的回答是:我也不清楚這些線程是干啥的,但是無論它的內部工作是什么,這都是正常的。”
博主 Tess Ferrandez 一直在編寫關于 CLR 調試的系列文章,這些文章十分有用,但最為重要的一條是在調試 ASP.NET 死鎖問題時該如何忽略掉不相關的部分。
在實際項目中,死鎖和掛起這類問題十分難以調試,因為出現這類問題時,調試器中并沒有輸出異常相關的信息。程序突然之間就停止了響應,開發者不得不苦思冥想,到底哪里出錯了。
出現此類問題,我們需要先有一個大概的思路,即:我們需要尋找那些”不同尋常”的東西,而為了找到這類東西,我們首先需要知道,哪些東西是正常的。
舉個例子,先運行程序一段時間,然后中斷到調試器,看看內存數據,線程,加載的模塊等相關信息,并將這些信息記錄下來。你所記錄下的這些信息,就是所謂的”正常”的程序行為,就是說,當程序正常運行的時候,你所記錄的就是正常的運行數據。
有了上面的記錄,當程序異常的時候,再次對比下運行時數據,就有可能識別出那些不太正常的數據結構了。
當調試一個大型工程的時候,可能程序會啟動非常多的線程,你不必知曉每個線程具體的工作細節。例如,當我掛接調試器到一個目標進程后,我經常會看到有一些線程會等待 RPC 對象或者是內核線程池相關的線程,說老實話,我也不清楚這些線程是干啥的,但是因為它們總是在那里悄無聲息的運行著,所以,我也不會太關注它們,這些可能就是我上面所說的正常的東西。
總結隨著代碼規模越來越大,診斷機制需要進一步完善,單純通過下斷點調試可能不是那么有效了,這個時候,需要結合調試輸出和日志來查找問題。