Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Improved out of process crash handler (#5543)
* Add out of process crash handler for better crash handling.
- Loading branch information
Showing
with
1,416 additions
and 356 deletions.
- +3 −0 src/CMakeLists.txt
- +0 −3 src/app/CMakeLists.txt
- +0 −15 src/app/main.cpp
- +4 −1 src/app/qgisapp.cpp
- +75 −26 src/app/qgscrashhandler.cpp
- +5 −20 src/app/qgscrashhandler.h
- +0 −5 src/core/CMakeLists.txt
- +32 −0 src/crashhandler/CMakeLists.txt
- +99 −0 src/crashhandler/main.cpp
- +16 −1 src/{app → crashhandler}/qgscrashdialog.cpp
- +55 −54 src/{app → crashhandler}/qgscrashdialog.h
- +103 −83 src/{ui → crashhandler}/qgscrashdialog.ui
- +63 −28 src/{app → crashhandler}/qgscrashreport.cpp
- +101 −93 src/{app → crashhandler}/qgscrashreport.h
- +834 −0 src/crashhandler/qgsstacktrace.cpp
- +26 −27 src/{core → crashhandler}/qgsstacktrace.h
@@ -0,0 +1,32 @@ | ||
INCLUDE_DIRECTORIES(SYSTEM | ||
${CMAKE_CURRENT_BINARY_DIR} | ||
) | ||
|
||
QT5_WRAP_UI(CRASH_UIS_H qgscrashdialog.ui) | ||
QT5_WRAP_CPP(CRASH_HDR_MOC qgscrashdialog.h) | ||
|
||
SET(IMAGE_RCCS ../../images/images.qrc) | ||
QT5_ADD_RESOURCES(IMAGE_RCC_SRCS ${IMAGE_RCCS}) | ||
|
||
# -wd4091 Avoid 'typedef' ignored on left of '' when no variable is declared warning in DbgHelp.h | ||
SET_SOURCE_FILES_PROPERTIES(qgsstacktrace.cpp PROPERTIES COMPILE_FLAGS -wd4091) | ||
|
||
ADD_EXECUTABLE(qgiscrashhandler WIN32 | ||
main.cpp | ||
${CRASH_UIS_H} | ||
${CRASH_HDR_MOC} | ||
${IMAGE_RCC_SRCS} | ||
qgscrashdialog.cpp | ||
qgsstacktrace.cpp | ||
qgscrashreport.cpp | ||
${CMAKE_CURRENT_SOURCE_DIR}/../app/qgis_win32.rc | ||
) | ||
|
||
TARGET_LINK_LIBRARIES(qgiscrashhandler | ||
${QT_QTCORE_LIBRARY} | ||
${QT_QTGUI_LIBRARY} | ||
DbgHelp | ||
) | ||
|
||
INSTALL(CODE "MESSAGE(\"Installing crashhandler ...\")") | ||
INSTALL(TARGETS qgiscrashhandler RUNTIME DESTINATION ${QGIS_LIBEXEC_DIR}) |
@@ -0,0 +1,99 @@ | ||
/*************************************************************************** | ||
crssync.cpp | ||
------------------- | ||
begin : October 2017 | ||
copyright : (C) 2017 by Nathan Woodrow | ||
email : woodrow.nathan@gmail.com | ||
***************************************************************************/ | ||
|
||
/*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
#include <memory> | ||
#include <iostream> | ||
|
||
#define _NO_CVCONST_H | ||
#define _CRT_STDIO_ISO_WIDE_SPECIFIERS | ||
|
||
#include <QApplication> | ||
#include <QMainWindow> | ||
#include "qgscrashdialog.h" | ||
#include "qgsstacktrace.h" | ||
#include "qgscrashreport.h" | ||
|
||
|
||
int main( int argc, char *argv[] ) | ||
{ | ||
if ( argc < 2 ) | ||
{ | ||
std::cout << "QGIS Crash Handler Usage: \n" | ||
<< "qgscrashhandler {infofile}" << std::endl; | ||
return -1; | ||
} | ||
|
||
QApplication app( argc, argv ); | ||
app.setQuitOnLastWindowClosed( true ); | ||
QCoreApplication::setOrganizationName( "QGIS" ); | ||
QCoreApplication::setApplicationName( "QGIS3" ); | ||
|
||
QString extraInfoFile = QString( argv[1] ); | ||
std::cout << "Extra Info File: " << extraInfoFile.toUtf8().data() << std::endl; | ||
|
||
QFile file( extraInfoFile ); | ||
QString processIdString; | ||
QString threadIdString; | ||
QString exceptionPointersString; | ||
QString symbolPaths; | ||
QString reloadArgs; | ||
QStringList versionInfo; | ||
|
||
if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) ) | ||
{ | ||
processIdString = file.readLine(); | ||
threadIdString = file.readLine(); | ||
exceptionPointersString = file.readLine(); | ||
symbolPaths = file.readLine(); | ||
reloadArgs = file.readLine(); | ||
// The version info is the last stuff to be in the file until the end | ||
// bit gross but :) | ||
QString info = file.readAll(); | ||
versionInfo = info.split( "\n" ); | ||
} | ||
|
||
DWORD processId; | ||
DWORD threadId; | ||
LPEXCEPTION_POINTERS exception; | ||
processId = processIdString.toULong(); | ||
threadId = threadIdString.toULong(); | ||
sscanf_s( exceptionPointersString.toLocal8Bit().constData(), "%p", &exception ); | ||
|
||
std::cout << "Process ID: " << processIdString.toLocal8Bit().constData() << std::endl; | ||
std::cout << "Trhead ID:" << threadIdString.toLocal8Bit().constData() << std::endl; | ||
std::cout << "Exception Pointer: " << exceptionPointersString.toLocal8Bit().constData() << std::endl; | ||
std::cout << "Symbol Path :" << symbolPaths.toUtf8().data() << std::endl; | ||
|
||
std::unique_ptr<QgsStackTrace> stackTrace( QgsStackTrace::trace( processId, threadId, exception, symbolPaths ) ); | ||
|
||
QgsCrashReport report; | ||
report.setVersionInfo( versionInfo ); | ||
report.setStackTrace( stackTrace.get() ); | ||
report.exportToCrashFolder(); | ||
|
||
QgsCrashDialog dlg; | ||
dlg.setReloadArgs( reloadArgs ); | ||
dlg.setBugReport( report.toHtml() ); | ||
dlg.setModal( true ); | ||
dlg.show(); | ||
app.exec(); | ||
|
||
ResumeThread( stackTrace->thread ); | ||
CloseHandle( stackTrace->thread ); | ||
CloseHandle( stackTrace->process ); | ||
|
||
return 0; | ||
} |
Oops, something went wrong.