I can get this working on Windows 2000 and ME but not 98 and 98SE. I'm using
the latest dbghelp.dll from the released VC .NET. I've also tried the
dbghelp supplied with the latest Win32 debugging tools.
MiniDumpWriteDump returns 0 and fails to write anything to the file or set
an error code on Windows 98 and Windows 98SE.
The same thing happens even when calling it with no exception info well
before the program crashes. There don't appear to be an obvious API failures
around or inside MiniDumpWriteDump
I've tried calling it from a separate thread and having the main thread wait
for it to complete. I've tried setting the ClientPointers to TRUE and FALSE.
I've also tried using a callback so that it ignores the spawned thread which
is calling MiniDumpWriteDump and also tried suspending the main thread while
the dumping thread is in action.
I'm currently basing the code on the crash handler described at
http://www.wintellect.com/resources/newsletters/nov2001.asp with some
modifications to make sure it doesn't call any Unicode API's.
Does dbghelp.dll have dependencies on other Windows components? It imports
msvcrt, kernel32, version, advapi32, rpcrt4. It does import GetProcAddress
but this doesn't seem to get called by dbghelp before it fails. Could it be
dependent on newer behaviour in msvcrt? An update to IE6 hasn't made any
difference.
Is dbghelp unable to minidump its own process on 95 or 98? I can't see
anything in the documentation or on the web that suggests I have to do
anything different for different OS's.
Alternatively do I need to launch another process from the exception handler
and dump from the new process? In theory this might use a lot of stack space
but in practice stack overflow and stack pointer corruption errors never
even get as far as the unhandled exception filter. The app probably throws
another exception while handling the first and just dies.
I'd be very grateful for any suggestions.
Thanks,
Mike Copperwhite
If a valid process id of another active process is specified on the command
line then this code always succeeds.
If dumping its own process then MiniDumpWriteDump intermittently fails and
returns FALSE on Win 98 and 98 SE.
#include <windows.h>
#include <dbghelp.h>
#include <stdlib.h>
static void ErrorMsg(const char* msg)
{
MessageBox(NULL,msg,"Dumper",MB_OK);
}
int main(int argc, char* argv[])
{
char *endChar=NULL;
DWORD processId = GetCurrentProcessId();
if (argc==2) {
DWORD parsedId = strtoul(argv[1],&endChar,10);
if (endChar == argv[1]) {
ErrorMsg("Bad process Id argument");
} else {
processId = parsedId;
}
}
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,processId);
if (!hProcess) {
ErrorMsg("Can't open process");
} else {
HANDLE hfile = CreateFile("User.dmp",GENERIC_READ | GENERIC_WRITE,0,NULL,
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (!hfile) {
ErrorMsg("Can't open file");
} else {
BOOL success =
MiniDumpWriteDump(hProcess,processId,hfile,MiniDumpNormal,NULL,NULL,NULL);
if (!success) {
ErrorMsg("MiniDumpWriteDump failed");
}
CloseHandle(hfile);
}
CloseHandle(hProcess);
}
return 0;
}
Your code looks fine. Instead of doing an OpenProcess, you might want to
try the following:
if (!MiniDumpWriteDump(GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
NULL,
NULL,
NULL))
{
printf("MiniDumpWriteDump failed with error code : %d\n",
GetLastError());
}
Also, on the file, you might want to include FILE_SHARE_READ like the
following:
HANDLE hfile = CreateFile("User.dmp",GENERIC_READ |
GENERIC_WRITE,FILE_SHARE_READ,NULL,
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
Best regards,
Raghavendra Rao
Microsoft
This posting is provided "AS IS" with no warranties, and confers no rights.
Thanks for the reply and the suggestions.
The code still fails most of the time when using GetCurrentProcess(),
GetCurrentProcessId() and the FILE_SHARE_READ flag. I've included my code at
the end in case I've done something else really lame.
I've tried using Dbghelp version 5.1.2600.0 (from XP) and 4.0.18.0 (from
debugging tools)
Code succeeds on Win2k, ME.
Mostly fails on Win 98 v4.10.2222 A with IE 6.0.2600
Could call MiniDumpWriteDump until it succeeds with a limit on the number of
attempts but I've decided to go with dumping from another process for
safetey. The minidumping app can also run the main application as a debuggee
and generate minidumps from crashes like stack corruption which often don't
get as far as the exception handler.
===================
#include "stdafx.h"
#include <dbghelp.h>
#include <stdlib.h>
static void ErrorMsg(const char* msg)
{
MessageBox(NULL,msg,"Dumper",MB_OK);
}
int main(int argc, char* argv[])
{
char *endChar=NULL;
DWORD processId = GetCurrentProcessId();
HANDLE hProcess = GetCurrentProcess();
if (argc==2) {
DWORD parsedId = strtoul(argv[1],&endChar,10);
if (endChar == argv[1]) {
ErrorMsg("Bad process Id argument");
} else {
processId = parsedId;
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,processId);
}
}
if (INVALID_HANDLE_VALUE == hProcess) {
ErrorMsg("Can't open process");
} else {
HANDLE hfile = CreateFile("User.dmp",GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (!hfile) {