1. 程式人生 > >使用Windbg分析程式死鎖小結

使用Windbg分析程式死鎖小結

死鎖場景描述: 
        針對之前一個版本反饋回來的問題,對資料通訊模組升級,做了精簡和重構

        因為ABA問題的存在,將之前以Socket為key改為以只增的Int為key。使用的鎖為臨界區鎖。

        修改完成,聯調後進行壓力測試,發現當後臺的執行緒池滿的時候會必然發生死鎖。

死鎖定位過程:

    第一步:精簡執行緒模型,將授權檢測執行緒、超時檢測等輔助執行緒通通遮蔽。

    大壓力測試,仍然死鎖。

    第二步: 在第一步的基礎上,將通訊工作執行緒減到1個。

    大壓力測試,仍然死鎖。

     因為涉及模組比較多,為了快速定位問題,使用windbg來檢測死鎖點

     第三步:使用windbg

      當應用程式掛死後,使用windbg Attach到程序。

      1. 使用 ~*kb,檢視堆疊資訊

   8  Id: 368.bd4 Suspend: 1 Teb: 7ffd6000 Unfrozen ChildEBP RetAddr  Args to Child               0614fd4c 7c92df5a 7c939b23 00000604 00000000 ntdll!KiFastSystemCallRet 0614fd50 7c939b23 00000604 00000000 00000000 ntdll!NtWaitForSingleObject+0xc 0614fdd8 7c921046 0012fe08 5f401b5f 0012fe08 ntdll!RtlpWaitForCriticalSection+0x132 0614fde0 5f401b5f 0012fe08 0012fdfc 0614fedc ntdll!RtlEnterCriticalSection+0x46 0614fdf0 0040b207 ffffffff 77d2b326 03103ee0 MFC42D!CCriticalSection::Lock+0x14 0614fedc 5f438514 0012fd30 ffffffff 77d2b326 RecExtraction!CRecExtractionModule::ThreadAnalysis+0x185 [G:\Code\vc2012\VSIP\DigitalViewer_V1\RecExtraction\RecExtractionModule.cpp @ 331] 0614ff80 1020c323 0012f4f4 ffffffff 77d2b326 MFC42D!_AfxThreadEntry+0x2c4 0614ffb4 7c80b729 03103ee0 ffffffff 77d2b326 MSVCRTD!_beginthreadex+0x133 0614ffec 00000000 1020c2b0 03103ee0 00000000 kernel32!BaseThreadStart+0x37 

       其中,上圖中的8是執行緒編號,368是程序ID,bd4是執行緒ID。
      可以看到ntdll!NtWaitForSingleObject ,沒有拿到鎖,說明死鎖發生了。

0614fd4c 7c92df5a 7c939b23 00000604 00000000 ntdll!KiFastSystemCallRet
0614fd50 7c939b23 00000604 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
0614fdd8 7c921046 0012fe08 5f401b5f 0012fe08 ntdll!RtlpWaitForCriticalSection+0x132
這裡的第一個是ebp,第二個是返回函式地址,接下來才是函式的引數。

     要看下比如 ntdll!NtWaitForSingleObject引數定義:

NTSTATUS WINAPI NtWaitForSingleObject( 
  _In_  HANDLE Handle, 
  _In_  BOOLEAN Alertable, 
  _In_  PLARGE_INTEGER Timeout 
); 

    所以 00000604 00000000 00000000分別對應上面的Handle,Alrtable,Timeout.

2. 如果執行緒比較多,可以使用 !cs -l 僅顯示死鎖的臨界區資訊。3.找到了死鎖的臨界區Handle,就可以查詢鎖的持有者了。

    如上所述,handle是00000604,

!cs 00000604     

再看一個網上的例子:

0:004> ~1kb
ChildEBP RetAddr  Args to Child             
0051fe48 7c92df5a 7c939b23 00000034 00000000 ntdll!KiFastSystemCallRet
0051fe4c 7c939b23 00000034 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
0051fed4 7c921046 00417140 00411420 00417140 ntdll!RtlpWaitForCriticalSection+0x132
*** WARNING: Unable to verify checksum for D:\Project1\test2\Debug\test2.exe
0051fedc 00411420 00417140 00000000 00000000 ntdll!RtlEnterCriticalSection+0x46
0051ffb4 7c80b729 00000000 00000000 00000000 test2!thread1+0x50 [d:\project1\test2\test2\test2.cpp @ 10]
0051ffec 00000000 00411122 00000000 00000000 kernel32!BaseThreadStart+0x37
0:004> !cs 00417140
-----------------------------------------
Critical section   = 0x00417140 (test2!cs2+0x0)
DebugInfo          = 0x7c99ea00
LOCKED
LockCount          = 0x2
OwningThread       = 0x00001f60
RecursionCount     = 0x1
LockSemaphore      = 0x34
SpinCount          = 0x00000000

可以看出該臨界區的持有者(OwningThread)是 0x00001f60

這個地址是執行緒在核心中的ID,需要轉換為使用者態的ID,使用~~[]命令。

~~[執行緒核心id]

0:003> ~~[0x0000185c]
        2  Id: 1a98.185c Suspend: 1 Teb: 7ffdd000 Unfrozen
         Start: test2+0x1030 (00401030)
         Priority class: 32; Affinity: f

通過轉換,可以看到鎖的持有者是2號執行緒。

這樣就可以很明確的找到鎖的持有者了,如果pdb載入正確,通過~2kb就已經可以對應到程式碼行了。

查詢死鎖很困難,但是一旦找到點,解決起來就容易多了。

以上的例子部分來自網貼,在此對原作者表示感謝。

---------------------------------

對於死鎖的小結:

1. 對上層提供的函式,需要通過設計,規避操作帶鎖。

2.在鎖中避免呼叫回撥,因為回撥的操作不可預知,易發生死鎖。

相關推薦

使用Windbg分析程式小結

死鎖場景描述:          針對之前一個版本反饋回來的問題,對資料通訊模組升級,做了精簡和重構         因為ABA問題的存在,將之前以Socket為key改為以只增的Int為key。使用的鎖為臨界區鎖。         修改完成,聯調後進行壓力測試,發現當後臺

小結

資源的分類         計算機系統中的資源分為兩類:可搶佔的和不可搶佔的。         可搶佔資源可以從擁有它的程序中搶佔而不會產生任何副作用,例如儲存器就是一類可搶佔的資源;不可搶佔資源是指在不引起相關的計算失敗的情況下,無法把它從佔有它的程序處搶佔過來,例如一個程序已開始刻盤,突然將CD燒錄機

——程式、中斷

1、程式死鎖 過多的同步有可能出現死鎖,死鎖的操作一般在程式執行的時候才有可能出現。 多執行緒要進行資源的共享,就需要同步,但同步過多,就可能造成死鎖。 程式中出現死鎖的一般

程式的原因及四個必要條件

產生死鎖的原因主要是:(1) 因為系統資源不足。(2) 程序執行推進的順序不合適。(3) 資源分配不當等。如果系統資源充足,程序的資源請求都能夠得到滿足,死鎖出現的可能性就很低,否則就會因爭奪有限的資源而陷入死鎖。其次,程序執行推進順序與速度不同,也可能產生死鎖。產生死鎖的

手把手教你分析Mysql問題

前言 發生死鎖了,如何排查和解決呢?本文將跟你一起探討這個問題 準備好資料環境 模擬死鎖案發 分析死鎖日誌 分析死鎖結果 環境準備 資料庫隔離級別: mysql> select @@tx_isolation; +-----------------+ | @@tx_isolation | +----

Windbg查看w3wp進程占用的內存及.NET內存泄露,分析

ubi sta windbg 死鎖 ML htm bing .com point https://www.cnblogs.com/startpoint/p/4194052.html https://www.cnblogs.com/lyl6796910/p/76136

利用windbg分析崩潰,控制代碼洩漏,,CPU高,記憶體洩漏

Windbg的一些簡單使用命令 一、崩潰 1、  輸入.ecxr;kbn得到崩潰的堆疊 其中原始碼如下 2、  檢視堆疊和原始碼,發現第0幀導致崩潰,程式碼也是原生代碼 輸入.frame  0,切到第0幀如下 3、  輸入 dv 檢視當前幀的一些變數資訊       

MySQL Innodb表導致日誌情況分析與歸納

進程 設置 歸納 操作數 into time uid int 死鎖 發現當備份表格的sql語句與刪除該表部分數據的sql語句同時運行時,mysql會檢測出死鎖,並打印出日誌 案例描述在定時腳本運行過程中,發現當備份表格的sql語句與刪除該表部分數據的

select for update引發分析

而在 back ons 關系 級別 分析 得到 ica 分享 本文針對MySQL中在Repeatable Read的隔離級別下使用select for update可能引發的死鎖問題進行分析。 1. 案例 業務中需要對各種類型的實體進行編號,例如對於x類實體的編號可能是x2

Java範例以及如何分析(轉載自ImportNew)

ofo index 對象 str wait 就會 moni ask 進入 本文由 ImportNew - 範琦琦 翻譯自 journaldev。歡迎加入翻譯小組。轉載請見文末要求。 死鎖是兩個甚至多個線程被永久阻塞時的一種運行局面,這種局面的生成伴隨著至少兩個線程和兩個或者

mysql 開發進階篇系列 14 問題(避免查看分析)

mysq cit 優化 業務流程 update span tro isp 問題 一. 概述   通常來說,死鎖都是應用設計問題,通過調整業務流程,數據庫對象設計,事務大小,以及訪問數據庫的sql語句,絕大部分死鎖都可以避免,下面介紹幾種避免死鎖的常用 方法.  1. 在應

Linux執行緒間分析

死鎖 (deadlocks): 是指兩個或兩個以上的程序(執行緒)在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序(執行緒)稱為死鎖程序(執行緒)。 由於資源佔用是互斥的,當某個程序提出申

物件和變數的併發訪問synchronized解析以及分析排查

一.synchronized   “非執行緒安全"是指發生在多個執行緒對同一個物件中的例項變數併發訪問時,產生的”髒讀“現象。synchronized同步處理可解決這一問題。 非執行緒安全問題存在於例項變數中,不存在方法內部的私有變數。 1、synchronized修飾方法的兩種情

MySQL分析一例

Tomcat日誌報死鎖錯誤,show innodb status獲取死鎖資訊: ------------------------ LATEST DETECTED DEADLOCK ------------------------ 181107 9:30:46 *** (1) TRANSACTION:

mysql 簡單分析

-- hand ODB star 資源 無法 作用 dex size mysql都有什麽鎖 MySQL有三種鎖的級別:頁級、表級、行級,內存級(latch)。 表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突的概率最高,並發度最低。 行級鎖:開銷大,加鎖慢;會

一次線上mysql分析

一、現象 發運車次呼叫發車介面時發生異常,後臺丟擲資料庫死鎖日誌。   二、原因分析   通過日誌可以看出事務T1等待 heap no 8的行鎖 (X locks 排他鎖)                 事務T2持有heap no 8的行鎖,等待heap no 7的行鎖 兩個更新運

nikel-rcu問題分析

一. 問題描述 1.1 問題JIRA   XXX 1.2 現象   手機卡死 1.3 結論  XXX 我們能看到在lowswap_fn方法中先呼叫了rcu_read_lock方法,然後呼叫了get_swap_unshared方法,並且在get_swap_unshared方法裡邊又呼叫了w

MySQL批量更新案例分析

表結構如下: CREATE TABLE `user_item` ( `id` BIGINT(20) NOT NULL, `user_id` BIGINT(20) NOT NULL, `item_id` BIGINT(20) NOT NULL,

一個AMS、PMS、WMS競爭引起無法開啟問題的分析過程

問題:在工廠段出現,一直提示“android 正在啟動”,長按開機鍵恢復。由於產線生產機器都是按K計算,所以概率問題會放大,此問題大約1000臺機器會出現10臺左右的卡在android正在啟動,由於到了量產階段,問題緊急,無奈我還被緊急派去生產車間解決問題,最快

【本人禿頂程式設計師】面試題之解密

←←←←←←←←←←←← 我都禿頂了,還不點關注! 死鎖的概念 在多執行緒環境中,我們經常會遇到多個執行緒訪問同一個共享資源的情況,這個時候必須考慮如何維護資料一致性,常見的方式是加鎖處理。只有拿到鎖的執行緒才可以訪問共享資源,通過鎖就可以讓執行緒對共享資源的訪問都是順序的,避免出現