我分析了转储文件以找到锁定的线程,并且我使用了!cs命令。
DebugInfo = 0x00639610
Critical section = 0x03e210c8 (+0x3E210C8)
LOCKED
LockCount = 0x1
WaiterWoken = No
OwningThread = 0x000017c8
RecursionCount = 0x1
LockSemaphore = 0x5B0
SpinCount = 0x00000000
此结果表示ThreadID 0x000017c8获得临界区。所以我听了所有线程使用〜命令找到threadID 0x000017c8。
0:000> ~
. 0 Id: 2240.1758 Suspend: 0 Teb: 7efdd000 Unfrozen
1 Id: 2240.1d90 Suspend: 0 Teb: 7efda000 Unfrozen
2 Id: 2240.16fc Suspend: 0 Teb: 7efd7000 Unfrozen
3 Id: 2240.1544 Suspend: 0 Teb: 7ef9c000 Unfrozen
4 Id: 2240.2550 Suspend: 0 Teb: 7ef99000 Unfrozen
5 Id: 2240.fd4 Suspend: 0 Teb: 7ef96000 Unfrozen
6 Id: 2240.1b08 Suspend: 0 Teb: 7ef93000 Unfrozen
7 Id: 2240.1958 Suspend: 0 Teb: 7ef90000 Unfrozen
8 Id: 2240.20e8 Suspend: 0 Teb: 7ef8d000 Unfrozen
9 Id: 2240.1bec Suspend: 0 Teb: 7ef8a000 Unfrozen
10 Id: 2240.fb4 Suspend: 0 Teb: 7ef87000 Unfrozen
11 Id: 2240.25c0 Suspend: 0 Teb: 7ef84000 Unfrozen
12 Id: 2240.15b0 Suspend: 0 Teb: 7ef81000 Unfrozen
13 Id: 2240.21a8 Suspend: 0 Teb: 7ef7b000 Unfrozen
14 Id: 2240.1fcc Suspend: 0 Teb: 7ef78000 Unfrozen
但是,没有threadID 0x000017c8。这个转储文件发生了什么?我怎样才能找到线程ID 0x000017c8?
答案 0 :(得分:2)
Kjell Gunnar是对的:线程17c8
因任何原因终止了。
这不仅可以在关键部分发生,也可以在其他同步对象中发生。在我的高级调试培训中,我为参与者提供了ManualResetEvent
的类似情况的转储。
这是来源:
#include "stdafx.h"
#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <iostream>
HANDLE threadA;
HANDLE threadB;
HANDLE eventB;
class WorkItem
{
public:
virtual void Initialize()
{
}
};
unsigned int __stdcall initializeWorkitems(void* param)
{
try
{
// Initialize workitems
WorkItem **items = new WorkItem*[2];
items[0] = new WorkItem();
items[1] = NULL;
for (int i = 0; i<2; i++)
{
items[i]->Initialize();
}
// Signal event for second thread to work on work items
SetEvent(eventB);
}
catch(...)
{
// Don't do this
}
return 0;
}
unsigned int __stdcall processWorkitems(void* param)
{
// Wait for work item initialization to complete
WaitForSingleObject(eventB, INFINITE);
// Work on workitems
Sleep(100);
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
eventB = CreateEvent(0, 0, 0, 0);
threadA = (HANDLE)_beginthreadex(0, 0, &initializeWorkitems, (void*)0, 0, 0);
threadB = (HANDLE)_beginthreadex(0, 0, &processWorkitems, (void*)0, 0, 0);
WaitForSingleObject(threadA, INFINITE);
WaitForSingleObject(threadB, INFINITE);
CloseHandle(threadA);
CloseHandle(threadB);
CloseHandle(eventB);
return 0;
}
在进程挂起时创建转储。分析应该导致与您的关键部分相当的案例。 threadA
终止了静默,在catch(...)
块中吃了一个NullPointerException,从而永远不会释放手动重置事件。