gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 13:26:09 27 4
gpt4 key购买 nike

我想为我的 Qt 应用程序创建一个崩溃/异常处理程序。我已经让处理程序工作了(不包括在下面的代码中)。问题出在 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();
}

最佳答案

经过大量研究,再加上我对 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 ] ), 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);
}

上面的处理程序使用 StackWalker

编辑:

当然,您还需要将终止处理程序添加到您的主线程中:

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

希望这对某人有帮助

-雅各布

关于在 Windows 上支持线程的 Qt 应用程序中的 C++ 崩溃/异常处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31705687/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com