mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-05 09:15:34 +08:00
Refactor crashpad initialization
Crashpad handler was initialized quite late since we were waiting for settings. However the settings in crashpad are persistent itself, hence we can start it at the earliest possible time and change the upload settings independently later. The only prerequisite is to have QCoreApplication constructed in order for the application name to be available. ref T652
This commit is contained in:
committed by
Klaus Basan
parent
99bcee87aa
commit
a7509669f9
@@ -21,6 +21,7 @@
|
||||
#include "blackcore/inputmanager.h"
|
||||
#include "blackmisc/atomicfile.h"
|
||||
#include "blackmisc/applicationinfo.h"
|
||||
#include "blackmisc/crashhandler.h"
|
||||
#include "blackmisc/datacache.h"
|
||||
#include "blackmisc/dbusserver.h"
|
||||
#include "blackmisc/directoryutils.h"
|
||||
@@ -68,16 +69,6 @@
|
||||
#include <QSysInfo>
|
||||
#include <cstdlib>
|
||||
|
||||
#ifdef BLACK_USE_CRASHPAD
|
||||
#if defined(Q_OS_WIN) && !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include "crashpad/client/crashpad_client.h"
|
||||
#include "crashpad/client/crash_report_database.h"
|
||||
#include "crashpad/client/settings.h"
|
||||
#include "crashpad/client/simulate_crash.h"
|
||||
#endif
|
||||
|
||||
using namespace BlackConfig;
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::Db;
|
||||
@@ -90,7 +81,6 @@ using namespace BlackCore::Context;
|
||||
using namespace BlackCore::Vatsim;
|
||||
using namespace BlackCore::Data;
|
||||
using namespace BlackCore::Db;
|
||||
using namespace crashpad;
|
||||
|
||||
BlackCore::CApplication *sApp = nullptr; // set by constructor
|
||||
|
||||
@@ -382,9 +372,6 @@ namespace BlackCore
|
||||
// Settings if not already initialized
|
||||
msgs.push_back(this->initLocalSettings());
|
||||
if (msgs.isFailure()) { break; }
|
||||
|
||||
// we have settings, so enable crash handler.
|
||||
msgs.push_back(this->initCrashHandler());
|
||||
}
|
||||
while (false);
|
||||
|
||||
@@ -959,7 +946,7 @@ namespace BlackCore
|
||||
CLogHandler::instance()->install(); // make sure we have a log handler!
|
||||
|
||||
// File logger
|
||||
m_fileLogger.reset(new CFileLogger(executable(), CDirectoryUtils::logDirectory()));
|
||||
m_fileLogger.reset(new CFileLogger(this));
|
||||
m_fileLogger->changeLogPattern(CLogPattern().withSeverityAtOrAbove(CStatusMessage::SeverityDebug));
|
||||
}
|
||||
|
||||
@@ -1636,164 +1623,20 @@ namespace BlackCore
|
||||
return CUrlList();
|
||||
}
|
||||
|
||||
#ifdef BLACK_USE_CRASHPAD
|
||||
//! Convert to file path
|
||||
base::FilePath qstringToFilePath(const QString &str)
|
||||
{
|
||||
# ifdef Q_OS_WIN
|
||||
return base::FilePath(str.toStdWString());
|
||||
# else
|
||||
return base::FilePath(str.toStdString());
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
BlackMisc::CStatusMessageList CApplication::initCrashHandler()
|
||||
{
|
||||
#ifdef BLACK_USE_CRASHPAD
|
||||
// No crash handling for unit tests
|
||||
if (this->getApplicationInfo().isUnitTest()) { return CStatusMessage(this).info(u"No crash handler for unit tests"); }
|
||||
|
||||
static const QString crashpadHandler(CBuildConfig::isRunningOnWindowsNtPlatform() ? "swift_crashpad_handler.exe" : "swift_crashpad_handler");
|
||||
static const QString handler = CFileUtils::appendFilePaths(CDirectoryUtils::binDirectory(), crashpadHandler);
|
||||
// const QString crashpadPath = CDirectoryUtils::crashpadDirectory();
|
||||
const QString database = CDirectoryUtils::crashpadDatabaseDirectory();
|
||||
const QString metrics = CDirectoryUtils::crashpadMetricsDirectory();
|
||||
|
||||
if (!QFileInfo::exists(handler))
|
||||
{
|
||||
return CStatusMessage(this).warning(u"Crashpad handler '%1' not found. Cannot init handler!") << handler;
|
||||
}
|
||||
|
||||
const CUrl serverUrl = this->getGlobalSetup().getCrashReportServerUrl();
|
||||
std::map<std::string, std::string> annotations;
|
||||
|
||||
// Backtrace annotations
|
||||
annotations["token"] = "b15efd93e290be3cf5d39750cadc092b651327ff0c027b80abd75e0ee50df1da";
|
||||
annotations["format"] = "minidump";
|
||||
annotations["version"] = CBuildConfig::getVersionString().toStdString();
|
||||
annotations["platform"] = CBuildConfig::getPlatformString().toStdString();
|
||||
annotations["qtversion"] = QT_VERSION_STR;
|
||||
|
||||
// add our logfile
|
||||
const QString logFilePath = m_fileLogger->getLogFilePath(); // file and path
|
||||
const QString logFileName = m_fileLogger->getLogFileName();
|
||||
const QString logAttachment = QStringLiteral("--attachment=attachment_%1=%2").arg(logFileName, logFilePath);
|
||||
|
||||
std::vector<std::string> arguments;
|
||||
arguments.push_back(logAttachment.toStdString());
|
||||
|
||||
// and the simplified crash info if any
|
||||
const QString crashInfoFileName("swiftcrashinfo.txt");
|
||||
const QString crashInfoFilePath(CFileUtils::appendFilePaths(CFileUtils::stripFileFromPath(logFilePath), crashInfoFileName));
|
||||
m_crashAndLogInfo.setLogPathAndFileName(crashInfoFilePath);
|
||||
const QString crashAttachment = QStringLiteral("--attachment=attachment_%1=%2").arg(crashInfoFileName, crashInfoFilePath);
|
||||
arguments.push_back(crashAttachment.toStdString());
|
||||
|
||||
// for testing purposes
|
||||
if (CBuildConfig::isLocalDeveloperDebugBuild())
|
||||
{
|
||||
arguments.push_back("--no-rate-limit");
|
||||
}
|
||||
|
||||
QDir().mkpath(database);
|
||||
m_crashReportDatabase = CrashReportDatabase::Initialize(qstringToFilePath(database));
|
||||
this->onCrashDumpUploadEnabledChanged(); // settings for crashpad uploads
|
||||
m_crashpadClient = std::make_unique<CrashpadClient>();
|
||||
m_crashpadClient->StartHandler(qstringToFilePath(handler),
|
||||
qstringToFilePath(database),
|
||||
qstringToFilePath(metrics),
|
||||
serverUrl.getFullUrl().toStdString(),
|
||||
annotations,
|
||||
arguments,
|
||||
false, true);
|
||||
|
||||
this->crashAndLogAppendInfo(u"Init crash info at " % QDateTime::currentDateTimeUtc().toString());
|
||||
return CStatusMessage(this).info(u"Using crash handler");
|
||||
#else
|
||||
return CStatusMessage(this).info(u"Not using crash handler");
|
||||
#endif
|
||||
}
|
||||
|
||||
void CApplication::onCrashDumpUploadEnabledChanged()
|
||||
{
|
||||
#ifdef BLACK_USE_CRASHPAD
|
||||
const bool enabled = CBuildConfig::isReleaseBuild() && m_crashDumpSettings.getThreadLocal().isEnabled();
|
||||
this->enableCrashDumpUpload(enabled);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CApplication::triggerCrashInfoWrite()
|
||||
{
|
||||
m_crashAndLogInfo.triggerWritingFile();
|
||||
}
|
||||
|
||||
void CApplication::setCrashInfo(const CCrashInfo &info)
|
||||
{
|
||||
m_crashAndLogInfo = info;
|
||||
m_dsCrashAndLogInfo.inputSignal();
|
||||
}
|
||||
|
||||
void CApplication::crashAndLogInfoUserName(const QString &name)
|
||||
{
|
||||
m_crashAndLogInfo.setUserName(name);
|
||||
m_dsCrashAndLogInfo.inputSignal();
|
||||
}
|
||||
|
||||
void CApplication::crashAndLogInfoSimulator(const QString &simulator)
|
||||
{
|
||||
m_crashAndLogInfo.setSimulatorString(simulator);
|
||||
m_dsCrashAndLogInfo.inputSignal();
|
||||
}
|
||||
|
||||
void CApplication::crashAndLogInfoFlightNetwork(const QString &flightNetwork)
|
||||
{
|
||||
m_crashAndLogInfo.setFlightNetworkString(flightNetwork);
|
||||
m_dsCrashAndLogInfo.inputSignal();
|
||||
}
|
||||
|
||||
void CApplication::crashAndLogAppendInfo(const QString &info)
|
||||
{
|
||||
m_crashAndLogInfo.appendInfo(info);
|
||||
m_dsCrashAndLogInfo.inputSignal();
|
||||
}
|
||||
|
||||
void CApplication::simulateCrash()
|
||||
{
|
||||
#ifdef BLACK_USE_CRASHPAD
|
||||
CLogMessage(this).info(u"Simulated crash dump!");
|
||||
m_crashAndLogInfo.appendInfo("Simulated crash dump!");
|
||||
m_crashAndLogInfo.writeToFile();
|
||||
CRASHPAD_SIMULATE_CRASH();
|
||||
// real crash
|
||||
// raise(SIGSEGV); #include <signal.h>
|
||||
#else
|
||||
CLogMessage(this).warning(u"This compiler or platform does not support crashpad. Cannot simulate crash dump!");
|
||||
#endif
|
||||
CCrashHandler::instance()->simulateCrash();
|
||||
}
|
||||
|
||||
void CApplication::enableCrashDumpUpload(bool enable)
|
||||
{
|
||||
#ifdef BLACK_USE_CRASHPAD
|
||||
if (!m_crashReportDatabase) { return; }
|
||||
crashpad::Settings *settings = m_crashReportDatabase->GetSettings();
|
||||
settings->SetUploadsEnabled(enable);
|
||||
#else
|
||||
Q_UNUSED(enable);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CApplication::isCrashDumpUploadEnabled() const
|
||||
{
|
||||
#ifdef BLACK_USE_CRASHPAD
|
||||
if (!m_crashReportDatabase) { return false; }
|
||||
crashpad::Settings *settings = m_crashReportDatabase->GetSettings();
|
||||
bool enabled = false;
|
||||
bool ok = settings->GetUploadsEnabled(&enabled);
|
||||
return ok && enabled;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
CCrashHandler::instance()->setUploadsEnabled(enable);
|
||||
}
|
||||
|
||||
bool CApplication::isSupportingCrashpad() const
|
||||
|
||||
@@ -43,10 +43,6 @@
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
|
||||
#if !defined(Q_CC_MINGW)
|
||||
#define BLACK_USE_CRASHPAD
|
||||
#endif
|
||||
|
||||
class QHttpMultiPart;
|
||||
class QNetworkReply;
|
||||
class QNetworkRequest;
|
||||
@@ -57,12 +53,6 @@ namespace BlackMisc
|
||||
class CLogCategoryList;
|
||||
}
|
||||
|
||||
namespace crashpad
|
||||
{
|
||||
class CrashpadClient;
|
||||
class CrashReportDatabase;
|
||||
}
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
class CCoreFacade;
|
||||
@@ -303,26 +293,6 @@ namespace BlackCore
|
||||
virtual QString cmdLineArgumentsAsString(bool withExecutable = true);
|
||||
//! @}
|
||||
|
||||
// ----------------------- Crash info ---------------------------------
|
||||
|
||||
//! Extra annotation for crash to easier identify annotation
|
||||
void setCrashInfo(const BlackMisc::CCrashInfo &info);
|
||||
|
||||
//! User name for crash info
|
||||
void crashAndLogInfoUserName(const QString &name);
|
||||
|
||||
//! Simulator string
|
||||
void crashAndLogInfoSimulator(const QString &simulator);
|
||||
|
||||
//! Flight network
|
||||
void crashAndLogInfoFlightNetwork(const QString &flightNetwork);
|
||||
|
||||
//! Append crash info
|
||||
void crashAndLogAppendInfo(const QString &info);
|
||||
|
||||
//! Get the crash info
|
||||
const BlackMisc::CCrashInfo &getCrashInfo() const { return m_crashAndLogInfo; }
|
||||
|
||||
//! Simulate a crash
|
||||
//! \private only for testing purposes
|
||||
void simulateCrash();
|
||||
@@ -331,9 +301,6 @@ namespace BlackCore
|
||||
//! \remark only change for testing
|
||||
void enableCrashDumpUpload(bool enable);
|
||||
|
||||
//! Is crash dump upload enabled
|
||||
bool isCrashDumpUploadEnabled() const;
|
||||
|
||||
//! Has crashpad support?
|
||||
bool isSupportingCrashpad() const;
|
||||
|
||||
@@ -727,22 +694,10 @@ namespace BlackCore
|
||||
bool m_localSettingsLoaded = false; //!< local settings loaded?
|
||||
|
||||
// -------------- crashpad -----------------
|
||||
//! Init the crash handler
|
||||
BlackMisc::CStatusMessageList initCrashHandler();
|
||||
BlackMisc::CSettingReadOnly<Application::TCrashDumpSettings> m_crashDumpSettings { this, &CApplication::onCrashDumpUploadEnabledChanged };
|
||||
|
||||
//! Upload settings changed
|
||||
void onCrashDumpUploadEnabledChanged();
|
||||
|
||||
#ifdef BLACK_USE_CRASHPAD
|
||||
std::unique_ptr<crashpad::CrashpadClient> m_crashpadClient;
|
||||
std::unique_ptr<crashpad::CrashReportDatabase> m_crashReportDatabase;
|
||||
BlackMisc::CSettingReadOnly<Application::TCrashDumpSettings> m_crashDumpSettings { this, &CApplication::onCrashDumpUploadEnabledChanged };
|
||||
#endif
|
||||
// crash info
|
||||
void triggerCrashInfoWrite();
|
||||
|
||||
BlackMisc::CCrashInfo m_crashAndLogInfo; //!< info representing details
|
||||
BlackMisc::CDigestSignal m_dsCrashAndLogInfo { this, &CApplication::triggerCrashInfoWrite, 10000, 5 };
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -20,9 +20,6 @@ INCLUDEPATH += pch
|
||||
|
||||
DEFINES += LOG_IN_FILE BUILD_BLACKCORE_LIB
|
||||
|
||||
INCLUDEPATH *= $$EXTERNALSROOT/common/include/crashpad
|
||||
INCLUDEPATH *= $$EXTERNALSROOT/common/include/crashpad/mini_chromium
|
||||
|
||||
HEADERS += *.h
|
||||
HEADERS += $$PWD/application/*.h
|
||||
HEADERS += $$PWD/audio/*.h
|
||||
@@ -41,13 +38,6 @@ LIBS *= -lvatlib
|
||||
DESTDIR = $$DestRoot/lib
|
||||
DLLDESTDIR = $$DestRoot/bin
|
||||
|
||||
msvc {
|
||||
CONFIG(debug, debug|release): LIBS *= -lclientd -lutild -lbased -lRpcrt4 -lAdvapi32
|
||||
CONFIG(release, debug|release): LIBS *= -lclient -lutil -lbase -lRpcrt4 -lAdvapi32
|
||||
}
|
||||
macx: LIBS *= -lclient -lutil -lbase -lbsm -framework Security
|
||||
unix:!macx: LIBS *= -lclient -lutil -lbase
|
||||
|
||||
OTHER_FILES += readme.txt *.xml
|
||||
|
||||
win32 {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "blackmisc/network/server.h"
|
||||
#include "blackmisc/network/user.h"
|
||||
#include "blackmisc/stringutils.h"
|
||||
#include "blackmisc/crashhandler.h"
|
||||
|
||||
#include <QVersionNumber>
|
||||
#include <QJsonObject>
|
||||
@@ -165,7 +166,7 @@ namespace BlackCore
|
||||
if (CBuildConfig::isLocalDeveloperDebugBuild()) { pingUrl.appendQuery("dev", "true"); }
|
||||
if (sApp)
|
||||
{
|
||||
const CCrashInfo ci = sApp->getCrashInfo();
|
||||
const CCrashInfo ci = CCrashHandler::instance()->getCrashInfo();
|
||||
pingUrl.appendQuery("application", sApp->getApplicationNameAndVersion());
|
||||
if (!ci.getSimulatorString().isEmpty()) { pingUrl.appendQuery("fs", ci.getSimulatorString()); }
|
||||
if (!ci.getFlightNetworkString().isEmpty()) { pingUrl.appendQuery("network", ci.getFlightNetworkString()); }
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "blackcore/application.h"
|
||||
#include "blackmisc/simulation/data/modelcaches.h"
|
||||
#include "blackmisc/math/mathutils.h"
|
||||
#include "blackmisc/crashhandler.h"
|
||||
#include "blackmisc/directoryutils.h"
|
||||
#include "blackmisc/threadutils.h"
|
||||
#include "blackmisc/logmessage.h"
|
||||
@@ -153,7 +154,7 @@ namespace BlackCore
|
||||
void ISimulator::reloadWeatherSettings()
|
||||
{
|
||||
// log crash info about weather
|
||||
if (sApp && !sApp->isShuttingDown()) { sApp->crashAndLogAppendInfo(u"Simulator weather: " % boolToYesNo(m_isWeatherActivated)); }
|
||||
if (sApp && !sApp->isShuttingDown()) { CCrashHandler::instance()->crashAndLogAppendInfo(u"Simulator weather: " % boolToYesNo(m_isWeatherActivated)); }
|
||||
if (!m_isWeatherActivated) { return; }
|
||||
const CWeatherScenario selectedWeatherScenario = m_weatherScenarioSettings.get();
|
||||
if (!CWeatherScenario::isRealWeatherScenario(selectedWeatherScenario))
|
||||
@@ -163,7 +164,7 @@ namespace BlackCore
|
||||
}
|
||||
|
||||
// log crash info about weather
|
||||
if (sApp && !sApp->isShuttingDown()) { sApp->crashAndLogAppendInfo(selectedWeatherScenario.toQString(true)); }
|
||||
if (sApp && !sApp->isShuttingDown()) { CCrashHandler::instance()->crashAndLogAppendInfo(selectedWeatherScenario.toQString(true)); }
|
||||
}
|
||||
|
||||
void ISimulator::clearAllRemoteAircraftData()
|
||||
@@ -872,7 +873,7 @@ namespace BlackCore
|
||||
const bool r = setup.isRenderingRestricted();
|
||||
const bool e = setup.isRenderingEnabled();
|
||||
|
||||
if (sApp && !sApp->isShuttingDown()) { sApp->crashAndLogAppendInfo(u"Rendering setup: " % setup.toQString(true)); }
|
||||
if (sApp && !sApp->isShuttingDown()) { CCrashHandler::instance()->crashAndLogAppendInfo(u"Rendering setup: " % setup.toQString(true)); }
|
||||
emit this->renderRestrictionsChanged(r, e, setup.getMaxRenderedAircraft(), setup.getMaxRenderedDistance());
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user