[原]调试TerminateThread导致的死锁

本文介绍了在项目中遇到的由TerminateThread导致的死锁问题,详细分析了问题的重现方法、代码示例及解决思路。通过调试工具揭示了线程在被终止前持有关键段导致的死锁现象,提醒开发者避免随意使用TerminateThread。
摘要由CSDN通过智能技术生成

这是继上一篇 [原]调试DLL卸载时的死锁 后的又一篇使用windbg调试死锁的文章。希望能对大家有所帮助。

前言

之前项目里的一个升级程序偶尔会死锁,查看dump后发现是死在了ShellExecuteExW里。经验少,不知道为什么,于是在高端调试论坛里发帖求助,链接如下 http://advdbg.org/forums/6520/ShowPost.aspx

根据张银奎老师的描述可知,应该是拥有关键段的线程意外结束了。仔细检查项目中的代码,发现程序中有使用TerminateThread()来强制杀线程的代码。很可疑,于是写了一个测试程序,还原了这个问题。

问题重现

重现方法

主程序会加载一个DLL,并调用该DLL的导出函数创建一个线程,然后调用TerminateThread()强制杀死这个线程,然后调用RunProcess()(内部封装了对ShellExecuteEx()的调用)执行一个新进程,会卡死在ShellExecuteEx()。为了让问题更容易重现,特地在DllMain()的参数ul_reason_for_callDLL_THREAD_DETACH时,强制睡眠了5秒。

代码摘录

主工程 testTerminateThread

//testTerminateThread.cpp
#include "stdafx.h"
#include "windows.h"
#include "process.h"

typedef HANDLE (*pfnGenerateThread)();

HANDLE RunProcess(const TCHAR* app_name, const TCHAR* cmd)
{
  SHELLEXECUTEINFO shex = {sizeof(SHELLEXECUTEINFO)};
  shex.fMask = SEE_MASK_NOCLOSEPROCESS;
  shex.lpVerb = _T("open");
  shex.lpFile = app_name;
  shex.lpParameters = cmd;
  shex.lpDirectory = NULL;
  shex.nShow = SW_NORMAL;

  if (!::ShellExecuteEx(&shex))
  {
    return INVALID_HANDLE_VALUE;
  }

  return shex.hProcess;
}

int _tmain(int argc, _TCHAR* argv[])
{
  while ( 1 )
  {
    HMODULE hModule = LoadLibrary(_T("test
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值