当使用qml qt编写程序时常常在release版本运行会出现crash,而没有报错信息,参考网上的部分步骤使用MiniDumpWriteDump函数来捕获并生成崩溃信息,具体代码如下
#include <Windows.h>
#include <QDateTime>
#include <DbgHelp.h>
#include <QDebug>
LONG crashHandler(EXCEPTION_POINTERS *pException)
{
QString curDataTime = QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
QString dumpName = curDataTime + ".dmp";
HANDLE dumpFile = CreateFile((LPCWSTR)QString("./" + dumpName).utf16(),GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(dumpFile != INVALID_HANDLE_VALUE)
{
MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
dumpInfo.ExceptionPointers = pException;
dumpInfo.ThreadId = GetCurrentThreadId();
dumpInfo.ClientPointers = TRUE;
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),dumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);
CloseHandle(dumpFile);
}
else
{
qDebug() << "dumpFile not vaild";
}
return EXCEPTION_EXECUTE_HANDLER;
}
//防止CRT(C runtime)函数报错可能捕捉不到
void DisableSetUnhandledExceptionFilter()
{
void* addr = (void*)GetProcAddress(LoadLibrary(L"kernel32.dll"), "SetUnhandledExceptionFilter");
if(addr)
{
unsigned char code[16];
int size = 0;
code[size++] = 0x33;
code[size++] = 0xC0;
code[size++] = 0xC2;
code[size++] = 0x04;
code[size++] = 0x00;
DWORD dwOldFlag, dwTempFlag;
VirtualProtect(addr, size, PAGE_READWRITE, &dwOldFlag);
WriteProcessMemory(GetCurrentProcess(), addr, code, size, NULL);
VirtualProtect(addr, size, dwOldFlag, &dwTempFlag);
}
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)crashHandler);
// DisableSetUnhandledExceptionFilter();
QWidget w;
w.show();
return a.exec();
}
当使用注释的部分时,切换到搜狗输入法,程序崩溃报setHandlerVerifier 的函数的问题,然后QtCreator程序退出,
注释掉就没有问题。
使用测试dll程序
#ifndef CTMP_H
#define CTMP_H
#include "CTmp_global.h"
class CTMP_EXPORT CTmp
{
public:
CTmp();
};
#endif // CTMP_H
#include "ctmp.h"
CTmp::CTmp()
{
int * a = nullptr;
*a = 10;
}
导出dll 并在main.cpp里调用
#include <ctmp.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)crashHandler);
// DisableSetUnhandledExceptionFilter();
QWidget w;
w.show();
CTmp t;
return a.exec();
}
程序崩溃,生成dmp文件,后使用windbg 在C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe里 执行!analyze -v 后可以输出错误源和错误位置
PRIMARY_PROBLEM_CLASS: APPLICATION_FAULT
PROBLEM_CLASSES:
ID: [0n313]
Type: [@ACCESS_VIOLATION]
Class: Addendum
Scope: BUCKET_ID
Name: Omit
Data: Omit
PID: [Unspecified]
TID: [0x2bfc]
Frame: [0] : LDTmpAPI_1_0d!CTmp::CTmp
ID: [0n286]
Type: [INVALID_POINTER_WRITE]
Class: Primary
Scope: BUCKET_ID
Name: Add
Data: Omit
PID: [Unspecified]
TID: [0x2bfc]
Frame: [0] : LDTmpAPI_1_0d!CTmp::CTmp
ID: [0n301]
Type: [NULL_POINTER_WRITE]
Class: Primary
Scope: DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
BUCKET_ID
Name: Add
Data: Omit
PID: [0xab4]
TID: [0x2bfc]
Frame: [0] : LDTmpAPI_1_0d!CTmp::CTmp
LAST_CONTROL_TRANSFER: from 00007ff74e003d89 to 00007ff9768a1345
STACK_TEXT:
000000a0`00cff580 00007ff7`4e003d89 : 000000a0`00cff5c0 00000000`00000000 00000234`00000000 00000234`00050f02 : LDTmpAPI_1_0d!CTmp::CTmp+0x15
000000a0`00cff5a0 00007ff7`4e00de65 : 00000000`00000001 00000234`af1ba6f0 00000000`00000000 00000000`00000000 : Resize!main+0x79
000000a0`00cff630 00007ff7`4e00c91d : 00007ff7`4e000000 00000000`00000000 00000234`af127037 00007ff7`0000000a : Resize!WinMain+0xf5
000000a0`00cff6b0 00007ff7`4e00c80e : 00007ff7`4e014000 00007ff7`4e0143d0 00000000`00000000 00000000`00000000 : Resize!invoke_main+0x2d
000000a0`00cff6f0 00007ff7`4e00c6ce : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : Resize!__scrt_common_main_seh+0x12e
000000a0`00cff760 00007ff7`4e00c9a9 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : Resize!__scrt_common_main+0xe
000000a0`00cff790 00007ff9`83e77344 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : Resize!WinMainCRTStartup+0x9
000000a0`00cff7c0 00007ff9`855226b1 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0x14
000000a0`00cff7f0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21
THREAD_SHA1_HASH_MOD_FUNC: 82b48052a82ea5320cea9416cb138593ebf72144
THREAD_SHA1_HASH_MOD_FUNC_OFFSET: 5b7aef97cf339c2c24442b0f2421febb4879acc8
THREAD_SHA1_HASH_MOD: 4e0e34d10f780c90f88c2aa1ecd302fc0b4fa961
FAULT_INSTR_CODE: a00c7
FAULTING_SOURCE_LINE: e:\ld\qt\20230922\ctmp\ctmp.cpp
FAULTING_SOURCE_FILE: e:\ld\qt\20230922\ctmp\ctmp.cpp
FAULTING_SOURCE_LINE_NUMBER: 6
FAULTING_SOURCE_CODE:
2:
3: CTmp::CTmp()
4: {
5: int * a = nullptr;
> 6: *a = 10;
7: }
SYMBOL_STACK_INDEX: 0
SYMBOL_NAME: LDTmpAPI_1_0d!CTmp::CTmp+15
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: LDTmpAPI_1_0d
IMAGE_NAME: LDTmpAPI_1_0d.dll
DEBUG_FLR_IMAGE_TIMESTAMP: 667cda74
STACK_COMMAND: ~0s ; .ecxr ; kb
FAILURE_BUCKET_ID: NULL_POINTER_WRITE_c0000005_LDTmpAPI_1_0d.dll!CTmp::CTmp
BUCKET_ID: APPLICATION_FAULT_NULL_POINTER_WRITE_INVALID_POINTER_WRITE_LDTmpAPI_1_0d!CTmp::CTmp+15
FAILURE_EXCEPTION_CODE: c0000005
FAILURE_IMAGE_NAME: LDTmpAPI_1_0d.dll
BUCKET_ID_IMAGE_STR: LDTmpAPI_1_0d.dll
FAILURE_MODULE_NAME: LDTmpAPI_1_0d
BUCKET_ID_MODULE_STR: LDTmpAPI_1_0d
FAILURE_FUNCTION_NAME: CTmp::CTmp
BUCKET_ID_FUNCTION_STR: CTmp::CTmp
BUCKET_ID_OFFSET: 15
BUCKET_ID_MODTIMEDATESTAMP: 667cda74
BUCKET_ID_MODCHECKSUM: 0
BUCKET_ID_MODVER_STR: 0.0.0.0
BUCKET_ID_PREFIX_STR: APPLICATION_FAULT_NULL_POINTER_WRITE_INVALID_POINTER_WRITE_
FAILURE_PROBLEM_CLASS: APPLICATION_FAULT
FAILURE_SYMBOL_NAME: LDTmpAPI_1_0d.dll!CTmp::CTmp