微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Qt应用程序中的C ++崩溃/exception处理程序,在Windows上有线程支持

我想为我的Qt应用程序做一个崩溃/exception处理程序。 我有处理程序已经工作(不包括在下面的代码中)。 问题是在Windows上,它只有在调用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(); }

你可以摆脱“Microsoft Office Excel遇到问题”对话框?

如何仅使用WaitForDebugEvent系列函数来监视UNHANDLEDexception?

gdb核心转储打开失败

如何读取崩溃转储文件我有代码和.pdb文件

R并行Linux服务器崩溃 – 反序列化错误(节点$ con):从连接读取时出错

简单的C代码编译,但input时崩溃

array_map导致服务器崩溃

SFML – sf :: Font :: loadFromFile崩溃程序

最清楚的方式来明确地崩溃应用程序?

为什么这个C程序在Windows上崩溃,并在Linux上正常工作?

经过非常多的研究,结合我对Windows操作系统的了解,我终于找到了一个可以自动为新线程设置终止函数的工作解决方案。

诀窍是创建一个DLL来处理你的崩溃/异常。 在你的dll实现保留的DllMain()函数。 每当新线程或进程连接到主进程时,该函数都会接收通知。 fdwReason参数保存有关事件的信息。

新线程: DLL_THREAD_ATTACH

新进程: DLL_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; }

我的处理程序是这样的:

#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 ] ),symbol ); printf( "%i: %s - 0x%0Xn",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); }

上面的处理程序使用StackWalker

编辑:

当然,你也需要添加终止处理程序到你的主线程:

int main(int argc,char *argv[]) { CALL_LOGGER(); signal(SIGSEGV,seg_handler); std::set_terminate( std_handler ); return runapp(argc,argv); }

希望这有助于某人

-Jakob

我怀疑SetUnhandledExceptionFilter是一个比signal更好地捕获Windows崩溃的方法。 它是全局设置的(所以你不需要DLL来在每个线程中安装一个处理程序)并且不丢弃关于错误的信息(有可能有一些方法可以恢复SIGSEGV的真正原因,但是我不会立即知道怎么样)。

根据MSDN :

在多线程环境中,为每个线程分别维护终止函数。 每个新线程都需要安装自己的终止函数。 因此,每个线程负责自己的终止处理。

我想你必须为每个线程分别设置它。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐