DllMain中不当操作导致死锁问题的分析--导致DllMain中死锁的关键隐藏因子2

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

(转载于breaksoftware的csdn博客)

本文介绍使用Windbg去验证《DllMain中不当操作导致死锁问题的分析--导致DllMain中死锁的关键隐藏因子》中的结论,调试对象是文中刚开始那个例子。

        1 g 让程序运行起来

        2 ctrl+break 中断程序

        3 ~ 查看线程数


        其实该程序自己运行起来的线程只有ID为0、TID为afc的线程。18c4线程是我们在windbg中输入ctrl+break,导致windbg在我们调试的进程中插入的一个中断线程。以后我们看到是这个线程的操作,就可以忽略。

        4 dd fs:[0] 寻找主线程TEB起始地址(7ffde000)


      5 dt _TEB 7ffde000 查看主线程中PEB结构指针(0x7ffdc000)


        6 dt _PEB 0x7ffdc000 寻找LoaderLock的指针(0x7c99e0174)


        7  dt_RTL_CRITICAL_SECTION 0x7c99e174 查看临界区状态,我们看到看到LockCount值为-1,那么我们通过给它设置“写”断点,从而在每次“关键”时刻予以监控。


        8 baw2 0x7c99e178 对LockCount设置写断点

        9 g 

        10kb 我们看到线程号是1,即Windbg插入的线程导致的断点,我们忽略之(我们看到关闭线程时也会进入临界区)


        11 g

        12 kb 同上,忽略之

        13 g

        14 kb 这次是主线程(0)触发了断点,断点原因是LdrLoadDll中要加锁。


        我们使用IDA反编译LdrLoadDll,可以看到调用的位置

  1. v4 = RtlDosApplyFileIsolationRedirection_Ustr(1, a3, &unk_7C99E214, &v11, &v14, &v17, 0, 0, 0);  
  2.  v5 = v4;  
  3.  if ( v4 >= 0 )  
  4.  {  
  5.    v9 = 1;  
  6.  }  
  7.  else  
  8.  {  
  9.    if ( v4 != -1072365560 )  
  10.      goto LABEL_6;  
  11.  }  
  12.  LdrLockLoaderLock(1, 0, &v10);  
  13.  ms_exc.disabled = 0;  
        15 g

        16 kb 还是主线程(0)触发了断点,原因是LdrLoadDll中调用了LdrpLoadDll,该函数中需要进入临界区,这是第二次进临界区了。在《Best Practices for Creating DLLs中有对这种现象允许的说明

[plain] view plain copy
  1. The loader lock is recursive, which means that it can be acquired again by the same thread.    

        在LdrLoadDll中我们看到

  1. LdrLockLoaderLock(1, 0, &v10);  
  2.   ms_exc.disabled = 0;  
  3.   if ( LdrpTopLevelDllBeingLoaded )  
  4.   {  
  5.     if ( ShowSnaps || LdrpShowRecursiveDllLoads || LdrpBreakOnRecursiveDllLoads )  
  6.     {  
  7.       DbgPrint("[%lx,%lx] LDR: Recursive DLL load\n");  
  8.       DbgPrint("[%lx,%lx]   Previous DLL being loaded: \"%wZ\"\n");  
  9.       DbgPrint("[%lx,%lx]   DLL being requested: \"%wZ\"\n");  
  10.       if ( LdrpCurrentDllInitializer )  
  11.         DbgPrint("[%lx,%lx]   DLL whose initializer was currently running: \"%wZ\"\n");  
  12.       else  
  13.         DbgPrint("[%lx,%lx]   No DLL initializer was running\n");  
  14.     }  
  15.   }  
  16.   LdrpTopLevelDllBeingLoaded = v17;  
  17.   v6 = LdrpLoadDll(v9, a1, a2, v17, a4, 1);  

        在LdrpLoadDll中我们看到



        17 g

        18 kb 第三次进入临界区


        19 g 主线程第一次退出临界区


        20 kb 主线程第四次进入临界区


        21 g 主线程第二次退出临界区


        22 g 有线程要进入临界区


        23 kb 这次是我们在代码中启动的工作线程(1)要尝试进入临界区


        24 ~ 查看线程 确定有两个线程了


        25 g 


        26 kb 工作线程(1)要进入临界区,可是它不会进去的,因为它会被挂起


        27 g 死锁了


        28 control+break windbg要启动一个中断线程,中断线程触发了断点


        29 ~ 查看线程,ID为2的就是windbg插入的线程


       30 ~0s 切换到主线程(0),发现主线程在内核态中出不来了


        31 kb 查看主线程调用堆栈,确实是在等工作线程结束


        32 ~1s 切换到工作线程,发现它也在内核态中出不来了


        33 kb 查看工作线程调用堆栈


        34 dt _RTL_CRITICAL_SECTION 0x7c99e174  查看临界区所有权,从线程TID中我们可以看到,临界区的确是被主线程占着。

使用WinDBG分析死锁问题 阅读详情

相关推荐

使用Windbg分析多线程临界区死锁问题

使用Windbg分析多线程临界区死锁问题分享。

dvlinker的技术专栏 5万+

windbg调试之死锁

操作系统对死锁的描述如下: 所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。    那么为什么会产生死锁呢? 1.因为系统资源不足。 2.进程运行推进的顺序不合适。    3.资源分配不当。             而产生死锁的条件有四个: 1.互斥条件:所谓互斥就是进程在某一时间内

sunliangyuan的专栏 2559

使用Windbg排查线程死锁引起的连不上服务器问题

使用Windbg排查线程死锁引起的连不上服务器问题

dvlinker的技术专栏 2万+

WinDbg定位死锁问题

分析程序死锁

过好每一天的女胖子 1348

[转载]DllMain不当操作导致死锁问题分析--导致DllMain死锁关键隐藏因子2...

(转载于breaksoftware的csdn博客) 本文介绍使用Windbg去验证《DllMain不当操作导致死锁问题分析--导致DllMain死锁关键隐藏因子》中的结论,调试对象是文中刚开始那个例子。 1 g 让程序运行起来 2 ctrl+break 中断程序 3 ~ 查看线程数 其实该程序自己运行起...

angbagangzhe065140的博客 138

DllMain不当操作导致死锁问题分析——DllMain中要谨慎写代码(完结篇)

之前几篇文章主要介绍和分析了为什么会在DllMain做出一些不当操作导致死锁的原因。本文将总结以前文章的结论,并介绍些DllMain中还有哪些操作导致死锁问题。(转载请指明出于breaksoftware的csdn博客) DllMain的相关特性 首先列出《DllMain不当操作导致死锁问题分析--进程对DllMain函数的调用规律的研究和分...

方亮的专栏 1万+

DllMain不当操作导致死锁问题分析--导致DllMain死锁关键隐藏因子

(转载于breaksoftware的csdn博客) 有了前面两节的基础,我们现在切入正题:研究下DllMain为什么会因为不当操作导致死锁问题。首先我们看一段比较经典的“DllMain死锁”代码。 [cpp] view plaincopy //主线程中  HMODULE h = LoadLibraryA(strDllName.c_str());  

ProgrammingRing的专栏 1120

导致C++动态库入口函数DllMain死锁关键隐藏因子

导致DllMain死锁关键隐藏因子

dvlinker的技术专栏 1340

[转载]DllMain不当操作导致死锁问题分析--导致DllMain死锁关键隐藏因子...

(转载于breaksoftware的csdn博客) 有了前面两节的基础,我们现在切入正题:研究下DllMain为什么会因为不当操作导致死锁问题。首先我们看一段比较经典的“DllMain死锁”代码。 //主线程中 HMODULEh=LoadLibraryA(strDllName.c_str()); //DLL中代码...

angbagangzhe065140的博客 134

导致DllMain死锁关键隐藏因子解析分享

导致DllMain死锁关键隐藏因子解析分享

dvlinker的技术专栏 280

DllMain不当操作导致死锁问题分析--加载卸载DLL与DllMain死锁的关系

(转载于breaksoftware的csdn博客) 前几篇文章一直没有在源码级证明:DllMain在收到DLL_PROCESS_ATTACH和DLL_PROCESS_DETACH时会进入临界区。这个论证非常重要,因为它是使其他线程不能进入临界区从而导致死锁关键。我构造了在DLL被映射到进程地址空间的场景,请看死锁时加载DLL的线程的堆栈         如果仔细看过《DllMai

ProgrammingRing的专栏 1044

[转载] DllMain不当操作导致死锁问题分析--加载卸载DLL与DllMain死锁的关系

(转载于breaksoftware的csdn博客) 前几篇文章一直没有在源码级证明:DllMain在收到DLL_PROCESS_ATTACH和DLL_PROCESS_DETACH时会进入临界区。这个论证非常重要,因为它是使其他线程不能进入临界区从而导致死锁关键。我构造了在DLL被映射到进程地址空间的场景,请看死锁时加载DLL的线程的堆栈 如果仔细看过《DllMa...

angbagangzhe065140的博客 183

[转载]DllMain不当操作导致死锁问题分析——DllMain中要谨慎写代码(完结篇)...

(转载于breaksoftware的csdn博客) 之前几篇文章主要介绍和分析了为什么会在DllMain做出一些不当操作导致死锁的原因。本文将总结以前文章的结论,并介绍些DllMain中还有哪些操作导致死锁问题DllMain的相关特性 首先列出《DllMain不当操作导致死锁问题分析--进程对DllMain函数的调用规律的研究和分析》中论...

angbagangzhe065140的博客 159

DllMain不当操作导致死锁问题

有人问到了,自己也没了解过这方面的内容,也并没有遇到过这种情况(可能是经验太少),于是做个记录 以便查阅 原作者:breaksoftware 感谢作者 DllMain不当操作导致死锁问题分析死锁介绍 https://blog.csdn.net/breaksoftware/article/details/8142203 DllMain不当操作导致死锁问题分析–进程对DllMain函数的调...

r250414958的博客 347
上一篇: DllMain中不当操作导致死锁问题的分析--导致DllMain中死锁的关键隐藏因子
下一篇: DllMain中不当操作导致死锁问题的分析--DisableThreadLibraryCalls对DllMain中死锁的影响
ProgrammingRing
博客等级 码龄17年 76粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值