I've found a number of posts on how to create a crash dump manually when required, but what I would like to do is ensure that a crash dump is produced when a monitored application crashes.
The TechNet PROCDUMP tool can do this perfectly. What I would like to know is how I can write some code to do the same thing in a management program of my own so that I only create a dump file when an exception occurs.
My program is a service app that knows the process IDs of the programs I wish to monitor.
Just to clarify, I want to mimic what this call to PROCDUMP would do:
procdump -e someprocess.exe -w
Theoretically Windows should be able to do this job for me with DrWatson. The problem I have is that I have about 200 customer systems running that are claiming our application crashes randomly. Dr Watson doesn't seem to be confirming the fact that our applications are crashing so I've decided that I'd rather have the crash dump generation controlled by our own software.
I have managed to get my own applications to create their own dumps using __try/except and MiniDumpWriteDump() with the MiniDumpWithFullMemory type.. but I can't look at local variables etc with WinDbg, so I'm guessing this is because it has been triggered from within the application itself.. so.. another reason I would like a monitor/management type of application to do the job.
At the very least.. how can one application react to another application crashing? Do you have to install some sort of debug hook or pretend that the management program is actually a custom debugg开发者_如何学运维er?
Cheers
OK, I figured it out myself. I've written my own "debugger" that can trap the exceptions generated in a program to which my "debugger" attaches to. Now I just need to figure out how to write a minidump of that external process. The tricky part would seem to be that I have to provide an array of EXCEPTION_POINTERS.. thats the only bit I need to figure out now.
Here's an example code snippet. I hope it helps somebody else out in the future:
void WriteCrashDump( EXCEPTION_DEBUG_INFO *pExceptionInfo )
{
CONTEXT c;
memset( &c, 0, sizeof( c ) );
GetThreadContext( hThread, &c );
EXCEPTION_POINTERS ep;
ep.ContextRecord = &c;
ep.ExceptionRecord = &pExceptionInfo->ExceptionRecord;
MINIDUMP_EXCEPTION_INFORMATION minidump_exception;
minidump_exception.ThreadId = dwThreadId;
minidump_exception.ExceptionPointers = &ep;
minidump_exception.ClientPointers = true;
HANDLE hFile = CreateFile( "dump.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( hFile )
{
BOOL fSuccess;
fSuccess = MiniDumpWriteDump( hProcess, dwProcessId, hFile, MiniDumpWithFullMemory, &minidump_exception, NULL, NULL );
if( ! fSuccess )
printf( "MiniDumpWriteDump -FAILED\n" );
CloseHandle( hFile );
}
}
void DebugLoop( void )
{
DEBUG_EVENT de;
while( 1 )
{
WaitForDebugEvent( &de, INFINITE );
switch( de.dwDebugEventCode )
{
case CREATE_PROCESS_DEBUG_EVENT:
hProcess = de.u.CreateProcessInfo.hProcess;
break;
case EXCEPTION_DEBUG_EVENT:
printf( "EXCEPTION_DEBUG_EVENT\n" );
// PDS: Not interested in the fact that I have attached to it and caused a breakpoint..
if( de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT )
break;
dwProcessId = de.dwProcessId;
dwThreadId = de.dwThreadId;
WriteCrashDump( &de.u.Exception );
return;
default:
break;
}
ContinueDebugEvent( de.dwProcessId, de.dwThreadId, DBG_CONTINUE );
}
}
精彩评论