Qt-生成dump文件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a844651990/article/details/85225273

简介

  之前转载过一片文章Qt–让你的客户端崩溃之前生成dump文件,文章中介绍了如何生成crash日志,不够形象直观,如果能够生成用vs打开的dump文件那就更好了,下面开始介绍。

Qt + MSVC编译器

   这种情况其实比较简单,我们直接在qmale构建配置的地方的额外的参数项上加上"CONFIG+=force_debug_info" "CONFIG+=separate_debug_info"即可,主要用来生成pdb文件。
在这里插入图片描述
Dump转储函数Helper.h头文件:

#pragma once
#include <tchar.h>
#include <Windows.h>
#include <DbgHelp.h>

#pragma comment(lib, "user32.lib")

int GenerateMiniDump(PEXCEPTION_POINTERS pExceptionPointers)
{
	// 定义函数指针
	typedef BOOL(WINAPI * MiniDumpWriteDumpT)(
		HANDLE,
		DWORD,
		HANDLE,
		MINIDUMP_TYPE,
		PMINIDUMP_EXCEPTION_INFORMATION,
		PMINIDUMP_USER_STREAM_INFORMATION,
		PMINIDUMP_CALLBACK_INFORMATION
		);
	// 从 "DbgHelp.dll" 库中获取 "MiniDumpWriteDump" 函数
	MiniDumpWriteDumpT pfnMiniDumpWriteDump = NULL;
	HMODULE hDbgHelp = LoadLibrary(_T("DbgHelp.dll"));
	if (NULL == hDbgHelp)
	{
		return EXCEPTION_CONTINUE_EXECUTION;
	}
	pfnMiniDumpWriteDump = (MiniDumpWriteDumpT)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");

	if (NULL == pfnMiniDumpWriteDump)
	{
		FreeLibrary(hDbgHelp);
		return EXCEPTION_CONTINUE_EXECUTION;
	}
	// 创建 dmp 文件件
	TCHAR szFileName[MAX_PATH] = { 0 };
    TCHAR szVersion[] = L"DumpFile";
	SYSTEMTIME stLocalTime;
	GetLocalTime(&stLocalTime);
	wsprintf(szFileName, L"%s-%04d%02d%02d-%02d%02d%02d.dmp",
		szVersion, stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
		stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond);
	HANDLE hDumpFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_WRITE | FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
	if (INVALID_HANDLE_VALUE == hDumpFile)
	{
		FreeLibrary(hDbgHelp);
		return EXCEPTION_CONTINUE_EXECUTION;
	}
	// 写入 dmp 文件
	MINIDUMP_EXCEPTION_INFORMATION expParam;
	expParam.ThreadId = GetCurrentThreadId();
	expParam.ExceptionPointers = pExceptionPointers;
	expParam.ClientPointers = FALSE;
	pfnMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
		hDumpFile, MiniDumpWithDataSegs, (pExceptionPointers ? &expParam : NULL), NULL, NULL);
	// 释放文件
	CloseHandle(hDumpFile);
	FreeLibrary(hDbgHelp);
	return EXCEPTION_EXECUTE_HANDLER;
}

LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo)
{
	// 这里做一些异常的过滤或提示
    if (IsDebuggerPresent()) {
		return EXCEPTION_CONTINUE_SEARCH;
	}
	return GenerateMiniDump(lpExceptionInfo);
}

调用:

#include <QApplication>
#include "Helper.h"

int main(int argc, char *argv[])
{
    SetUnhandledExceptionFilter(ExceptionFilter);

    QApplication a(argc, argv);

    int *p = nullptr;
    *p = 100;

    return a.exec();
}

  给一个空指针赋值程序肯定会crash掉。
  然后我们将pdb文件和生成dump文件拷贝到源码目录:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后用VS2015打开dump文件:
在这里插入图片描述
点击设置符号路径,选择Microsoft符号服务器,点击确认,第一次的话时间会比较长,耐心等待:
在这里插入图片描述
然后点击使用仅限本机调试,然后会定位到出问题的代码的位置,会出现调试信息,非常方便:
在这里插入图片描述
在这里插入图片描述

使用google的breakpad框架

关于breakpad的框架在Qt中的使用,这篇文章讲的很好,大家可以参看下。
https://github.com/JPNaude/dev_notes/wiki/Using-Google-Breakpad-with-Qt

猜你喜欢

转载自blog.csdn.net/a844651990/article/details/85225273