Generate a dump file of the program crash and use windbg to debug

1. Purpose

 

Sometimes the program crashes at the client, and your program does not have any effective log log to record the details of the crash, which is really a very troublesome thing.

You have to repeatedly understand the operation content from the customer and hope to reproduce it here. This process is very painful to think about. .

Using the following method, you can generate your own dump file when the program crashes, record some useful information when the program crashes, and generally help you easily find the wrong place.

 

2. Principle

 

Simply put, when the windows program crashes, a dialog box will be called to display some useless information.

Under XP:

In WIN7 :

①Set the callback function when it crashes.

There is a method that allows us to set the callback function to be executed first when the program crashes, which can play our own dialog box, such as allowing the user to enter some useful content and send it to us.

This function is SetUnhandledExceptionFilter. 

prototype:

WINBASEAPI
LPTOP_LEVEL_EXCEPTION_FILTER
WINAPI
SetUnhandledExceptionFilter(
    __in_opt LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
    );

Its parameter is the callback function you want to set: PTOP_LEVEL_EXCEPTION_FILTER

typedef LONG (WINAPI *PTOP_LEVEL_EXCEPTION_FILTER)(
    __in struct _EXCEPTION_POINTERS *ExceptionInfo
    );
typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER;


When the system calls your callback function, it will pass you a structure representing exception information: EXCEPTION_POINTERS

typedef struct _EXCEPTION_POINTERS {
    PEXCEPTION_RECORD ExceptionRecord;
    PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;


What we need to do now is to record in a dump file according to the information given to us by the system in the callback function . For us to use windbg analysis.

Through the return value of the SetUnhandledExceptionFilter function, we can choose to end the program directly without popping the original default dialog box after the callback, or play the default and then end the program without popping the dialog box to continue execution.

as follows:

 

#define EXCEPTION_EXECUTE_HANDLER 1 //After the callback ends, the original default dialog box will not be played, and the program will end directly
#define EXCEPTION_CONTINUE_SEARCH 0 //Play the default and end the program again
#define EXCEPTION_CONTINUE_EXECUTION -1 //Continue to execute




 

 

② Output the crash information to the dump file in the callback function.

 

Writing content to the dump file uses an API: MiniDumpWriteDump.

In the DbgHelp.h header file, and the DbgHelp.lib library needs to be included.

#include <DbgHelp.h>
#pragma comment(lib, "dbghelp.lib")

Function form:

BOOL
WINAPI
MiniDumpWriteDump (
    __in HANDLE hProcess,
    __in DWORD ProcessId,
    __in HANDLE hFile,
    __in MINIDUMP_TYPE DumpType,
    __in_opt PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
    __in_opt PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
    __in_opt PMINIDUMP_CALLBACK_INFORMATION CallbackParam
    );

illustrate:

hProcess - Process handle, which can be obtained using GetCurrentProcess().
ProcessID - Process ID, GetCurrentProcessId().

hFile - The dump file handle we created.

DumpType—— dump type, generally fill in MiniDumpNormal, please refer to DbgHelp.h and MSDN for details.

ExceptionParam——  1)ThreadId:GetCurrentThreadId()。

2) ExceptionPointers: the parameters of the callback function.

3) ClientPointers: generally fill in TRUE.

UserStreamParam - generally set to NULL.

CallbackParam - generally set to NULL.

 

 

3. Demo program code

 

If it is a release version, you need to set the generate debug file and generate map file in the project configuration.

As shown in the figure:

 

win32 console program:

#include "stdafx.h"
#include <windows.h>
#include <DbgHelp.h>
#pragma comment(lib, "dbghelp.lib")

//our callback function
LONG __stdcall ExceptCallBack( EXCEPTION_POINTERS *pExcPointer)
{
	MessageBox(NULL,"The program crashed! The relevant information is recorded in the C:\\Test.dmp file.",NULL,MB_OK);

	//create dump file
	HANDLE hFile = CreateFile("C:\\Test.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL ,NULL);
	
	//Write the current program crash related information to the file
	MINIDUMP_EXCEPTION_INFORMATION loExceptionInfo;
	loExceptionInfo.ExceptionPointers = pExcPointer;
	loExceptionInfo.ThreadId = GetCurrentThreadId();
	loExceptionInfo.ClientPointers = TRUE;
	MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),hFile, MiniDumpNormal, &loExceptionInfo, NULL, NULL);
	CloseHandle(hFile);

	return EXCEPTION_EXECUTE_HANDLER;
}

void WrongFun()
{
	//crash
    int * p = NULL;
	*p = 1;
}

int _tmain(int argc, _TCHAR* argv[])
{
	//Set the crash callback function
	SetUnhandledExceptionFilter(ExceptCallBack);

	WrongFun();

	return 0;
}


4, the effect.

After the crash, a dialog box pops up:

After that, the crash dialog box that comes with windows is no longer adjusted. The program ends.

 

5. Use windbg to view dmp files

 

Use the windbg menu File->Open Crash File to open the Test.dmp file, and enter the "!analyze -v" command in the edit box below to perform automatic analysis.

After a while, some content will appear, roughly found as follows:

You can see some details of the program crash and even the code.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326451194&siteId=291194637