软件调试系列:谁动了我的线程

 

死锁的原因很多,其中一种比较常见的是 线程占用临界区后被强杀,导致临界区没有释放,因此当其它线程访问该临界区就会死等。

可是到底是谁强杀了线程了呢?被强杀的线程当时的调用线又是什么呢?

对于问题1:有两种办法找到答案。

一)搜索所有的代码,查看是否有调用terminatethread的地方。

二)在内存中搜索调用terminatethread的指令。

方法一有一定难度,因为开发人员可能没有所有代码的权限。

相比方法一,方法二就更加的直接了当了,在程序的内存中直接搜索call terminatethread的指令,找到对应的模块及调用函数,然后再与模块相关的开发人员确认即可。

现在以我所在的项目的一个死锁例子来看一下,如何在内存中搜索调用terminatethread的指令。

第一步,找到terminatethread函数地址。

0:000> x *!*_imp__TerminateThread*

0023b6f4 VFToolkit0101D!_imp__TerminateThread = <no type information>

00d6f63c RTDAcc!_imp__TerminateThread = <no type information>

0102f070 VFToolkit0101!_imp__TerminateThread = <no type information>

012ec020 SCUtility_VC6D!_imp__TerminateThread = <no type information>

013e3024 SCSessionUtil_VC6D!_imp__TerminateThread = <no type information>

0e7a7014 PostTripQuery_VC6D!_imp__TerminateThread = <no type information>

0ea75010 PostTripClient!_imp__TerminateThread = <no type information>

第二步:找到调用_imp__TerminateThread 的函数指令地址

0:000> s -b 0 L?80000000 ff 15 10 50 a7 0e

0ea00f84  ff 15 10 50 a7 0e 3b f4-e8 3f 00 03 00 8b f4 8b  ...P..;..?......

其中 ff 15 call 指令二进制码.

第三步:确定第三步找到的指令地址对应的函数名

0:000> uf 0ea00f84  

PostTripClient!CPostTripClientDetailWnd::BeginWork+0xb4 [E:\Daily_Build\code\src\Set_Nuclear\Tables\PostTripClient\PostTripClientDetailWnd.cpp @ 912]:

  912 0ea00f84 ff151050a70e    call    dword ptr [PostTripClient!_imp__TerminateThread (0ea75010)]

  912 0ea00f8a 3bf4            cmp     esi,esp

  912 0ea00f8c e83f000300      call    PostTripClient!chkesp (0ea30fd0)

  914 0ea00f91 8bf4            mov     esi,esp

这时我们就知道PostTripClientDetailWnd.cpp 912 行 

CPostTripClientDetailWnd::BeginWork调用了TerminateThread 函数,在再相应的开发人员确认,该处TerminateThread 是否有可能造成死锁问题。

对于问题二:被强杀的线程当时的调用线又是什么呢?Win7操作系统在线程被强杀后会清除调用栈数据,所以当时的调用栈就无从得知了,XP操作系统则可通过我的另一篇文章《Windbg调试技术之寻找消失的线程.doc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值