Discussion:
How to get exhaustive information about the application when it crashes.
(too old to reply)
w***@hotmail.com
2008-02-29 01:48:39 UTC
Permalink
Hello, everyone:

My company have developed an application launched in Release version
with its relative PDB files. We, however, have long been puzzled by
complaints from the guests when the application sometimes crashed.
Unfortunately, we have no good idea how to trace the exact causes of
the problems, for it's not a practical way for us to debug on their
factory. All we could get is the bits and pieces information from the
operator, which is not enough at all. We want to get, when crashed,
which functions is called, what the parameters they have, and so on.
Could you point out a way to us on how to get exhaustive information
about the application when it crashes? I will appreciate any your
advices. Thanks in advanced!
Jochen Kalmbach [MVP]
2008-02-29 07:11:11 UTC
Permalink
Hi wuguangwen734!
Post by w***@hotmail.com
My company have developed an application launched in Release version
with its relative PDB files. We, however, have long been puzzled by
complaints from the guests when the application sometimes crashed.
Unfortunately, we have no good idea how to trace the exact causes of
the problems, for it's not a practical way for us to debug on their
factory. All we could get is the bits and pieces information from the
operator, which is not enough at all. We want to get, when crashed,
which functions is called, what the parameters they have, and so on.
Could you point out a way to us on how to get exhaustive information
about the application when it crashes? I will appreciate any your
advices. Thanks in advanced!
Write a MiniDump, when your app crashes...

For example:
static LONG __stdcall CrashHandlerExceptionFilter(
EXCEPTION_POINTERS* pExPtrs)
{
if (pExPtrs->ExceptionRecord->ExceptionCode ==
EXCEPTION_STACK_OVERFLOW)
{
static char MyStack[1024*128]; // be sure that we have enought
space...
// it assumes that DS and SS are the same!!! (this is the case for
Win32)
// change the stack only if the selectors are the same (this is the
case for Win32)
//__asm push offset MyStack[1024*128];
//__asm pop esp;
__asm mov eax,offset MyStack[1024*128];
__asm mov esp,eax;
}


WriteMiniDumps("minidump-file.dmp", pExPtrs);
}


static int WriteMiniDump(
const char *szFN,
struct _EXCEPTION_POINTERS *ep)
{
int ret = -1; // failed
HANDLE hFile;


if (hdbghelpmod == NULL)
hdbghelpmod = LoadLibrary("dbghelp.dll");
if (hdbghelpmod == NULL)
return ret;


if (pMDWD == NULL)
pMDWD = (tMDWD) GetProcAddress(hdbghelpmod, "MiniDumpWriteDump");
if (pMDWD == NULL)
return ret;



hFile = CreateFile(szFN,
GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);


if (hFile != INVALID_HANDLE_VALUE)
{
MINIDUMP_EXCEPTION_INFORMATION stMDEI;
stMDEI.ThreadId = GetCurrentThreadId();
stMDEI.ExceptionPointers = ep;
stMDEI.ClientPointers = TRUE;
// try to create an miniDump:
if (pMDWD(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
&stMDEI,
NULL,
NULL
) == FALSE)
{
printf("Minidump failed! 0x8.8X\n", GetLastError());
OutputDebugString("Minidump failed!");
}
else
ret = 0; // suceeded
CloseHandle(hFile);
}
return ret;
}

int _tmain()
{
SetUnhandledExceptionFilter(CrashHandlerExceptionFilter);

char *szTest = NULL;
strcpy(szTest, "Hallo Welt"); // BANG...
}


See also:
http://blog.kalmbachnet.de/?postid=75
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Ondrej Spanel
2008-02-29 10:18:19 UTC
Permalink
Post by Jochen Kalmbach [MVP]
Write a MiniDump, when your app crashes...
Another way, if the customer is using WinXP or newer OS, is to register
for Windows Error Reporting and the get crashes they can (and often do)
send to Microsoft.

This requires some administrative work and some money to get the Digital
ID and to register on the WinQual, but it does not require any changes
at the application side at all, and it is often much easier for the
customer, as he does not have to locate the minidumps for you.

Cheers
Ondrej
Post by Jochen Kalmbach [MVP]
Hi wuguangwen734!
Post by w***@hotmail.com
My company have developed an application launched in Release version
with its relative PDB files. We, however, have long been puzzled by
complaints from the guests when the application sometimes crashed.
Unfortunately, we have no good idea how to trace the exact causes of
the problems, for it's not a practical way for us to debug on their
factory. All we could get is the bits and pieces information from the
operator, which is not enough at all. We want to get, when crashed,
which functions is called, what the parameters they have, and so on.
Could you point out a way to us on how to get exhaustive information
about the application when it crashes? I will appreciate any your
advices. Thanks in advanced!
Write a MiniDump, when your app crashes...
static LONG __stdcall CrashHandlerExceptionFilter(
EXCEPTION_POINTERS* pExPtrs)
{
if (pExPtrs->ExceptionRecord->ExceptionCode ==
EXCEPTION_STACK_OVERFLOW)
{
static char MyStack[1024*128]; // be sure that we have enought
space...
// it assumes that DS and SS are the same!!! (this is the case for
Win32)
// change the stack only if the selectors are the same (this is the
case for Win32)
//__asm push offset MyStack[1024*128];
//__asm pop esp;
__asm mov eax,offset MyStack[1024*128];
__asm mov esp,eax;
}
WriteMiniDumps("minidump-file.dmp", pExPtrs);
}
static int WriteMiniDump(
const char *szFN,
struct _EXCEPTION_POINTERS *ep)
{
int ret = -1; // failed
HANDLE hFile;
if (hdbghelpmod == NULL)
hdbghelpmod = LoadLibrary("dbghelp.dll");
if (hdbghelpmod == NULL)
return ret;
if (pMDWD == NULL)
pMDWD = (tMDWD) GetProcAddress(hdbghelpmod, "MiniDumpWriteDump");
if (pMDWD == NULL)
return ret;
hFile = CreateFile(szFN,
GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
MINIDUMP_EXCEPTION_INFORMATION stMDEI;
stMDEI.ThreadId = GetCurrentThreadId();
stMDEI.ExceptionPointers = ep;
stMDEI.ClientPointers = TRUE;
if (pMDWD(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
&stMDEI,
NULL,
NULL
) == FALSE)
{
printf("Minidump failed! 0x8.8X\n", GetLastError());
OutputDebugString("Minidump failed!");
}
else
ret = 0; // suceeded
CloseHandle(hFile);
}
return ret;
}
int _tmain()
{
SetUnhandledExceptionFilter(CrashHandlerExceptionFilter);
char *szTest = NULL;
strcpy(szTest, "Hallo Welt"); // BANG...
}
http://blog.kalmbachnet.de/?postid=75
JG
2008-03-30 13:07:19 UTC
Permalink
Post by Jochen Kalmbach [MVP]
Write a MiniDump, when your app crashes...
Greetings Jochen
My blog about Win32 and .NET
http://blog.kalmbachnet.de/
(From amateur programmer) this looks interesting, does one have to
implement Throw and Catch into all of you code to successfully execute
the mini dump?
Is this a better (or easier) way than using the Microsoft tools such as
Userdump.exe and Windbg.exe ?
Jochen Kalmbach [MVP]
2008-03-30 13:41:59 UTC
Permalink
Hi JG!
Post by JG
Is this a better (or easier) way than using the Microsoft tools such as
Userdump.exe and Windbg.exe ?
Easier is WinQual (winqual.microsoft.com).

If you just want minidumps which you can debug at "home", then this is
an option.
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
w***@hotmail.com
2008-04-03 07:06:57 UTC
Permalink
On Feb 29, 3:11 pm, "Jochen Kalmbach [MVP]" <nospam-
Post by Jochen Kalmbach [MVP]
Write a MiniDump, when your app crashes...
Hi,Jochen,

Thanks for your advice. I have tried the method you suggested on a
platform of VC 2005, Windows XP Professional. Unfortunately, it
doesn't work. After inserting breakpoint in
functions,i.e.,CrashHandlerExceptionFilter and WriteMiniDump, I run
the application within DEBUG version. No mater how many times I
tried, the exception-filter-function could not get a chance to be
invoked. When it crashed, it stopped at a instruction ' mov
[edi],edx ', as follows, which was exstracted from strcat.asm file.
main_loop: ; edx contains
first dword of sorc string
mov [edi],edx ; store
one more dword
add edi,4 ; kick
dest pointer

What's more, if I didn't call to SetUnhandledExceptionFilter in
_tmain function, the behaviour was just as the same.
For completion reason, I paste the code written out of your
suggestion:

#include "stdafx.h"
#include <stdlib.h>
#include <tchar.h>
#include <Windows.h>
#include <ImageHlp.h>
//#include <DbgHelp.h>



typedef BOOL (WINAPI *pFun_MiniDumpWriteDump)(
HANDLE hProcess,
DWORD ProcessId,
HANDLE hFile,
MINIDUMP_TYPE DumpType,
PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
PMINIDUMP_CALLBACK_INFORMATION CallbackParam
);

static HMODULE hdbghelpmod = NULL;
static pFun_MiniDumpWriteDump pMDWD = NULL;

static int WriteMiniDump( const wchar_t *szFN, struct
_EXCEPTION_POINTERS *ep)
{
int ret = -1; // failed
HANDLE hFile;

if (hdbghelpmod == NULL)
hdbghelpmod = LoadLibrary(_T("dbghelp.dll"));
if (hdbghelpmod == NULL)
return ret;


if (pMDWD == NULL)
pMDWD = (pFun_MiniDumpWriteDump) GetProcAddress(hdbghelpmod,
("MiniDumpWriteDump"));
if (pMDWD == NULL)
return ret;


hFile = CreateFile(szFN,
GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);


if (hFile != INVALID_HANDLE_VALUE)
{
MINIDUMP_EXCEPTION_INFORMATION stMDEI;
stMDEI.ThreadId = GetCurrentThreadId();
stMDEI.ExceptionPointers = ep;
stMDEI.ClientPointers = TRUE;
// try to create an miniDump:
if
(pMDWD(GetCurrentProcess(),GetCurrentProcessId(),hFile,MiniDumpNormal,&stMDEI,
NULL, NULL ) == FALSE)
{
printf("Minidump failed! 0x8.8X\n", GetLastError());
OutputDebugString(_T("Minidump failed!"));
}
else
ret = 0; // suceeded
CloseHandle(hFile);
}
return ret;
}

static LONG __stdcall CrashHandlerExceptionFilter(EXCEPTION_POINTERS*
pExPtrs)
{
if (pExPtrs->ExceptionRecord->ExceptionCode ==
EXCEPTION_STACK_OVERFLOW)
{
static char MyStack[1024*128]; // be sure that we have enought
space...
// it assumes that DS and SS are the same!!! (this is the case for
Win32)
// change the stack only if the selectors are the same (this is the
case for Win32)
//__asm push offset MyStack[1024*128];
//__asm pop esp;
__asm mov eax,offset MyStack[1024*128];
__asm mov esp,eax;
}

WriteMiniDump(_T("minidump-file.dmp"), pExPtrs);
}

int _tmain(int argc, _TCHAR* argv[])
{
SetUnhandledExceptionFilter(CrashHandlerExceptionFilter);

char *szTest = NULL;
strcpy(szTest, "Hallo Welt"); // BANG...
}



I'm looking forward for your response, again.

Regards,
Simon
Jochen Kalmbach [MVP]
2008-04-03 17:04:19 UTC
Permalink
Hi wuguangwen734!
Post by w***@hotmail.com
Unfortunately, it
doesn't work. After inserting breakpoint in
functions,i.e.,CrashHandlerExceptionFilter and WriteMiniDump, I run
The breakpoint will *never* be hit!
The reason is simple: If your program runs under a debugger, the
unhandled exception will be handled by the debugger!!!
So your handler will never be called!
Post by w***@hotmail.com
I'm looking forward for your response, again.
Let it run *outside* from the debugger (start it with the explorer!).
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
w***@hotmail.com
2008-04-07 01:58:03 UTC
Permalink
Hi,Jochen,

I'm grateful to you for your help.
Post by Jochen Kalmbach [MVP]
Let it run *outside* from the debugger (start it with the explorer!).
It really works within Release Version. Nevertheless, I started
it within Debug Version with the Explorer, there was no minidump-
file.dmp file generated. What's the distinction between the two ways?

I examined the minidump-file.dmp file using Ultra-Edit32.exe and
got nothing. The file was fairly unreadable. Could you please tell me
how to make it more "beautiful"? What's more, as far as I could see,
the minidump-file.dmp file seemed to have no information about the
calling stack. I mean I wanna get the points causing the application
crashes.

Regards,
Simon
Jochen Kalmbach [MVP]
2008-04-07 15:02:13 UTC
Permalink
Hi wuguangwen734!
Post by w***@hotmail.com
I examined the minidump-file.dmp file using Ultra-Edit32.exe and
got nothing. The file was fairly unreadable. Could you please tell me
how to make it more "beautiful"?
The easiest way is "double-click" on it in the explorer.


A more sophisticated way:

Install "Debugging Tools for Windows"
Open WinDbg
Open crash dump...
Setup correct PDB/EXE path
Use MS symbol server (.symfix+)
Type "!analyze -v"
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Loading...