關於 mutex 的調試執行個體

來源:互聯網
上載者:User

今天解決了一個關於 mutex 的 bug.
程式每次登入成功就會建立兩個線程.  sign out 的時候可能會強制 Terminate 這兩個線程.
當程式出現問題時用 Process Explorer 觀察各個線程. 發現其中一個線程一直在等一個對象, 
開啟 windbg, 查看 WaitForSingleObject() 的參數. 找到了這個對象的控制代碼 6d0. 在 windbg 中執行:

0:001>!handle 6d0 f
Handle 6d0
  Type          Mutant
  Attributes    0
  GrantedAccess 0x1f0001:
         Delete,ReadControl,WriteDac,WriteOwner,Synch
         QueryState
  HandleCount   4
  PointerCount  8
  Name         none
  Object Specific Information
    Mutex is Owned
 
知道了這是一個 mutex. 我用 windbg 也不太熟. google 了一下 windbg  mutex. 有所收穫.
用這個文章裡的方法: http://blogs.thinktecture.com/ingo/archive/2006/08/05/414674.aspx
可以找到是那個線程擁有了這個 mutex
運行 kd, 發現是恰好是另一個線程獲得了這個 mutex. 查看代碼, 發現線上程中有這樣的代碼:

 ...
 if (WaitForSingleObject(hmutex, 100) != WAIT_OBJECT_0) return FALSE;
 return TRUE;
  
如果返回 TRUE, 則認為等到這個 mutex, 操作完成之後, 會調用 ReleaseMutex() 釋放這個 mutex. 如果返回 FALSE, 則不會調用 ReleaseMutex().
 
問題就出在這裡. 因為線程可能被強制結束. 那麼就有可能沒有釋放 mutex. 這種情況下, MSDN 的描述是:
 
 If a thread terminates without releasing its ownership of a mutex object, the mutex object is considered to be abandoned. A waiting thread can acquire ownership of an abandoned mutex object, but the wait function will return WAIT_ABANDONED to indicate that the mutex object is abandoned.
 
下一個線程在等這個"被拋棄"的 mutex 時. WaitForSingleObject() 的傳回值是 WAIT_ABANDONED, 而不是 WAIT_OBJECT_0. 而且, 這種情況下, 線程的確獲得了 mutex 的控制權. 但上面的代碼沒有考慮這種情況. 還是返回 FALSE,  導致後繼的 ReleaseMutex() 沒有調用. 因此導致另一個線程被死結.
 
幾點思考:
 1. 一定不要強制結束線程. 反覆強調這一點. 但程式員們還是照用不誤.
 2. 調用 API 的時候對於傳回值的處理要很小心.

PS: 關於 Process Explorer 查看調用棧. 需要幾個前提:
 . 安裝最新的 Process Explorer
 . 安裝最新的 windbg
 . 設定好 _NT_SYMBOL_PATH, 比如:SRV*e:/symbols*http://msdl.microsoft.com/download/symbols
 . 使用命令 symchk /r %windir% 將符號下載到本地. 這個比較費時, 可能要下載超過 1G 的符號檔案
 . 在 Process Explorer 菜單 Options/Configure Symbols 裡設定正確的 Dbghelp.dll 路徑以及 Symbols Path (預設是 _NT_SYMBOL_PATH 的值)
 
這些做好之後, 就可以在 Process Explorer 雙擊一個進程, 切換到 Threads 頁. 等初始化完成之後, 雙擊一個線程, 就可以看到調用棧了.  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.