-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqgscrashhandler.cpp
126 lines (108 loc) · 4.76 KB
/
qgscrashhandler.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/***************************************************************************
qgscrashhandler.cpp - QgsCrashHandler
---------------------
begin : 23.4.2017
copyright : (C) 2017 by Nathan Woodrow
email : [email protected]
***************************************************************************
* *
* 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 <qgslogger.h>
#include <iostream>
#include "qgscrashhandler.h"
#include "qgsapplication.h"
#include "qgsproject.h"
#include <gdal.h>
#include <QTextStream>
#include <QProcess>
#include <QDir>
#include <QStandardPaths>
#include <QUuid>
QString QgsCrashHandler::sPythonCrashLogFile;
#ifdef _MSC_VER
LONG WINAPI QgsCrashHandler::handle( LPEXCEPTION_POINTERS exception )
{
DWORD processID = GetCurrentProcessId();
DWORD threadID = GetCurrentThreadId();
QString symbolPath;
if ( !QgsApplication::isRunningFromBuildDir() )
{
symbolPath = QStringLiteral( "%1\\pdb;http://msdl.microsoft.com/download/symbols;http://download.osgeo.org/osgeo4w/%2/symstores/%3" )
.arg( getenv( "QGIS_PREFIX_PATH" ) )
.arg( QSysInfo::WordSize == 64 ? QStringLiteral( "x86_64" ) : QStringLiteral( "x86" ) )
.arg( QFileInfo( getenv( "QGIS_PREFIX_PATH" ) ).baseName() );
}
else
{
symbolPath = QStringLiteral( "%1;%2;http://msdl.microsoft.com/download/symbols" )
.arg( getenv( "QGIS_PDB_PATH" ) )
.arg( QgsApplication::applicationDirPath() );
}
QString ptrStr = QString( "0x%1" ).arg( ( quintptr )exception, QT_POINTER_SIZE * 2, 16, QChar( '0' ) );
handleCrash( processID, threadID, symbolPath, ptrStr );
return TRUE;
}
#else
void QgsCrashHandler::handle( int )
{
handleCrash( QCoreApplication::applicationPid(), 0, QString(), QString() );
}
#endif
void QgsCrashHandler::handleCrash( int processID, int threadID,
const QString &symbolPath,
const QString &ptrStr )
{
QString fileName = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 ) + "/qgis-crash-info-" + QString::number( processID );
QgsDebugMsgLevel( fileName, 2 );
QStringList arguments;
arguments = QCoreApplication::arguments();
// TODO In future this needs to be moved out into a "session state" file because we can't trust this is valid in
// a crash.
QString projectFile = QgsProject::instance()->fileName();
if ( !projectFile.isEmpty() )
// quote project file path to avoid issues if it has spaces
arguments << QStringLiteral( "\"%1\"" ).arg( projectFile );
QStringList reportData;
reportData.append( QStringLiteral( "QGIS Version: %1" ).arg( Qgis::version() ) );
if ( QString( Qgis::devVersion() ) == QLatin1String( "exported" ) )
{
reportData.append( QStringLiteral( "QGIS code branch: Release %1.%2" )
.arg( Qgis::versionInt() / 10000 ).arg( Qgis::versionInt() / 100 % 100 ) );
}
else
{
reportData.append( QStringLiteral( "QGIS code revision: %1" ).arg( Qgis::devVersion() ) );
}
reportData.append( QStringLiteral( "Compiled against Qt: %1" ).arg( QT_VERSION_STR ) );
reportData.append( QStringLiteral( "Running against Qt: %1" ).arg( qVersion() ) );
reportData.append( QStringLiteral( "Compiled against GDAL: %1" ).arg( GDAL_RELEASE_NAME ) );
reportData.append( QStringLiteral( "Running against GDAL: %1" ).arg( GDALVersionInfo( "RELEASE_NAME" ) ) );
QFile file( fileName );
if ( file.open( QIODevice::WriteOnly | QIODevice::Text ) )
{
QTextStream stream( &file );
stream << QString::number( processID ) << Qt::endl;
stream << QString::number( threadID ) << Qt::endl;
stream << ptrStr << Qt::endl;
stream << symbolPath << Qt::endl;
stream << sPythonCrashLogFile << Qt::endl;
stream << arguments.join( ' ' ) << Qt::endl;
stream << reportData.join( '\n' ) << Qt::endl;
}
file.close();
QStringList args;
args << fileName;
QString prefixPath( getenv( "QGIS_PREFIX_PATH" ) ? getenv( "QGIS_PREFIX_PATH" ) : QApplication::applicationDirPath() );
#ifdef _MSC_VER
QString path = prefixPath + QStringLiteral( "/qgiscrashhandler.exe" );
#else
QString path = prefixPath + QStringLiteral( "/qgiscrashhandler" );
#endif
QgsDebugMsgLevel( path, 2 );
QProcess::execute( path, args );
}