High-Level Design Issues with DeadlockDetection

[Previous] [Next]

I had to figure out how to implement DeadlockDetection given the preceding requirements. I first needed to determine what functions I needed to monitor so that I could report the complete deadlock trace. Table 12-1 lists all the functions, grouped by type, I decided I needed to monitor to implement DeadlockDetection.

After pondering the problem of how to collect the information I needed to satisfy the first four requirements, I realized that I was going to have to intercept (or hook) the functions in Table 12-1 to record the acquisition and release of synchronization objects. Hooking functions isn't a trivial task, and I'll explain how I implemented the code in the section "Hooking Imported Functions" later in this chapter. The one constraint that hooking imported functions imposed on DeadlockDetection is that the code for DeadlockDetection must reside in a DLL because the hooks apply only to the address space in which they're created. This constraint means that the user must load the DeadlockDetection DLL into her address space, a requirement that isn't too harsh given the benefits. As a DLL, the utility would integrate easily with a user program, a condition specified in requirement 7 in the list in the preceding section.

Gathering the information to satisfy requirements 1 through 4 follows as a direct consequence of choosing the in-process function hooking approach. This approach means that each of the multithreading and synchronization functions will be calling directly into the DeadlockDetection code with all the information I need.

Table 12-1 Functions That DeadlockDetection Monitors

TypeFunction
Thread-related functions CreateThread
ExitThread
SuspendThread
ResumeThread
TerminateThread
Critical-section functions InitializeCriticalSection
InitializeCriticalSectionAndSpinCount
DeleteCriticalSection
EnterCriticalSection
LeaveCriticalSection
SetCriticalSectionSpinCount
TryEnterCriticalSection
Mutex functions CreateMutexA
CreateMutexW
OpenMutexA
OpenMutexW
ReleaseMutex
Semaphore functions CreateSemaphoreA
CreateSemaphoreW
OpenSemaphoreA
OpenSemaphoreW
ReleaseSemaphore
Event functions CreateEventA
CreateEventW
OpenEventA
OpenEventW
PulseEvent
ResetEvent
SetEvent
Blocking functions WaitForSingleObject
WaitForSingleObjectEx
WaitForMultipleObjects
WaitForMultipleObjectsEx
MsgWaitForMultipleObjects
MsgWaitForMultipleObjectsEx
SignalObjectAndWait
Special functions CloseHandle
ExitProcess
GetProcAddress

Making DeadlockDetection as lightweight as possible (requirement 5) was a tough condition to satisfy. I tried to code efficiently, but efficient code went only so far toward fulfilling the goal I set out to achieve. Figuring that you would know best what types of synchronization objects you're using in your program, I grouped the object types so that you can specify just those functions you want to hook. For example, if you're concerned only about deadlock problems on mutexes, you can process only mutex functions.

To make DeadlockDetection even more useful, you can specify, on the fly, which sets of synchronization object functions you want to watch. You can also turn DeadlockDetection on and off as many times as needed. You might even want to give your application an accelerator key or a special menu option that toggles the entire DeadlockDetection system. Allowing this narrow scope meets requirement 5 and helps with requirement 7.

The only requirement left is 6: making the output processing as extensible as possible. I wanted to give you the ability to slice and dice the output, rather than force you to make do with some arbitrary, hard-coded format. By keeping the main hooking and processing separate from the output code, I can achieve greater code reuse because the only part being changed, the output side, is much easier to develop than the core side. I named the output portions DeadlockDetection extensions, or DeadDetExt for short. A DeadDetExt is simply a DLL that has several exported functions that DeadlockDetection looks for and calls when appropriate.

Now it's time to explain how to use DeadlockDetection. If you understand the requirements I set out and understand how to use this utility, you'll find it easier to see how I implemented it.



Debugging Applications
Debugging Applications for MicrosoftВ® .NET and Microsoft WindowsВ® (Pro-Developer)
ISBN: 0735615365
EAN: 2147483647
Year: 2000
Pages: 122
Authors: John Robbins

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net