mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 23:05:36 +08:00
203 lines
7.0 KiB
C++
203 lines
7.0 KiB
C++
/* Copyright (C) 2019
|
|
* swift project Community / Contributors
|
|
*
|
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
|
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
|
|
* or distributed except according to the terms contained in the LICENSE file.
|
|
*/
|
|
|
|
#include "blackmisc/crashhandler.h"
|
|
#include "blackmisc/swiftdirectories.h"
|
|
#include "blackmisc/directoryutils.h"
|
|
#include "blackmisc/logmessage.h"
|
|
#include "blackmisc/filelogger.h"
|
|
#include "blackconfig/buildconfig.h"
|
|
|
|
#include <QCoreApplication>
|
|
#include <QFileInfo>
|
|
#include <QStringBuilder>
|
|
|
|
#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 crashpad;
|
|
|
|
namespace BlackMisc
|
|
{
|
|
CCrashHandler *CCrashHandler::instance()
|
|
{
|
|
static CCrashHandler crashHandler;
|
|
return &crashHandler;
|
|
}
|
|
|
|
CCrashHandler::~CCrashHandler()
|
|
{ }
|
|
|
|
#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
|
|
|
|
void CCrashHandler::init()
|
|
{
|
|
#ifdef BLACK_USE_CRASHPAD
|
|
static const QString crashpadHandler(CBuildConfig::isRunningOnWindowsNtPlatform() ? "swift_crashpad_handler.exe" : "swift_crashpad_handler");
|
|
static const QString handler = CFileUtils::appendFilePaths(CSwiftDirectories::binDirectory(), crashpadHandler);
|
|
const QString database = CSwiftDirectories::crashpadDatabaseDirectory();
|
|
const QString metrics = CSwiftDirectories::crashpadMetricsDirectory();
|
|
|
|
if (!QFileInfo::exists(handler)) { return; }
|
|
|
|
const std::string serverUrl("http://swift-project.sp.backtrace.io:6097/");
|
|
std::map<std::string, std::string> annotations;
|
|
|
|
// Backtrace annotations
|
|
annotations["token"] = "b15efd93e290be3cf5d39750cadc092b651327ff0c027b80abd75e0ee50df1da";
|
|
annotations["format"] = "minidump";
|
|
annotations["commit"] = CBuildConfig::gitHeadSha1().toStdString();
|
|
annotations["version"] = CBuildConfig::getVersionString().toStdString();
|
|
annotations["short_version"] = CBuildConfig::getShortVersionString().toStdString();
|
|
annotations["platform"] = CBuildConfig::getPlatformString().toStdString();
|
|
annotations["qtversion"] = QT_VERSION_STR;
|
|
|
|
// add our logfile
|
|
const QString logAttachment = QStringLiteral("--attachment=attachment_%1=%2").arg(CFileLogger::getLogFileName(), CFileLogger::getLogFilePath());
|
|
|
|
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(CFileLogger::getLogFilePath()), 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));
|
|
m_crashpadClient = std::make_unique<CrashpadClient>();
|
|
m_crashpadClient->StartHandler(qstringToFilePath(handler),
|
|
qstringToFilePath(database),
|
|
qstringToFilePath(metrics),
|
|
serverUrl,
|
|
annotations,
|
|
arguments,
|
|
false, true);
|
|
|
|
this->crashAndLogAppendInfo(u"Init crash info at " % QDateTime::currentDateTimeUtc().toString());
|
|
#endif
|
|
}
|
|
|
|
void CCrashHandler::setUploadsEnabled(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 CCrashHandler::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
|
|
}
|
|
|
|
void CCrashHandler::triggerCrashInfoWrite()
|
|
{
|
|
m_crashAndLogInfo.triggerWritingFile();
|
|
}
|
|
|
|
void CCrashHandler::setCrashInfo(const CCrashInfo &info)
|
|
{
|
|
m_crashAndLogInfo = info;
|
|
m_dsCrashAndLogInfo.inputSignal();
|
|
}
|
|
|
|
void CCrashHandler::crashAndLogInfoUserName(const QString &name)
|
|
{
|
|
m_crashAndLogInfo.setUserName(name);
|
|
m_dsCrashAndLogInfo.inputSignal();
|
|
}
|
|
|
|
void CCrashHandler::crashAndLogInfoSimulator(const QString &simulator)
|
|
{
|
|
m_crashAndLogInfo.setSimulatorString(simulator);
|
|
m_dsCrashAndLogInfo.inputSignal();
|
|
}
|
|
|
|
void CCrashHandler::crashAndLogInfoFlightNetwork(const QString &flightNetwork)
|
|
{
|
|
m_crashAndLogInfo.setFlightNetworkString(flightNetwork);
|
|
m_dsCrashAndLogInfo.inputSignal();
|
|
}
|
|
|
|
void CCrashHandler::crashAndLogAppendInfo(const QString &info)
|
|
{
|
|
m_crashAndLogInfo.appendInfo(info);
|
|
m_dsCrashAndLogInfo.inputSignal();
|
|
}
|
|
|
|
void CCrashHandler::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
|
|
}
|
|
|
|
void CCrashHandler::simulateAssert()
|
|
{
|
|
# ifdef BLACK_USE_CRASHPAD
|
|
CLogMessage(this).info(u"Simulated ASSERT!");
|
|
m_crashAndLogInfo.appendInfo("Simulated ASSERT!");
|
|
m_crashAndLogInfo.writeToFile();
|
|
Q_ASSERT_X(false, Q_FUNC_INFO, "Test server to test Crash handler");
|
|
# else
|
|
CLogMessage(this).warning(u"This compiler or platform does not support crashpad. Cannot simulate crash dump!");
|
|
# endif
|
|
}
|
|
|
|
CCrashHandler::CCrashHandler(QObject *parent) :
|
|
QObject(parent)
|
|
{ }
|
|
}
|