From a41b3d5bf6077c64eb2bc65ad4bb44cf19923eb4 Mon Sep 17 00:00:00 2001 From: LiaoCheng <820564830@qq.com> Date: Sat, 11 Jun 2022 22:21:52 +0800 Subject: [PATCH] Optimize WinVeh's implementation --- handler/QBreakpadHandler.cpp | 8 -------- handler/QBreakpadHandler.h | 11 ++++------- handler/WinVeh.cpp | 32 +++++++++++++++++++++----------- handler/WinVeh.h | 8 +++++++- 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/handler/QBreakpadHandler.cpp b/handler/QBreakpadHandler.cpp index 2fe008a..3e30b86 100644 --- a/handler/QBreakpadHandler.cpp +++ b/handler/QBreakpadHandler.cpp @@ -32,7 +32,6 @@ #include "client/linux/handler/exception_handler.h" #elif defined(Q_OS_WIN32) #include "client/windows/handler/exception_handler.h" -#include "WinVeh.h" #endif #if defined(Q_OS_WIN32) @@ -191,13 +190,6 @@ void QBreakpadHandler::toCrash() *iNotExistVar = 2; } -#ifdef Q_OS_WIN32 -void QBreakpadHandler::AddWindowsVeh() -{ - WinVeh::AddVeh(); -} -#endif - void QBreakpadHandler::setUploadUrl(const QUrl &url) { if(!url.isValid() || url.isEmpty()) diff --git a/handler/QBreakpadHandler.h b/handler/QBreakpadHandler.h index c61652c..14275cf 100644 --- a/handler/QBreakpadHandler.h +++ b/handler/QBreakpadHandler.h @@ -24,6 +24,10 @@ #include #include "singletone/singleton.h" +#if defined(Q_OS_WIN32) +#include "WinVeh.h" +#endif + namespace google_breakpad { class ExceptionHandler; class MinidumpDescriptor; @@ -53,13 +57,6 @@ class QBreakpadHandler: public QObject /// To crash. A static test function static void toCrash(); -#ifdef Q_OS_WIN32 - /// Add a windows veh. Experimental Function - /// \details Google breakpad do not catch exception after qt app enters main event loop, so add a veh to catch exceptions. - /// Test environment: qt5.6.2_mingw, qt5.6.2_msvc2015-32bit, qt5.9.9_mingw, qt5.9.9_msvc2015-32bit - static void AddWindowsVeh(); -#endif - public slots: void sendDumps(); diff --git a/handler/WinVeh.cpp b/handler/WinVeh.cpp index 23fcb92..2c5317b 100644 --- a/handler/WinVeh.cpp +++ b/handler/WinVeh.cpp @@ -25,31 +25,41 @@ typedef BOOL (WINAPI *MiniDumpWriteDump_type)( CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); PVOID WinVeh::previous_filter_veh = NULL; +std::vector WinVeh::extraIgnoredExceptionCodes = {}; void WinVeh::AddVeh() { previous_filter_veh = AddVectoredExceptionHandler(TRUE, HandleException_Veh); } +void WinVeh::SetExtraIgnoredExceptionCodes(const std::vector &codes) +{ + extraIgnoredExceptionCodes = codes; +} + LONG WinVeh::HandleException_Veh(PEXCEPTION_POINTERS exinfo) { + unsigned long &exceptionCode = exinfo->ExceptionRecord->ExceptionCode; +// unsigned long &exceptionFlags = exinfo->ExceptionRecord->ExceptionFlags; + // ignore debug exception and EXCEPTION_INVALID_HANDLE - switch (exinfo->ExceptionRecord->ExceptionCode) { + switch (exceptionCode) { case EXCEPTION_BREAKPOINT: case EXCEPTION_SINGLE_STEP: case DBG_PRINTEXCEPTION_C: case DBG_PRINTEXCEPTION_WIDE_C: case EXCEPTION_INVALID_HANDLE: return EXCEPTION_CONTINUE_EXECUTION; - // veh may catch some unnecessary exception, such as 0x000006ba(print server err), you can ignore it if you don't need it. - case 0x000006ba: - return EXCEPTION_CONTINUE_EXECUTION; } + const std::vector& v = extraIgnoredExceptionCodes; + if (std::find(v.begin(), v.end(), exceptionCode) != v.end()) + return EXCEPTION_CONTINUE_EXECUTION; // start to write dump // May can use google_breakpad::ExceptionHandler's WriteMinidump() WriteMinidumpForException()... functions to write dumps, but it seems more complex. - printf(" ---- veh ExceptionFlags: %lX \n", exinfo->ExceptionRecord->ExceptionFlags); //If it is can be continue to execute. Mostly is 0. - printf(" ---- veh ExceptionCode: %lX \n", exinfo->ExceptionRecord->ExceptionCode); + + //printf("qBreakPad veh ExceptionFlags: %lX \n", exceptionFlags); //If it is can be continue to execute. Mostly is 0. + //printf("qBreakPad veh ExceptionCode: %lX \n", exceptionCode); RemoveVectoredExceptionHandler(previous_filter_veh); //del veh, avoid to self-recursion @@ -62,7 +72,7 @@ LONG WinVeh::HandleException_Veh(PEXCEPTION_POINTERS exinfo) std::wstring wsFileName = sFileName.toStdWString(); HANDLE lhDumpFile = CreateFile(wsFileName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (!lhDumpFile) { - printf(" ---- veh CreateFile failed: \n"); + printf("qBreakPad veh CreateFile failed: \n"); return EXCEPTION_EXECUTE_HANDLER; } @@ -76,19 +86,19 @@ LONG WinVeh::HandleException_Veh(PEXCEPTION_POINTERS exinfo) // function MiniDumpWriteDump() defined in MinGW but not in msvc2015-32bit, use MiniDumpWriteDump_type and find it from dll MiniDumpWriteDump_type minidump_write_dump_ = reinterpret_cast(GetProcAddress(dbghelp_module_, "MiniDumpWriteDump")); if (!minidump_write_dump_) { - printf(" ---- veh MiniDumpWriteDump() failed: \n"); + printf("qBreakPad veh MiniDumpWriteDump() failed: \n"); return EXCEPTION_EXECUTE_HANDLER; } bSuccess = minidump_write_dump_(GetCurrentProcess(), GetCurrentProcessId(), lhDumpFile, MiniDumpNormal, &loExceptionInfo, NULL, NULL); } else { - printf(" ---- veh LoadLibrary 'dbghelp' failed: \n"); + printf("qBreakPad veh LoadLibrary 'dbghelp' failed: \n"); return EXCEPTION_EXECUTE_HANDLER; } if (bSuccess) - printf(" ---- veh write file success \n"); + printf("qBreakPad veh write file success \n"); else - printf(" ---- veh write file failed: \n"); + printf("qBreakPad veh write file failed: \n"); fflush(stdout); // ouput immediately, or may not print cause the crash CloseHandle(lhDumpFile); diff --git a/handler/WinVeh.h b/handler/WinVeh.h index 3c6fafb..78e2dc8 100644 --- a/handler/WinVeh.h +++ b/handler/WinVeh.h @@ -2,15 +2,21 @@ #define WINVEH_H #include +#include class WinVeh { public: - /// Add A Windows VEH + /// Add a windows veh. Experimental Function + /// \details Google breakpad do not catch exception after qt app enters main event loop, so add a veh to catch exceptions. + /// Test environment: qt5.6.2_mingw, qt5.6.2_msvc2015-32bit, qt5.9.9_mingw, qt5.9.9_msvc2015-32bit static void AddVeh(); + /// Veh may catch some unnecessary exception, such as 0x000006ba(print server err). Set the extra exception codes that you want to ignore + static void SetExtraIgnoredExceptionCodes(const std::vector &codes); private: static PVOID previous_filter_veh; static LONG WINAPI HandleException_Veh(PEXCEPTION_POINTERS exinfo); + static std::vector extraIgnoredExceptionCodes; };