首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

DllMain中不当操作导致死锁有关问题的分析-DisableThreadLibraryCalls对DllMain中死锁的影响

2012-11-11 
DllMain中不当操作导致死锁问题的分析--DisableThreadLibraryCalls对DllMain中死锁的影响《windows核心编程

DllMain中不当操作导致死锁问题的分析--DisableThreadLibraryCalls对DllMain中死锁的影响

        《windows核心编程》作者在讨论DllMain执行序列化的时候,曾说过一个他的故事:他试图通过调用DisableThreadLibraryCalls以使得新线程不在调用DllMain从而解决死锁问题。但是该方案最后失败了。思考作者的思路,他可能一开始认为:因为线程要调用DllMain而加锁,于是windows在发现DllMain不用调用时就不用加锁了。本文将探讨DisableThreadLibraryCalls对DllMain死锁的影响。首先我们需要定位是什么函数调用了DllMain。(转载请指明出于breaksoftware的csdn博客)为了方便分析,我设计了以下代码


       DLL中

DllMain中不当操作导致死锁有关问题的分析-DisableThreadLibraryCalls对DllMain中死锁的影响

        在LoadLibrary之后Sleep了一下,是为了让工作线程有机会执行起来。

        在执行到Sleep之后,程序中断在DLL中。我们看调用堆栈

DllMain中不当操作导致死锁有关问题的分析-DisableThreadLibraryCalls对DllMain中死锁的影响
        我将关注下从ntdll进入DllWithoutDisableThreadLibraryCalls_A.dll的逻辑调用。双击_LdrpCallInitRoutine这行查看其汇编


        由以上流程可以发现,标红色的7C939A10前一句和7C9399FD前一句是重要的跳转条件判断。它们分别是

VOIDLdrpInitialize (                IN PCONTEXT Context,                IN PVOID SystemArgument1,                IN PVOID SystemArgument2                ){    ……        Peb->LoaderLock = (PVOID)&LoaderLock;    if ( !RtlTryEnterCriticalSection(&LoaderLock) ) {        if ( LoaderLockInitialized ) {            RtlEnterCriticalSection(&LoaderLock);        }        else {            //            // drop into a 30ms delay loop            //            DelayValue.QuadPart = Int32x32To64( 30, -10000 );            while ( !LoaderLockInitialized ) {                NtDelayExecution(FALSE,&DelayValue);            }            RtlEnterCriticalSection(&LoaderLock);        }    }    ……        LdrpInitializeThread(Context);    ……        RtlLeaveCriticalSection(&LoaderLock);    …
        我们看到在11或13或25行进入临界区后,在29行调用了LdrpInitializeThread,而在31行退出临界区。这就是说整个LdrpInitializeThread的逻辑都在临界区中执行的,也就是说DisableThreadLibraryCalls将无权干涉是否会进入临界区。这就解释了为什么不能使用DisableThreadLibraryCalls来使上例解决死锁的原因。


热点排行