• 如何debug出unmanaged程序中的deadlock?


    在多线程程序开发中,经常会不可预期的出现程序hang。本文介绍了通过windbg找出因为deadlock而造成程序的hang的过程。用于测试的源代码如下:

    // deadlock.cpp : Defines the entry point for the console application.
    //

    #include 
    "stdafx.h"
    #include 
    "windows.h"

    CRITICAL_SECTION g_reader;
    CRITICAL_SECTION g_writer;
    int x=2;

    DWORD WINAPI ThreadProc1(LPVOID lpparameter)
    {
        
        EnterCriticalSection(
    &g_reader);
        printf(
    "get reader of proc1\n");
        Sleep(
    1000);

        EnterCriticalSection(
    &g_writer);
        printf(
    "get writer of proc1\n");
        
        x
    ++;
        printf(
    "this is thread 1,and the result is %d\n",x);

        LeaveCriticalSection(
    &g_reader);
        LeaveCriticalSection(
    &g_writer);
        
    return 0;
    }



    DWORD WINAPI ThreadProc2(LPVOID lpparameter)
    {
        EnterCriticalSection(
    &g_writer);
        printf(
    "get writer of proc2\n");
        Sleep(
    1000);

        EnterCriticalSection(
    &g_reader);
        printf(
    "get reader of proc2\n");

        x
    ++;
        printf(
    "this is thread 2,and the result is %d\n",x);
        LeaveCriticalSection(
    &g_reader);
        LeaveCriticalSection(
    &g_writer);
        
    return 0;
        
    }

    int main(int argc, char* argv[])
    {
        InitializeCriticalSection(
    &g_reader);
        InitializeCriticalSection(
    &g_writer);
        DWORD id;
        
    int i=0;
        
    while(i++<4)
        {
        CreateThread(NULL,NULL,ThreadProc1,NULL,NULL,
    &id);
        
    //Sleep(500);
        CreateThread(NULL,NULL,ThreadProc2,NULL,NULL,&id);
        }
        getchar();
        
    return 0;
    }

    程序运行后就会hang住不动了。

    假设没有源码的情况下,如何知道程序为什么会hang呢?

    首先我们抓取hang dump,键入如下adplus command:

    cscript.exe -hang -pn deadlockdemo -o c:\deaklockdump -quiet

    然后对获取后的dump进行分析,以下是debug过程:

      1 Opened log file 'c:\deadlockdump\debugprocess.log'
      2 0:000> .sympath + D:\study\deadlock\Debug
      3 Symbol search path is+ D:\study\deadlock\Debug
      4 WARNING: Inaccessible path: '+ D:\study\deadlock\Debug'
      5 0:000> .sympath+ D:\study\deadlock\Debug
      6 Symbol search path is+ D:\study\deadlock\Debug;D:\study\deadlock\Debug
      7 WARNING: Inaccessible path: '+ D:\study\deadlock\Debug'
      8 0:000> !runaway
      9  User Mode Time
     10   Thread       Time
     11    8:8eb8      0 days 0:00:00.000
     12    7:8eb4      0 days 0:00:00.000
     13    6:8eb0      0 days 0:00:00.000
     14    5:8eac      0 days 0:00:00.000
     15    4:8ea8      0 days 0:00:00.000
     16    3:8ea4      0 days 0:00:00.000
     17    2:8ea0      0 days 0:00:00.000
     18    1:8e9c      0 days 0:00:00.000
     19    0:8e98      0 days 0:00:00.000
     20 0:000> ~*
     21 .  0  Id: 8e94.8e98 Suspend: 1 Teb: 7ffdf000 Unfrozen
     22       Start: *** WARNING: Unable to verify checksum for deadlock.exe
     23 deadlock!mainCRTStartup (00401780
     24       Priority: 0  Priority class32  Affinity: 1
     25    1  Id: 8e94.8e9c Suspend: 1 Teb: 7ffde000 Unfrozen
     26       Start: deadlock!ILT+0(?ThreadProc1YGKPAXZ) (00401005
     27       Priority: 0  Priority class32  Affinity: 1
     28    2  Id: 8e94.8ea0 Suspend: 1 Teb: 7ffdd000 Unfrozen
     29       Start: deadlock!ILT+5(?ThreadProc2YGKPAXZ) (0040100a) 
     30       Priority: 0  Priority class32  Affinity: 1
     31    3  Id: 8e94.8ea4 Suspend: 1 Teb: 7ffdc000 Unfrozen
     32       Start: deadlock!ILT+0(?ThreadProc1YGKPAXZ) (00401005
     33       Priority: 0  Priority class32  Affinity: 1
     34    4  Id: 8e94.8ea8 Suspend: 1 Teb: 7ffdb000 Unfrozen
     35       Start: deadlock!ILT+5(?ThreadProc2YGKPAXZ) (0040100a) 
     36       Priority: 0  Priority class32  Affinity: 1
     37    5  Id: 8e94.8eac Suspend: 1 Teb: 7ffd9000 Unfrozen
     38       Start: deadlock!ILT+0(?ThreadProc1YGKPAXZ) (00401005
     39       Priority: 0  Priority class32  Affinity: 1
     40    6  Id: 8e94.8eb0 Suspend: 1 Teb: 7ffd8000 Unfrozen
     41       Start: deadlock!ILT+5(?ThreadProc2YGKPAXZ) (0040100a) 
     42       Priority: 0  Priority class32  Affinity: 1
     43    7  Id: 8e94.8eb4 Suspend: 1 Teb: 7ffd7000 Unfrozen
     44       Start: deadlock!ILT+0(?ThreadProc1YGKPAXZ) (00401005
     45       Priority: 0  Priority class32  Affinity: 1
     46    8  Id: 8e94.8eb8 Suspend: 1 Teb: 7ffd6000 Unfrozen
     47       Start: deadlock!ILT+5(?ThreadProc2YGKPAXZ) (0040100a) 
     48       Priority: 0  Priority class32  Affinity: 1
     49 0:000> ~*kb
     50 
     51 .  0  Id: 8e94.8e98 Suspend: 1 Teb: 7ffdf000 Unfrozen
     52 ChildEBP RetAddr  Args to Child              
     53 0012fcbc 7c82787b 7c82ec2a 00000024 0012fd1c ntdll!KiFastSystemCallRet
     54 0012fcc0 7c82ec2a 00000024 0012fd1c 0012fd1c ntdll!NtRequestWaitReplyPort+0xc
     55 *** ERROR: Symbol file could not be found.  Defaulted to export symbols for kernel32.dll - 
     56 0012fce0 77e4cf7c 00000000 00340688 0002021d ntdll!CsrClientCallServer+0x8c
     57 WARNING: Stack unwind information not available. Following frames may be wrong.
     58 0012fdd8 77eb27cc 00000003 00423fa0 00001000 kernel32!ReadConsoleW+0x19b
     59 0012fe60 77e418f0 00000003 00423fa0 00001000 kernel32!ReadConsoleA+0x3b
     60 0012feb8 0040362b 00000003 00423fa0 00001000 kernel32!ReadFile+0xa5
     61 0012fef4 00401520 00000000 00423fa0 00001000 deadlock!_read+0x13b [read.c @ 146]
     62 0012ff1c 0040130e 00422a38 00000000 00000000 deadlock!_filbuf+0xd0 [_filbuf.c @ 127]
     63 0012ff80 00401869 00000001 015d0e90 015d0dc0 deadlock!main+0xde [D:\study\deadlock\deadlock.cpp @ 60]
     64 0012ffc0 77e6f23b 00000000 00000000 7ffda000 deadlock!mainCRTStartup+0xe9 [crt0.c @ 206]
     65 0012fff0 00000000 00401780 00000000 78746341 kernel32!ProcessIdToSessionId+0x209
     66 
     67    1  Id: 8e94.8e9c Suspend: 1 Teb: 7ffde000 Unfrozen
     68 ChildEBP RetAddr  Args to Child              
     69 017cff00 7c827d0b 7c83d236 00000050 00000000 ntdll!KiFastSystemCallRet
     70 017cff04 7c83d236 00000050 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
     71 017cff40 7c83d281 00000050 00000004 00000000 ntdll!RtlpWaitOnCriticalSection+0x1a3
     72 017cff60 0040108a 004235c8 00000000 00000000 ntdll!RtlEnterCriticalSection+0xa8
     73 017cffb8 77e64829 00000000 00000000 00000000 deadlock!ThreadProc1+0x5a [D:\study\deadlock\deadlock.cpp @ 18]
     74 WARNING: Stack unwind information not available. Following frames may be wrong.
     75 017cffec 00000000 00401005 00000000 00000000 kernel32!GetModuleHandleA+0xdf
     76 
     77    2  Id: 8e94.8ea0 Suspend: 1 Teb: 7ffdd000 Unfrozen
     78 ChildEBP RetAddr  Args to Child              
     79 018cff00 7c827d0b 7c83d236 0000004c 00000000 ntdll!KiFastSystemCallRet
     80 018cff04 7c83d236 0000004c 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
     81 018cff40 7c83d281 0000004c 00000004 00000000 ntdll!RtlpWaitOnCriticalSection+0x1a3
     82 018cff60 0040118a 004235e0 00000000 00000000 ntdll!RtlEnterCriticalSection+0xa8
     83 018cffb8 77e64829 00000000 00000000 00000000 deadlock!ThreadProc2+0x5a [D:\study\deadlock\deadlock.cpp @ 37]
     84 WARNING: Stack unwind information not available. Following frames may be wrong.
     85 018cffec 00000000 0040100a 00000000 00000000 kernel32!GetModuleHandleA+0xdf
     86 
     87    3  Id: 8e94.8ea4 Suspend: 1 Teb: 7ffdc000 Unfrozen
     88 ChildEBP RetAddr  Args to Child              
     89 019cff00 7c827d0b 7c83d236 0000004c 00000000 ntdll!KiFastSystemCallRet
     90 019cff04 7c83d236 0000004c 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
     91 019cff40 7c83d281 0000004c 00000004 00000000 ntdll!RtlpWaitOnCriticalSection+0x1a3
     92 019cff60 00401055 004235e0 00000000 00000000 ntdll!RtlEnterCriticalSection+0xa8
     93 019cffb8 77e64829 00000000 00000000 00000000 deadlock!ThreadProc1+0x25 [D:\study\deadlock\deadlock.cpp @ 14]
     94 WARNING: Stack unwind information not available. Following frames may be wrong.
     95 019cffec 00000000 00401005 00000000 00000000 kernel32!GetModuleHandleA+0xdf
     96 
     97    4  Id: 8e94.8ea8 Suspend: 1 Teb: 7ffdb000 Unfrozen
     98 ChildEBP RetAddr  Args to Child              
     99 01acff00 7c827d0b 7c83d236 00000050 00000000 ntdll!KiFastSystemCallRet
    100 01acff04 7c83d236 00000050 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
    101 01acff40 7c83d281 00000050 00000004 00000000 ntdll!RtlpWaitOnCriticalSection+0x1a3
    102 01acff60 00401155 004235c8 00000000 00000000 ntdll!RtlEnterCriticalSection+0xa8
    103 01acffb8 77e64829 00000000 00000000 00000000 deadlock!ThreadProc2+0x25 [D:\study\deadlock\deadlock.cpp @ 33]
    104 WARNING: Stack unwind information not available. Following frames may be wrong.
    105 01acffec 00000000 0040100a 00000000 00000000 kernel32!GetModuleHandleA+0xdf
    106 
    107    5  Id: 8e94.8eac Suspend: 1 Teb: 7ffd9000 Unfrozen
    108 ChildEBP RetAddr  Args to Child              
    109 01bcff00 7c827d0b 7c83d236 0000004c 00000000 ntdll!KiFastSystemCallRet
    110 01bcff04 7c83d236 0000004c 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
    111 01bcff40 7c83d281 0000004c 00000004 00000000 ntdll!RtlpWaitOnCriticalSection+0x1a3
    112 01bcff60 00401055 004235e0 00000000 00000000 ntdll!RtlEnterCriticalSection+0xa8
    113 01bcffb8 77e64829 00000000 00000000 00000000 deadlock!ThreadProc1+0x25 [D:\study\deadlock\deadlock.cpp @ 14]
    114 WARNING: Stack unwind information not available. Following frames may be wrong.
    115 01bcffec 00000000 00401005 00000000 00000000 kernel32!GetModuleHandleA+0xdf
    116 
    117    6  Id: 8e94.8eb0 Suspend: 1 Teb: 7ffd8000 Unfrozen
    118 ChildEBP RetAddr  Args to Child              
    119 01ccff00 7c827d0b 7c83d236 00000050 00000000 ntdll!KiFastSystemCallRet
    120 01ccff04 7c83d236 00000050 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
    121 01ccff40 7c83d281 00000050 00000004 00000000 ntdll!RtlpWaitOnCriticalSection+0x1a3
    122 01ccff60 00401155 004235c8 00000000 00000000 ntdll!RtlEnterCriticalSection+0xa8
    123 01ccffb8 77e64829 00000000 00000000 00000000 deadlock!ThreadProc2+0x25 [D:\study\deadlock\deadlock.cpp @ 33]
    124 WARNING: Stack unwind information not available. Following frames may be wrong.
    125 01ccffec 00000000 0040100a 00000000 00000000 kernel32!GetModuleHandleA+0xdf
    126 
    127    7  Id: 8e94.8eb4 Suspend: 1 Teb: 7ffd7000 Unfrozen
    128 ChildEBP RetAddr  Args to Child              
    129 01dcff00 7c827d0b 7c83d236 0000004c 00000000 ntdll!KiFastSystemCallRet
    130 01dcff04 7c83d236 0000004c 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
    131 01dcff40 7c83d281 0000004c 00000004 00000000 ntdll!RtlpWaitOnCriticalSection+0x1a3
    132 01dcff60 00401055 004235e0 00000000 00000000 ntdll!RtlEnterCriticalSection+0xa8
    133 01dcffb8 77e64829 00000000 00000000 00000000 deadlock!ThreadProc1+0x25 [D:\study\deadlock\deadlock.cpp @ 14]
    134 WARNING: Stack unwind information not available. Following frames may be wrong.
    135 01dcffec 00000000 00401005 00000000 00000000 kernel32!GetModuleHandleA+0xdf
    136 
    137    8  Id: 8e94.8eb8 Suspend: 1 Teb: 7ffd6000 Unfrozen
    138 ChildEBP RetAddr  Args to Child              
    139 01ecff00 7c827d0b 7c83d236 00000050 00000000 ntdll!KiFastSystemCallRet
    140 01ecff04 7c83d236 00000050 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
    141 01ecff40 7c83d281 00000050 00000004 00000000 ntdll!RtlpWaitOnCriticalSection+0x1a3
    142 01ecff60 00401155 004235c8 00000000 00000000 ntdll!RtlEnterCriticalSection+0xa8
    143 01ecffb8 77e64829 00000000 00000000 00000000 deadlock!ThreadProc2+0x25 [D:\study\deadlock\deadlock.cpp @ 33]
    144 WARNING: Stack unwind information not available. Following frames may be wrong.
    145 01ecffec 00000000 0040100a 00000000 00000000 kernel32!GetModuleHandleA+0xdf
    146 0:000> !cs 004235c8 /*找出该criticalSection的相关信息*/
    147 -----------------------------------------
    148 Critical section   = 0x004235c8 (deadlock!g_writer+0x0)
    149 DebugInfo          = 0x7c887f40
    150 LOCKED
    151 LockCount          = 0x4
    152 WaiterWoken        = No
    153 OwningThread       = 0x00008ea0
    154 RecursionCount     = 0x1
    155 LockSemaphore      = 0x50
    156 SpinCount          = 0x00000000
    157 0:000> ~~[0x00008ea0]//找出thread ID相对应的thread详细信息,主要是thread No,如下面是 2
    158    2  Id: 8e94.8ea0 Suspend: 1 Teb: 7ffdd000 Unfrozen
    159       Start: deadlock!ILT+5(?ThreadProc2YGKPAXZ) (0040100a) 
    160       Priority: 0  Priority class32  Affinity: 1
    161 0:000> !cs 004235e0 
    162 -----------------------------------------
    163 Critical section   = 0x004235e0 (deadlock!g_reader+0x0)
    164 DebugInfo          = 0x7c887f20
    165 LOCKED
    166 LockCount          = 0x4
    167 WaiterWoken        = No
    168 OwningThread       = 0x00008e9c
    169 RecursionCount     = 0x1
    170 LockSemaphore      = 0x4C
    171 SpinCount          = 0x00000000
    172 0:000> ~~[0x00008e9c]
    173    1  Id: 8e94.8e9c Suspend: 1 Teb: 7ffde000 Unfrozen
    174       Start: deadlock!ILT+0(?ThreadProc1YGKPAXZ) (00401005
    175       Priority: 0  Priority class32  Affinity: 1
    176 0:000> !cs 004235e0 
    177 -----------------------------------------
    178 Critical section   = 0x004235e0 (deadlock!g_reader+0x0)
    179 DebugInfo          = 0x7c887f20
    180 LOCKED
    181 LockCount          = 0x4
    182 WaiterWoken        = No
    183 OwningThread       = 0x00008e9c
    184 RecursionCount     = 0x1
    185 LockSemaphore      = 0x4C
    186 SpinCount          = 0x00000000
    187 0:000> ~~[0x00008e9c]
    188    1  Id: 8e94.8e9c Suspend: 1 Teb: 7ffde000 Unfrozen
    189       Start: deadlock!ILT+0(?ThreadProc1YGKPAXZ) (00401005
    190       Priority: 0  Priority class32  Affinity: 1
    191 0:000> !cs 004235c8 
    192 -----------------------------------------
    193 Critical section   = 0x004235c8 (deadlock!g_writer+0x0)
    194 DebugInfo          = 0x7c887f40
    195 LOCKED
    196 LockCount          = 0x4
    197 WaiterWoken        = No
    198 OwningThread       = 0x00008ea0
    199 RecursionCount     = 0x1
    200 LockSemaphore      = 0x50
    201 SpinCount          = 0x00000000
    202 0:000> ~~[0x00008ea0]
    203    2  Id: 8e94.8ea0 Suspend: 1 Teb: 7ffdd000 Unfrozen
    204       Start: deadlock!ILT+5(?ThreadProc2YGKPAXZ) (0040100a) 
    205       Priority: 0  Priority class32  Affinity: 1
    206 0:000> .logclose
    207 Closing open log file c:\deadlockdump\debugprocess.log
    208 

    通过以上分析,可以看出thread 1请求g_write,但是g_writer分配给thread2.同时,thread2请求g_reader,而g_reader分配给thread1,从而造成了死锁。而其他的thread,包括thread3,thread4,thread5,thread6,thread7,thread8都在请求g_writer或者g_reader而进入到等待状态。

    以上就是在unmanaged code下寻找deadlock的过程。

  • 相关阅读:
    (感受)新人生的三种境界
    (学)如何在打印时对横向页面重复左端标题
    (原)解决.NET 32位程序运行在64位操作系统下的兼容性问题
    (原)儿子上小学了
    OSG学习过程中的笔记
    从c++角度学习JAVA、Android的总结
    Android Studio利用cmakelists.txt编译OSG的方法总结
    android studio 利用gradle和cmakelist生成c++静态库.a的方法总结
    Android Studio使用c++静态库的方法总结(hello-libs为例)
    Android.mk、CMake、Gradle简介 NDK和JNI的关系
  • 原文地址:https://www.cnblogs.com/Winston/p/1335996.html
Copyright © 2020-2023  润新知