windbg 调试线程死锁

本文讲述了作者在工作中遇到线程死锁和crash的问题,通过windbg调试定位到网络通信类存在错误,并解决。同时分享了一个windbg分析死锁的案例,展示如何使用~*kb命令查看线程状态,揭示了线程等待的对象和代码位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

           最近工作遇到很多问题,尤其是线程死锁,crash这样的bug。 前几天遇到的一个crash , 用windbg调试的时候的发现每次报错的位置都不一样,仿佛是随机的,后来找一个前辈来帮忙分析,也没有找到问题。后来通过代码屏蔽的方法,发现是我的网络通信类有问题,于是重新写了通信类,总算是表面上解决了问题。自己对windbg也一知半解的,所以今天就特意找了个死锁的例子,用windbg来分析。

          偷懒了 ,直接从网上找个一段死锁的代码,如下:

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <iostream>
CRITICAL_SECTION g_cs1;
CRITICAL_SECTION g_cs2;


DWORD WINAPI Worker(LPVOID lpParam)
{
if((int)lpParam == 7)
{
  while(1)
  {
   printf("Worker[%x]: 就我活着\n", GetCurrentThreadId());
   Sleep(10000);
  }
}
else
{
  printf("Worker[%x]:准备进入临界段---g_cs2\n", GetCurrentThreadId());
  EnterCriticalSection(&g_cs2);
  printf("Worker[%x]:成功进入临界段---g_cs2\n", GetCurrentThreadId());


  printf("Worker[%x]:准备进入临界段---g_cs1\n", GetCurrentThreadId());
  EnterCriticalSection(&g_cs1);
  printf("Worker[%x]:成功进入临界段---g_cs1\n", GetCurrentThreadId());
}
return 0;
}


int _tmain(int argc, _TCHAR* argv[])
{
InitializeCriticalSection(&g_cs1);
InitializeCriticalSection(&g_cs2);
printf("main[%x]: 准备进入临界段 g_cs1\n", GetCurrentThreadId());
EnterCriticalSection(&g_cs1);
printf("main[%x]: 成功进入临界段 g_cs1\n", GetCurrentThreadId());
HANDLE hThread[8];


for(int i=0; i<8; i++)
{
  hThread[i] = CreateThread(NULL, 0, Worker, (LPVOID)i, 0, NULL);
}


printf("main[%x]: 准备进入临界段 g_cs2\n", GetCurrentThreadId());
EnterCriticalSection(&g_cs2);
printf("main[%x]: 成功进入临界段 g_cs2!\n", GetCurrentThreadId());
return 0;

}

编译运行后效果如下:

由于主线程率先进入了临界区1不离开,  就导致其他无法进入临界区1.   线程15dc虽然请求到临界区2,但是却无法进入临界区1.;   主线程和 15dc都再等待对方的资源,结果导致死锁。现在用windbg附加上进程, 输入命令 ~*kb 查看所有线程

发现有8个线程 都有类似的输出:(因为第七个个线程是不进入临界区的)

0095feb4 77c68cd8 00000000 00000000 77c522a0 ntdll!ZwWaitForSingleObject+0x15

ntdll!ZwWaitForSingleObject+0x15 这里便是问题的关键,我们可以看到所有的线程都在等待0x15,   难道他们都在等待0x15, 其实这里仅供参考。我从资料上看到说得是这个对象很可能是windbg给出了错误的信息

紧接着的输出变给出了当前线程运行到代码的哪一行:

0095fef4 761c339a 00000000 0095ff40 77c69ef2 TestDeadLock!Worker+0x7d [e:\projects\testdeadlock\testdeadlock\testdeadlock.cpp @ 31]

testdeadlock.cpp 文件第 31行。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值