zoukankan      html  css  js  c++  java
  • 蛙蛙推荐:新学一招,教大家怎么看死锁

    新学一招,教大家怎么看死锁

    代码如下,3个线程,第一个线程得到锁,Sleep一分钟,后两个线程都等待锁。

    class Program

    {

        static List<int> _list = new List<int>();

        static object _syncRoot = new object();

        static void Main(string[] args)

        {

            Thread t = new Thread(F1);

            t.Start();

            Thread.Sleep(1000);

            t = new Thread(F2);

            t.Start();

            t = new Thread(F3);

            t.Start();

            Console.ReadKey();

        }

        static void F1(object o)

        {

            Console.WriteLine("enter F1");

            lock (_syncRoot)

            {

                Console.WriteLine("F1 enter lock");

                _list.Add(1);

                Thread.Sleep(1000*60);

            }

            Console.WriteLine("F1 leave lock");

        }

        static void F2(object o)

        {

            Console.WriteLine("enter F2");

            lock (_syncRoot)

            {

                Console.WriteLine("F2 enter lock");

                _list.Add(2);

            }

            Console.WriteLine("F2 leave lock");

        }

        static void F3(object o)

        {

            Console.WriteLine("enter F3");

            lock (_syncRoot)

            {

                Console.WriteLine("F3 enter lock");

                _list.Add(3);

            }

            Console.WriteLine("F3 leave lock");

        }

    }

    用windbg按f6附加进程,看同步块信息

    0:013> !syncblk

    Index SyncBlock MonitorHeld Recursion Owning Thread Info  SyncBlock Owner

       18 001b623c            5         1 001eae28  164c  12   0143d54c System.Object

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

    Total           18

    CCW             2

    RCW             0

    ComClassFactory 0

    Free            0

    12号线程获取了0143d54c资源的锁,有2(MonitorHeld的值减去1,除以2)个线程在等待这个锁。

    在.net 1.1里可以直接列出哪些线程在等待这个锁,.net 2.0就不好判断了,这时候可以输入“~* kv”命令,然后搜索“JIT_MonEnterWorker_Portable”和“JITutil_MonContention”,然后看那行的Args列的第一段儿,也就是该方法的第一个参数,如果是!syncblk打出的SyncBlock列的值,那就说明该线程正在等待这个锁,如下

    13  Id: 1840.8f4 Suspend: 1 Teb: 7ff3e000 Unfrozen

    ChildEBP RetAddr  Args to Child             

    WARNING: Stack unwind information not available. Following frames may be wrong.

    0461f1dc 79f4c88a 00000001 001b6250 00000000 ntdll!KiFastSystemCallRet

    0461f244 79f4c4bb 00000001 001b6250 00000000 mscorwks!WaitForMultipleObjectsEx_SO_TOLERANT+0x6f (FPO: [Non-Fpo])

    0461f264 79f4c5c4 00000001 001b6250 00000000 mscorwks!Thread::DoAppropriateAptStateWait+0x3c (FPO: [Non-Fpo])

    0461f2e8 79f4c659 00000001 001b6250 00000000 mscorwks!Thread::DoAppropriateWaitWorker+0x13c (FPO: [Non-Fpo])

    0461f338 79f4c7d9 00000001 001b6250 00000000 mscorwks!Thread::DoAppropriateWait+0x40 (FPO: [Non-Fpo])

    0461f394 79e8c54e ffffffff 00000001 00000000 mscorwks!CLREvent::WaitEx+0xf7 (FPO: [Non-Fpo])

    0461f3a8 79f649fa ffffffff 00000001 00000000 mscorwks!CLREvent::Wait+0x17 (FPO: [Non-Fpo])

    0461f434 79fb874c 001eb4d0 ffffffff 001eb4d0 mscorwks!AwareLock::EnterEpilog+0x8c (FPO: [Non-Fpo])

    0461f450 79fb86d0 e937bce2 0461f52c 00000000 mscorwks!AwareLock::Enter+0x61 (FPO: [Non-Fpo])

    0461f4f0 00da1481 0143d54c 00000000 00000000 mscorwks!JIT_MonEnterWorker_Portable+0xb3 (FPO: [Non-Fpo])

    0461f538 79a00eee 00000000 00000000 00000000 lockTest!lockTest.Program.F2(System.Object)+0x51 (Managed) [D:"huhao_Document"Visual Studio 2005"Projects"ConsoleApplication1"lockTest"Program.cs @ 40]

    0461f544 792e019f 00000000 00000000 00000000 mscorlib_ni!System.Threading.ThreadHelper.ThreadStart_Context(System.Object)+0x72a25e (Managed)

    0461f558 797db48a 00000000 00000000 00000000 mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0x6f (Managed)

    0461f570 79e71b4c 00000000 00000000 00000000 mscorlib_ni!System.Threading.ThreadHelper.ThreadStart(System.Object)+0x4a (Managed)

    0461f580 79e821b1 0461f650 00000000 0461f620 mscorwks!CallDescrWorker+0x33

    0461f600 79e96501 0461f650 00000000 0461f620 mscorwks!CallDescrWorkerWithHandler+0xa3 (FPO: [Non-Fpo])

    0461f738 79e96534 79253444 0461f894 0461f7c4 mscorwks!MethodDesc::CallDescr+0x19c (FPO: [Non-Fpo])

    0461f754 79e96552 79253444 0461f894 0461f7c4 mscorwks!MethodDesc::CallTargetWorker+0x1f (FPO: [Non-Fpo])

    0461f76c 79f3d803 0461f7c4 e937b146 001eb4d0 mscorwks!MethodDescCallSite::CallWithValueTypes+0x1a (FPO: [Non-Fpo])

    0461f954 79e9845f 0461fad0 00000000 00000000 mscorwks!ThreadNative::KickOffThread_Worker+0x192 (FPO: [Non-Fpo])

      14  Id: 1840.14e0 Suspend: 1 Teb: 7ff3d000 Unfrozen

    ChildEBP RetAddr  Args to Child             

    WARNING: Stack unwind information not available. Following frames may be wrong.

    0471f0f4 79f4c88a 00000001 001b6250 00000000 ntdll!KiFastSystemCallRet

    0471f15c 79f4c4bb 00000001 001b6250 00000000 mscorwks!WaitForMultipleObjectsEx_SO_TOLERANT+0x6f (FPO: [Non-Fpo])

    0471f17c 79f4c5c4 00000001 001b6250 00000000 mscorwks!Thread::DoAppropriateAptStateWait+0x3c (FPO: [Non-Fpo])

    0471f200 79f4c659 00000001 001b6250 00000000 mscorwks!Thread::DoAppropriateWaitWorker+0x13c (FPO: [Non-Fpo])

    0471f250 79f4c7d9 00000001 001b6250 00000000 mscorwks!Thread::DoAppropriateWait+0x40 (FPO: [Non-Fpo])

    0471f2ac 79e8c54e ffffffff 00000001 00000000 mscorwks!CLREvent::WaitEx+0xf7 (FPO: [Non-Fpo])

    0471f2c0 79f649fa ffffffff 00000001 00000000 mscorwks!CLREvent::Wait+0x17 (FPO: [Non-Fpo])

    0471f34c 79fb874c 002040b8 ffffffff 001b623c mscorwks!AwareLock::EnterEpilog+0x8c (FPO: [Non-Fpo])

    0471f368 79f64f88 e927bbc2 002040b8 002040b8 mscorwks!AwareLock::Enter+0x61 (FPO: [Non-Fpo])

    0471f3d0 79f64d67 ffffffff e927bc62 0471f4ac mscorwks!AwareLock::Contention+0x199 (FPO: [Non-Fpo])

    0471f470 00da1549 0143d54c 00000000 00000000 mscorwks!JITutil_MonContention+0xa3 (FPO: [Non-Fpo])

    0471f4b8 79a00eee 00000000 00000000 00000000 lockTest!lockTest.Program.F3(System.Object)+0x51 (Managed) [D:"huhao_Document"Visual Studio 2005"Projects"ConsoleApplication1"lockTest"Program.cs @ 50]

    0471f4c4 792e019f 00000000 00000000 00000000 mscorlib_ni!System.Threading.ThreadHelper.ThreadStart_Context(System.Object)+0x72a25e (Managed)

    0471f4d8 797db48a 00000000 00000000 00000000 mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0x6f (Managed)

    0471f4f0 79e71b4c 00000000 00000000 00000000 mscorlib_ni!System.Threading.ThreadHelper.ThreadStart(System.Object)+0x4a (Managed)

    0471f500 79e821b1 0471f5d0 00000000 0471f5a0 mscorwks!CallDescrWorker+0x33

    0471f580 79e96501 0471f5d0 00000000 0471f5a0 mscorwks!CallDescrWorkerWithHandler+0xa3 (FPO: [Non-Fpo])

    0471f6b8 79e96534 79253444 0471f814 0471f744 mscorwks!MethodDesc::CallDescr+0x19c (FPO: [Non-Fpo])

    0471f6d4 79e96552 79253444 0471f814 0471f744 mscorwks!MethodDesc::CallTargetWorker+0x1f (FPO: [Non-Fpo])

    0471f6ec 79f3d803 0471f744 e927b0c6 002040b8 mscorwks!MethodDescCallSite::CallWithValueTypes+0x1a (FPO: [Non-Fpo])

    以上片段说明13号和14号线程,正在等待12号线程所拥有的锁,在排查死锁问题的时候,如果syncblk打出多行,用上面的方法就可以看到是否有互相等待的资源,然后再想法解决掉。以前用“~*e!dso”也能打出所有线程等待的syncblk object对象,但那样来确定是否是这个线程等待这个锁有些没有根据,只说明这个线程的调用栈上引用了这个同步块儿对象。

    参考:http://support.microsoft.com/kb/812614

    !SyncBlk in SOS for .NET Framework 2.0
    http://dotnetdebug.net/2006/02/23/syncblk-in-sos-for-net-framework-20/comment-page-1/#comment-30066

    .NET调试实例-实验1:死锁 - 回顾 (原创翻译)
    http://www.cnblogs.com/justinw/archive/2008/07/14/1242970.html

    A Hang Scenario, Locks and Critical Sections
    http://blogs.msdn.com/tess/archive/2006/01/09/a-hang-scenario-locks-and-critical-sections.aspx

    备注:有时候等待所的时候非托管线程并不停在这两个调用栈上,用!u也看不出来和monitor相关的操作,这种情况我还没掌握如何分析,但~*e!dso,然后搜索!syncblk出来的lock object一般可以确定哪些线程等待哪个锁,笨办法,不知道准不准,前提是你尽量用单独的object做来加锁,这些对象保证不做其他用处,这样!dso出来就比较准了。

  • 相关阅读:
    一个项目需要提交哪了些文档?
    aspose.cells
    国内人才申领《上海市居住证》审核试行办法
    SPRING.NET 1.3.2 学习1组件功能说明
    Nhibernate中实现多数据库支持
    Asp.net Mvc 实用技巧
    windwos server 2008 r2安装,一些最基本设置需要注意的地方
    配置SQL Server的身份验证方式
    MindManager 2012 简介(安装)
    Git 管理篇章
  • 原文地址:https://www.cnblogs.com/onlytiancai/p/1383804.html
Copyright © 2011-2022 走看看