Jak*_*rde 6 c++ windows crash multithreading exception-handling
我想为我的Qt应用程序制作崩溃/异常处理程序.我已经有处理程序工作(不包括在下面的代码中).问题是,在Windows上,如果飞机坠毁在同一个线程在那里occures,它只能signal()和std::set_terminate()被调用.
在Linux上,它似乎默认适用于所有线程.
有没有办法让它适用于Windows上的所有应用程序线程?
#include "mainwindow.h"
#include <QApplication>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <exception>
void seg_handler(int sig)
{
// Crash/exception handling code
// ...
exit(1);
}
void std_handler( void ) {
seg_handler(1);
}
int main(int argc, char *argv[]) {
signal(SIGSEGV, seg_handler);
std::set_terminate( std_handler );
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Run Code Online (Sandbox Code Playgroud)
经过大量研究,加上我对 Windows 操作系统缺乏了解,我终于找到了一个可行的解决方案,可以自动为新线程设置终止函数。
诀窍是创建一个 dll 来处理崩溃/异常。在你的dll中实现保留的DllMain()函数。每次有新线程或进程附加到主进程时,此函数都会收到通知。该fdwReason参数保存有关事件的信息。
DLL_THREAD_ATTACHDLL_PROCESS_ATTACH在 dll 中实现终止处理程序,并为启动的每个线程或进程调用signal()和。std::set_terminate()
BOOL WINAPI DllMain(
_In_ HINSTANCE hinstDLL,
_In_ DWORD fdwReason,
_In_ LPVOID lpvReserved) {
if (fdwReason==DLL_THREAD_ATTACH) {
signal(SIGSEGV, seg_handler);
std::set_terminate( std_handler );
}
if (fdwReason==DLL_PROCESS_ATTACH) {
signal(SIGSEGV, seg_handler);
std::set_terminate( std_handler );
}
return TRUE;
}
Run Code Online (Sandbox Code Playgroud)
我的处理程序如下所示:
#include <windows.h>
#include "StackWalker.h"
#include <signal.h>
#include <DbgHelp.h>
#include <iostream>
#include <qdebug.h>
void seg_handler(int sig) {
// Simple callstack
unsigned int i;
void * stack[ 100 ];
unsigned short frames;
SYMBOL_INFO * symbol;
HANDLE process;
process = GetCurrentProcess();
SymInitialize( process, NULL, TRUE );
frames = CaptureStackBackTrace( 0, 100, stack, NULL );
symbol = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );
symbol->MaxNameLen = 255;
symbol->SizeOfStruct = sizeof( SYMBOL_INFO );
for( i = 0; i < frames; i++ ) {
SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );
printf( "%i: %s - 0x%0X\n", frames - i - 1, symbol->Name, symbol->Address );
}
free( symbol );
// Detailed callstack/crashinfo
StackWalker sw;
sw.ShowCallstack(GetCurrentThread());
exit(1);
}
void std_handler( void ) {
seg_handler(1);
}
Run Code Online (Sandbox Code Playgroud)
上面的处理程序使用StackWalker
编辑:
当然,您还需要将终止处理程序添加到主线程中:
int main(int argc, char *argv[]) {
CALL_LOGGER();
signal(SIGSEGV, seg_handler);
std::set_terminate( std_handler );
return runapp(argc, argv);
}
Run Code Online (Sandbox Code Playgroud)
希望这对某人有帮助
-雅各布