mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 06:57:37 +02:00
Crash reporter moved to separate library
UAL moved back to networking
This commit is contained in:
parent
6ec276c818
commit
4dcc2882fd
16 changed files with 339 additions and 308 deletions
|
@ -230,7 +230,7 @@ link_hifi_libraries(
|
||||||
${PLATFORM_GL_BACKEND}
|
${PLATFORM_GL_BACKEND}
|
||||||
# Plaform specific input & display plugin libraries
|
# Plaform specific input & display plugin libraries
|
||||||
${PLATFORM_PLUGIN_LIBRARIES}
|
${PLATFORM_PLUGIN_LIBRARIES}
|
||||||
shaders
|
shaders monitoring
|
||||||
)
|
)
|
||||||
include_hifi_library_headers(script-engine)
|
include_hifi_library_headers(script-engine)
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@
|
||||||
#include "avatar/AvatarPackager.h"
|
#include "avatar/AvatarPackager.h"
|
||||||
#include "avatar/MyCharacterController.h"
|
#include "avatar/MyCharacterController.h"
|
||||||
#include "CrashRecoveryHandler.h"
|
#include "CrashRecoveryHandler.h"
|
||||||
#include "CrashHandler.h"
|
#include "crash-handler/CrashHandler.h"
|
||||||
#include "DiscoverabilityManager.h"
|
#include "DiscoverabilityManager.h"
|
||||||
#include "GLCanvas.h"
|
#include "GLCanvas.h"
|
||||||
#include "InterfaceDynamicFactory.h"
|
#include "InterfaceDynamicFactory.h"
|
||||||
|
@ -407,8 +407,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void deadlockDetectionCrash() {
|
void deadlockDetectionCrash() {
|
||||||
setCrashAnnotation("_mod_faulting_tid", std::to_string((uint64_t)_mainThreadID));
|
auto &ch = CrashHandler::getInstance();
|
||||||
setCrashAnnotation("deadlock", "1");
|
|
||||||
|
ch.setAnnotation("_mod_faulting_tid", std::to_string((uint64_t)_mainThreadID));
|
||||||
|
ch.setAnnotation("deadlock", "1");
|
||||||
uint32_t* crashTrigger = nullptr;
|
uint32_t* crashTrigger = nullptr;
|
||||||
*crashTrigger = 0xDEAD10CC;
|
*crashTrigger = 0xDEAD10CC;
|
||||||
}
|
}
|
||||||
|
@ -1054,9 +1056,11 @@ Application::Application(
|
||||||
{
|
{
|
||||||
// identify gpu as early as possible to help identify OpenGL initialization errors.
|
// identify gpu as early as possible to help identify OpenGL initialization errors.
|
||||||
auto gpuIdent = GPUIdent::getInstance();
|
auto gpuIdent = GPUIdent::getInstance();
|
||||||
setCrashAnnotation("sentry[contexts][gpu][name]", gpuIdent->getName().toStdString());
|
auto &ch = CrashHandler::getInstance();
|
||||||
setCrashAnnotation("sentry[contexts][gpu][version]", gpuIdent->getDriver().toStdString());
|
|
||||||
setCrashAnnotation("gpu_memory", std::to_string(gpuIdent->getMemory()));
|
ch.setAnnotation("sentry[contexts][gpu][name]", gpuIdent->getName().toStdString());
|
||||||
|
ch.setAnnotation("sentry[contexts][gpu][version]", gpuIdent->getDriver().toStdString());
|
||||||
|
ch.setAnnotation("gpu_memory", std::to_string(gpuIdent->getMemory()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the debug draw singleton is initialized on the main thread.
|
// make sure the debug draw singleton is initialized on the main thread.
|
||||||
|
@ -1166,13 +1170,15 @@ Application::Application(
|
||||||
_logger->setSessionID(accountManager->getSessionID());
|
_logger->setSessionID(accountManager->getSessionID());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
setCrashAnnotation("metaverse_session_id", accountManager->getSessionID().toString().toStdString());
|
auto &ch = CrashHandler::getInstance();
|
||||||
setCrashAnnotation("main_thread_id", std::to_string((size_t)QThread::currentThreadId()));
|
|
||||||
|
ch.setAnnotation("metaverse_session_id", accountManager->getSessionID().toString().toStdString());
|
||||||
|
ch.setAnnotation("main_thread_id", std::to_string((size_t)QThread::currentThreadId()));
|
||||||
|
|
||||||
if (steamClient) {
|
if (steamClient) {
|
||||||
qCDebug(interfaceapp) << "[VERSION] SteamVR buildID:" << steamClient->getSteamVRBuildID();
|
qCDebug(interfaceapp) << "[VERSION] SteamVR buildID:" << steamClient->getSteamVRBuildID();
|
||||||
}
|
}
|
||||||
setCrashAnnotation("steam", property(hifi::properties::STEAM).toBool() ? "1" : "0");
|
ch.setAnnotation("steam", property(hifi::properties::STEAM).toBool() ? "1" : "0");
|
||||||
|
|
||||||
qCDebug(interfaceapp) << "[VERSION] Build sequence:" << qPrintable(applicationVersion());
|
qCDebug(interfaceapp) << "[VERSION] Build sequence:" << qPrintable(applicationVersion());
|
||||||
qCDebug(interfaceapp) << "[VERSION] MODIFIED_ORGANIZATION:" << BuildInfo::MODIFIED_ORGANIZATION;
|
qCDebug(interfaceapp) << "[VERSION] MODIFIED_ORGANIZATION:" << BuildInfo::MODIFIED_ORGANIZATION;
|
||||||
|
@ -1236,7 +1242,8 @@ Application::Application(
|
||||||
connect(&domainHandler, SIGNAL(domainURLChanged(QUrl)), SLOT(domainURLChanged(QUrl)));
|
connect(&domainHandler, SIGNAL(domainURLChanged(QUrl)), SLOT(domainURLChanged(QUrl)));
|
||||||
connect(&domainHandler, SIGNAL(redirectToErrorDomainURL(QUrl)), SLOT(goToErrorDomainURL(QUrl)));
|
connect(&domainHandler, SIGNAL(redirectToErrorDomainURL(QUrl)), SLOT(goToErrorDomainURL(QUrl)));
|
||||||
connect(&domainHandler, &DomainHandler::domainURLChanged, [](QUrl domainURL){
|
connect(&domainHandler, &DomainHandler::domainURLChanged, [](QUrl domainURL){
|
||||||
setCrashAnnotation("domain", domainURL.toString().toStdString());
|
auto &ch = CrashHandler::getInstance();
|
||||||
|
ch.setAnnotation("domain", domainURL.toString().toStdString());
|
||||||
});
|
});
|
||||||
connect(&domainHandler, SIGNAL(resetting()), SLOT(resettingDomain()));
|
connect(&domainHandler, SIGNAL(resetting()), SLOT(resettingDomain()));
|
||||||
connect(&domainHandler, SIGNAL(connectedToDomain(QUrl)), SLOT(updateWindowTitle()));
|
connect(&domainHandler, SIGNAL(connectedToDomain(QUrl)), SLOT(updateWindowTitle()));
|
||||||
|
@ -1348,8 +1355,9 @@ Application::Application(
|
||||||
setPreferredCursor(Cursor::Manager::getIconName(Cursor::Icon::SYSTEM));
|
setPreferredCursor(Cursor::Manager::getIconName(Cursor::Icon::SYSTEM));
|
||||||
}
|
}
|
||||||
|
|
||||||
setCrashAnnotation("display_plugin", displayPlugin->getName().toStdString());
|
auto &ch = CrashHandler::getInstance();
|
||||||
setCrashAnnotation("hmd", displayPlugin->isHmd() ? "1" : "0");
|
ch.setAnnotation("display_plugin", displayPlugin->getName().toStdString());
|
||||||
|
ch.setAnnotation("hmd", displayPlugin->isHmd() ? "1" : "0");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
connect(this, &Application::activeDisplayPluginChanged, this, &Application::updateSystemTabletMode);
|
connect(this, &Application::activeDisplayPluginChanged, this, &Application::updateSystemTabletMode);
|
||||||
|
@ -1388,7 +1396,8 @@ Application::Application(
|
||||||
|
|
||||||
connect(myAvatar.get(), &MyAvatar::skeletonModelURLChanged, [](){
|
connect(myAvatar.get(), &MyAvatar::skeletonModelURLChanged, [](){
|
||||||
QUrl avatarURL = qApp->getMyAvatar()->getSkeletonModelURL();
|
QUrl avatarURL = qApp->getMyAvatar()->getSkeletonModelURL();
|
||||||
setCrashAnnotation("avatar", avatarURL.toString().toStdString());
|
auto &ch = CrashHandler::getInstance();
|
||||||
|
ch.setAnnotation("avatar", avatarURL.toString().toStdString());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Inititalize sample before registering
|
// Inititalize sample before registering
|
||||||
|
@ -2698,7 +2707,8 @@ void Application::updateHeartbeat() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onAboutToQuit() {
|
void Application::onAboutToQuit() {
|
||||||
setCrashAnnotation("shutdown", "1");
|
auto &ch = CrashHandler::getInstance();
|
||||||
|
ch.setAnnotation("shutdown", "1");
|
||||||
|
|
||||||
// quickly save AvatarEntityData before the EntityTree is dismantled
|
// quickly save AvatarEntityData before the EntityTree is dismantled
|
||||||
getMyAvatar()->saveAvatarEntityDataToSettings();
|
getMyAvatar()->saveAvatarEntityDataToSettings();
|
||||||
|
@ -7147,7 +7157,8 @@ void Application::updateWindowTitle() const {
|
||||||
QString metaverseUsername = accountManager->getAccountInfo().getUsername();
|
QString metaverseUsername = accountManager->getAccountInfo().getUsername();
|
||||||
QString domainUsername = domainAccountManager->getUsername();
|
QString domainUsername = domainAccountManager->getUsername();
|
||||||
|
|
||||||
setCrashAnnotation("sentry[user][username]", metaverseUsername.toStdString());
|
auto &ch = CrashHandler::getInstance();
|
||||||
|
ch.setAnnotation("sentry[user][username]", metaverseUsername.toStdString());
|
||||||
|
|
||||||
QString currentPlaceName;
|
QString currentPlaceName;
|
||||||
if (isServerlessMode()) {
|
if (isServerlessMode()) {
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <SettingManager.h>
|
#include <SettingManager.h>
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include <UserActivityLogger.h>
|
#include <UserActivityLogger.h>
|
||||||
|
#include <crash-handler/CrashHandler.h>
|
||||||
#include <BuildInfo.h>
|
#include <BuildInfo.h>
|
||||||
|
|
||||||
bool CrashRecoveryHandler::checkForResetSettings(bool wasLikelyCrash, bool suppressPrompt) {
|
bool CrashRecoveryHandler::checkForResetSettings(bool wasLikelyCrash, bool suppressPrompt) {
|
||||||
|
@ -91,7 +92,7 @@ bool CrashRecoveryHandler::suggestCrashReporting() {
|
||||||
QVBoxLayout* layout = new QVBoxLayout;
|
QVBoxLayout* layout = new QVBoxLayout;
|
||||||
|
|
||||||
QString explainText;
|
QString explainText;
|
||||||
auto &ual = UserActivityLogger::getInstance();
|
auto &ch = CrashHandler::getInstance();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,7 +120,7 @@ bool CrashRecoveryHandler::suggestCrashReporting() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ual.isCrashMonitorStarted()) {
|
if (!ch.isStarted()) {
|
||||||
qWarning() << "Crash reporting not working, skipping suggestion to enable it.";
|
qWarning() << "Crash reporting not working, skipping suggestion to enable it.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -131,8 +132,8 @@ bool CrashRecoveryHandler::suggestCrashReporting() {
|
||||||
|
|
||||||
QCheckBox* crashReportCheckbox = new QCheckBox("Enable automatic crash reporting");
|
QCheckBox* crashReportCheckbox = new QCheckBox("Enable automatic crash reporting");
|
||||||
|
|
||||||
crashReportCheckbox->setChecked(ual.isCrashReportingEnabled());
|
crashReportCheckbox->setChecked(ch.isEnabled());
|
||||||
crashReportCheckbox->setEnabled(ual.isCrashMonitorStarted());
|
crashReportCheckbox->setEnabled(ch.isStarted());
|
||||||
|
|
||||||
layout->addWidget(explainLabel);
|
layout->addWidget(explainLabel);
|
||||||
layout->addSpacing(12);
|
layout->addSpacing(12);
|
||||||
|
@ -149,7 +150,7 @@ bool CrashRecoveryHandler::suggestCrashReporting() {
|
||||||
|
|
||||||
crashDialog.exec();
|
crashDialog.exec();
|
||||||
|
|
||||||
ual.setCrashReportingEnabled(crashReportCheckbox->isChecked());
|
ch.setEnabled(crashReportCheckbox->isChecked());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -157,7 +158,7 @@ bool CrashRecoveryHandler::suggestCrashReporting() {
|
||||||
CrashRecoveryHandler::Action CrashRecoveryHandler::promptUserForAction(bool showCrashMessage) {
|
CrashRecoveryHandler::Action CrashRecoveryHandler::promptUserForAction(bool showCrashMessage) {
|
||||||
QDialog crashDialog;
|
QDialog crashDialog;
|
||||||
QLabel* label;
|
QLabel* label;
|
||||||
auto &ual = UserActivityLogger::getInstance();
|
auto &ch = CrashHandler::getInstance();
|
||||||
|
|
||||||
if (showCrashMessage) {
|
if (showCrashMessage) {
|
||||||
crashDialog.setWindowTitle("Interface Crashed Last Run");
|
crashDialog.setWindowTitle("Interface Crashed Last Run");
|
||||||
|
@ -176,7 +177,7 @@ CrashRecoveryHandler::Action CrashRecoveryHandler::promptUserForAction(bool show
|
||||||
QRadioButton* option3 = new QRadioButton("Continue with my current settings");
|
QRadioButton* option3 = new QRadioButton("Continue with my current settings");
|
||||||
QLabel* crashReportLabel = nullptr;
|
QLabel* crashReportLabel = nullptr;
|
||||||
|
|
||||||
if (ual.isCrashMonitorStarted()) {
|
if (ch.isStarted()) {
|
||||||
crashReportLabel = new QLabel("To help us with debugging, you can enable automatic crash reports.\n"
|
crashReportLabel = new QLabel("To help us with debugging, you can enable automatic crash reports.\n"
|
||||||
"They'll only be seen by developers trusted by the Overte e.V. organization,\n"
|
"They'll only be seen by developers trusted by the Overte e.V. organization,\n"
|
||||||
"and will only be used for improving the code.");
|
"and will only be used for improving the code.");
|
||||||
|
@ -187,8 +188,8 @@ CrashRecoveryHandler::Action CrashRecoveryHandler::promptUserForAction(bool show
|
||||||
QCheckBox* crashReportCheckbox = new QCheckBox("Enable automatic crash reporting");
|
QCheckBox* crashReportCheckbox = new QCheckBox("Enable automatic crash reporting");
|
||||||
|
|
||||||
|
|
||||||
crashReportCheckbox->setChecked(ual.isCrashReportingEnabled());
|
crashReportCheckbox->setChecked(ch.isEnabled());
|
||||||
crashReportCheckbox->setEnabled(ual.isCrashMonitorStarted());
|
crashReportCheckbox->setEnabled(ch.isStarted());
|
||||||
|
|
||||||
option3->setChecked(true);
|
option3->setChecked(true);
|
||||||
layout->addWidget(option1);
|
layout->addWidget(option1);
|
||||||
|
@ -218,7 +219,7 @@ CrashRecoveryHandler::Action CrashRecoveryHandler::promptUserForAction(bool show
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ual.setCrashReportingEnabled(crashReportCheckbox->isChecked());
|
ch.setEnabled(crashReportCheckbox->isChecked());
|
||||||
|
|
||||||
// Dialog cancelled or "do nothing" option chosen
|
// Dialog cancelled or "do nothing" option chosen
|
||||||
return CrashRecoveryHandler::DO_NOTHING;
|
return CrashRecoveryHandler::DO_NOTHING;
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
#include <plugins/SteamClientPlugin.h>
|
#include <plugins/SteamClientPlugin.h>
|
||||||
#include <UserActivityLogger.h>
|
#include <UserActivityLogger.h>
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
|
#include <crash-handler/CrashHandler.h>
|
||||||
|
|
||||||
#include "CrashHandler.h"
|
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
|
|
||||||
const Discoverability::Mode DEFAULT_DISCOVERABILITY_MODE = Discoverability::Connections;
|
const Discoverability::Mode DEFAULT_DISCOVERABILITY_MODE = Discoverability::Connections;
|
||||||
|
@ -133,7 +133,8 @@ void DiscoverabilityManager::updateLocation() {
|
||||||
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
|
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
|
||||||
steamClient->updateLocation(domainHandler.getHostname(), currentAddress);
|
steamClient->updateLocation(domainHandler.getHostname(), currentAddress);
|
||||||
}
|
}
|
||||||
setCrashAnnotation("address", currentAddress.toString().toStdString());
|
|
||||||
|
CrashHandler::getInstance().setAnnotation("address", currentAddress.toString().toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiscoverabilityManager::handleHeartbeatResponse(QNetworkReply* requestReply) {
|
void DiscoverabilityManager::handleHeartbeatResponse(QNetworkReply* requestReply) {
|
||||||
|
|
|
@ -57,6 +57,7 @@
|
||||||
#include "LocationBookmarks.h"
|
#include "LocationBookmarks.h"
|
||||||
#include "DeferredLightingEffect.h"
|
#include "DeferredLightingEffect.h"
|
||||||
#include "PickManager.h"
|
#include "PickManager.h"
|
||||||
|
#include "crash-handler/CrashHandler.h"
|
||||||
|
|
||||||
#include "scripting/SettingsScriptingInterface.h"
|
#include "scripting/SettingsScriptingInterface.h"
|
||||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||||
|
@ -636,12 +637,13 @@ Menu::Menu() {
|
||||||
true,
|
true,
|
||||||
&UserActivityLogger::getInstance(),
|
&UserActivityLogger::getInstance(),
|
||||||
SLOT(disable(bool)));
|
SLOT(disable(bool)));
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(networkMenu,
|
addCheckableActionToQMenuAndActionHash(networkMenu,
|
||||||
MenuOption::EnableCrashReporting,
|
MenuOption::EnableCrashReporting,
|
||||||
0,
|
0,
|
||||||
UserActivityLogger::getInstance().isCrashReportingEnabled(),
|
CrashHandler::getInstance().isEnabled(),
|
||||||
&UserActivityLogger::getInstance(),
|
&CrashHandler::getInstance(),
|
||||||
SLOT(setCrashReportingEnabled(bool)));
|
SLOT(setEnabled(bool)));
|
||||||
|
|
||||||
addActionToQMenuAndActionHash(networkMenu, MenuOption::ShowDSConnectTable, 0,
|
addActionToQMenuAndActionHash(networkMenu, MenuOption::ShowDSConnectTable, 0,
|
||||||
qApp, SLOT(loadDomainConnectionDialog()));
|
qApp, SLOT(loadDomainConnectionDialog()));
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include <shared/GlobalAppProperties.h>
|
#include <shared/GlobalAppProperties.h>
|
||||||
#include <shared/QtHelpers.h>
|
#include <shared/QtHelpers.h>
|
||||||
|
#include <crash-handler/CrashHandler.h>
|
||||||
|
|
||||||
#include "CrashHandler.h"
|
|
||||||
|
|
||||||
RenderEventHandler::RenderEventHandler(CheckCall checkCall, RenderCall renderCall) :
|
RenderEventHandler::RenderEventHandler(CheckCall checkCall, RenderCall renderCall) :
|
||||||
_checkCall(checkCall),
|
_checkCall(checkCall),
|
||||||
|
@ -29,7 +29,7 @@ RenderEventHandler::RenderEventHandler(CheckCall checkCall, RenderCall renderCal
|
||||||
void RenderEventHandler::initialize() {
|
void RenderEventHandler::initialize() {
|
||||||
setObjectName("Render");
|
setObjectName("Render");
|
||||||
PROFILE_SET_THREAD_NAME("Render");
|
PROFILE_SET_THREAD_NAME("Render");
|
||||||
setCrashAnnotation("render_thread_id", std::to_string((size_t)QThread::currentThreadId()));
|
CrashHandler::getInstance().setAnnotation("render_thread_id", std::to_string((size_t)QThread::currentThreadId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderEventHandler::resumeThread() {
|
void RenderEventHandler::resumeThread() {
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
#include "AddressManager.h"
|
#include "AddressManager.h"
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "CrashHandler.h"
|
#include "crash-handler/CrashHandler.h"
|
||||||
#include "InterfaceLogging.h"
|
#include "InterfaceLogging.h"
|
||||||
#include "UserActivityLogger.h"
|
#include "UserActivityLogger.h"
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
extern "C" {
|
extern "C" {
|
||||||
typedef int(__stdcall * CHECKMINSPECPROC) ();
|
typedef int(__stdcall* CHECKMINSPECPROC)();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ int main(int argc, const char* argv[]) {
|
||||||
// This appears to resolve the issues with corrupted fonts on OSX. No
|
// This appears to resolve the issues with corrupted fonts on OSX. No
|
||||||
// idea why.
|
// idea why.
|
||||||
qputenv("QT_ENABLE_GLYPH_CACHE_WORKAROUND", "true");
|
qputenv("QT_ENABLE_GLYPH_CACHE_WORKAROUND", "true");
|
||||||
// https://i.kym-cdn.com/entries/icons/original/000/008/342/ihave.jpg
|
// https://i.kym-cdn.com/entries/icons/original/000/008/342/ihave.jpg
|
||||||
QSurfaceFormat::setDefaultFormat(format);
|
QSurfaceFormat::setDefaultFormat(format);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -73,179 +73,88 @@ int main(int argc, const char* argv[]) {
|
||||||
QCommandLineOption helpOption = parser.addHelpOption();
|
QCommandLineOption helpOption = parser.addHelpOption();
|
||||||
QCommandLineOption versionOption = parser.addVersionOption();
|
QCommandLineOption versionOption = parser.addVersionOption();
|
||||||
|
|
||||||
QCommandLineOption urlOption(
|
QCommandLineOption urlOption("url", "Start at specified URL location.", "string");
|
||||||
"url",
|
QCommandLineOption protocolVersionOption("protocolVersion", "Writes the protocol version base64 signature to a file?",
|
||||||
"Start at specified URL location.",
|
"path");
|
||||||
"string"
|
QCommandLineOption noUpdaterOption("no-updater", "Do not show auto-updater.");
|
||||||
);
|
QCommandLineOption
|
||||||
QCommandLineOption protocolVersionOption(
|
checkMinSpecOption("checkMinSpec",
|
||||||
"protocolVersion",
|
"Check if machine meets minimum specifications. The program will run if check passes.");
|
||||||
"Writes the protocol version base64 signature to a file?",
|
QCommandLineOption runServerOption("runServer", "Run the server.");
|
||||||
"path"
|
QCommandLineOption listenPortOption("listenPort", "Port to listen on.", "port_number");
|
||||||
);
|
QCommandLineOption serverContentPathOption("serverContentPath",
|
||||||
QCommandLineOption noUpdaterOption(
|
"Path to find server content.", // What content??
|
||||||
"no-updater",
|
"path");
|
||||||
"Do not show auto-updater."
|
QCommandLineOption overrideAppLocalDataPathOption("cache", "Set test cache.", "dir");
|
||||||
);
|
QCommandLineOption scriptsOption("scripts",
|
||||||
QCommandLineOption checkMinSpecOption(
|
"Set path for defaultScripts. These are probably scripts that run automatically. This "
|
||||||
"checkMinSpec",
|
"parameter does not seem to work.",
|
||||||
"Check if machine meets minimum specifications. The program will run if check passes."
|
"dir");
|
||||||
);
|
QCommandLineOption allowMultipleInstancesOption("allowMultipleInstances", "Allow multiple instances to run.");
|
||||||
QCommandLineOption runServerOption(
|
QCommandLineOption displaysOption("display", "Preferred display.", "displays");
|
||||||
"runServer",
|
QCommandLineOption disableDisplaysOption("disable-displays",
|
||||||
"Run the server."
|
"Displays to disable. Valid options include \"OpenVR (Vive)\" and \"Oculus Rift\"",
|
||||||
);
|
"string");
|
||||||
QCommandLineOption listenPortOption(
|
QCommandLineOption disableInputsOption("disable-inputs",
|
||||||
"listenPort",
|
"Inputs to disable. Valid options include \"OpenVR (Vive)\" and \"Oculus Rift\"",
|
||||||
"Port to listen on.",
|
"string");
|
||||||
"port_number"
|
QCommandLineOption suppressSettingsResetOption("suppress-settings-reset",
|
||||||
);
|
"Suppress the prompt to reset interface settings.");
|
||||||
QCommandLineOption serverContentPathOption(
|
QCommandLineOption oculusStoreOption("oculus-store",
|
||||||
"serverContentPath",
|
"Let the Oculus plugin know if interface was run from the Oculus Store.");
|
||||||
"Path to find server content.", // What content??
|
QCommandLineOption standaloneOption("standalone", "Emulate a standalone device.");
|
||||||
"path"
|
QCommandLineOption disableWatchdogOption("disableWatchdog",
|
||||||
);
|
"Disable the watchdog thread. The interface will crash on deadlocks.");
|
||||||
QCommandLineOption overrideAppLocalDataPathOption(
|
QCommandLineOption systemCursorOption("system-cursor", "Use the default system cursor.");
|
||||||
"cache",
|
QCommandLineOption
|
||||||
"Set test cache.",
|
concurrentDownloadsOption("concurrent-downloads",
|
||||||
"dir"
|
"Maximum concurrent resource downloads. Default is 16, except for Android where it is 4.",
|
||||||
);
|
"integer");
|
||||||
QCommandLineOption scriptsOption(
|
QCommandLineOption avatarURLOption("avatarURL", "Override the avatar U.R.L.", "url");
|
||||||
"scripts",
|
QCommandLineOption replaceAvatarURLOption("replaceAvatarURL",
|
||||||
"Set path for defaultScripts. These are probably scripts that run automatically. This parameter does not seem to work.",
|
"Replaces the avatar U.R.L. When used with --avatarURL, this takes precedence.",
|
||||||
"dir"
|
"url");
|
||||||
);
|
QCommandLineOption
|
||||||
QCommandLineOption allowMultipleInstancesOption(
|
setBookmarkOption("setBookmark",
|
||||||
"allowMultipleInstances",
|
"Set bookmark as key=value pair. Including the '=' symbol in either string is unsupported.",
|
||||||
"Allow multiple instances to run."
|
"string");
|
||||||
);
|
QCommandLineOption forceCrashReportingOption("forceCrashReporting", "Force crash reporting to initialize.");
|
||||||
QCommandLineOption displaysOption(
|
|
||||||
"display",
|
|
||||||
"Preferred display.",
|
|
||||||
"displays"
|
|
||||||
);
|
|
||||||
QCommandLineOption disableDisplaysOption(
|
|
||||||
"disable-displays",
|
|
||||||
"Displays to disable. Valid options include \"OpenVR (Vive)\" and \"Oculus Rift\"",
|
|
||||||
"string"
|
|
||||||
);
|
|
||||||
QCommandLineOption disableInputsOption(
|
|
||||||
"disable-inputs",
|
|
||||||
"Inputs to disable. Valid options include \"OpenVR (Vive)\" and \"Oculus Rift\"",
|
|
||||||
"string"
|
|
||||||
);
|
|
||||||
QCommandLineOption suppressSettingsResetOption(
|
|
||||||
"suppress-settings-reset",
|
|
||||||
"Suppress the prompt to reset interface settings."
|
|
||||||
);
|
|
||||||
QCommandLineOption oculusStoreOption(
|
|
||||||
"oculus-store",
|
|
||||||
"Let the Oculus plugin know if interface was run from the Oculus Store."
|
|
||||||
);
|
|
||||||
QCommandLineOption standaloneOption(
|
|
||||||
"standalone",
|
|
||||||
"Emulate a standalone device."
|
|
||||||
);
|
|
||||||
QCommandLineOption disableWatchdogOption(
|
|
||||||
"disableWatchdog",
|
|
||||||
"Disable the watchdog thread. The interface will crash on deadlocks."
|
|
||||||
);
|
|
||||||
QCommandLineOption systemCursorOption(
|
|
||||||
"system-cursor",
|
|
||||||
"Use the default system cursor."
|
|
||||||
);
|
|
||||||
QCommandLineOption concurrentDownloadsOption(
|
|
||||||
"concurrent-downloads",
|
|
||||||
"Maximum concurrent resource downloads. Default is 16, except for Android where it is 4.",
|
|
||||||
"integer"
|
|
||||||
);
|
|
||||||
QCommandLineOption avatarURLOption(
|
|
||||||
"avatarURL",
|
|
||||||
"Override the avatar U.R.L.",
|
|
||||||
"url"
|
|
||||||
);
|
|
||||||
QCommandLineOption replaceAvatarURLOption(
|
|
||||||
"replaceAvatarURL",
|
|
||||||
"Replaces the avatar U.R.L. When used with --avatarURL, this takes precedence.",
|
|
||||||
"url"
|
|
||||||
);
|
|
||||||
QCommandLineOption setBookmarkOption(
|
|
||||||
"setBookmark",
|
|
||||||
"Set bookmark as key=value pair. Including the '=' symbol in either string is unsupported.",
|
|
||||||
"string"
|
|
||||||
);
|
|
||||||
QCommandLineOption forceCrashReportingOption(
|
|
||||||
"forceCrashReporting",
|
|
||||||
"Force crash reporting to initialize."
|
|
||||||
);
|
|
||||||
// The documented "--disable-lod" does not seem to exist.
|
// The documented "--disable-lod" does not seem to exist.
|
||||||
// Below are undocumented.
|
// Below are undocumented.
|
||||||
QCommandLineOption noLauncherOption(
|
QCommandLineOption noLauncherOption("no-launcher",
|
||||||
"no-launcher",
|
"Supposedly does something for the server, unrelated to the application launcher. The "
|
||||||
"Supposedly does something for the server, unrelated to the application launcher. The feature may never have been implemented."
|
"feature may never have been implemented.");
|
||||||
);
|
QCommandLineOption
|
||||||
QCommandLineOption overrideScriptsPathOption(
|
overrideScriptsPathOption("overrideScriptsPath",
|
||||||
"overrideScriptsPath",
|
"Specifies path to default directory where the application will look for scripts to load.",
|
||||||
"Specifies path to default directory where the application will look for scripts to load.",
|
"string");
|
||||||
"string"
|
QCommandLineOption defaultScriptsOverrideOption("defaultScriptsOverride",
|
||||||
);
|
"Override default script to run automatically on start. Default is "
|
||||||
QCommandLineOption defaultScriptsOverrideOption(
|
"\"defaultsScripts.js\".",
|
||||||
"defaultScriptsOverride",
|
"string");
|
||||||
"Override default script to run automatically on start. Default is \"defaultsScripts.js\".",
|
QCommandLineOption responseTokensOption("tokens", "Set response tokens <json>.", "json");
|
||||||
"string"
|
QCommandLineOption displayNameOption("displayName", "Set user display name <string>.", "string");
|
||||||
);
|
QCommandLineOption noLoginOption("no-login-suggestion", "Do not show log-in dialogue.");
|
||||||
QCommandLineOption responseTokensOption(
|
QCommandLineOption
|
||||||
"tokens",
|
traceFileOption("traceFile",
|
||||||
"Set response tokens <json>.",
|
"Writes a trace to a file in the documents folder. Only works if \"--traceDuration\" is specified.",
|
||||||
"json"
|
"path");
|
||||||
);
|
QCommandLineOption
|
||||||
QCommandLineOption displayNameOption(
|
traceDurationOption("traceDuration",
|
||||||
"displayName",
|
"Automatically quit interface after duration. Only works if \"--traceFile\" is specified.",
|
||||||
"Set user display name <string>.",
|
"seconds");
|
||||||
"string"
|
QCommandLineOption clockSkewOption("clockSkew", "Forces client instance's clock to skew for demonstration purposes.",
|
||||||
);
|
"integer"); // This should probably be removed.
|
||||||
QCommandLineOption noLoginOption(
|
QCommandLineOption testScriptOption("testScript", "Undocumented. Accepts parameter as U.R.L.", "string");
|
||||||
"no-login-suggestion",
|
QCommandLineOption testResultsLocationOption("testResultsLocation", "Undocumented", "path");
|
||||||
"Do not show log-in dialogue."
|
|
||||||
);
|
|
||||||
QCommandLineOption traceFileOption(
|
|
||||||
"traceFile",
|
|
||||||
"Writes a trace to a file in the documents folder. Only works if \"--traceDuration\" is specified.",
|
|
||||||
"path"
|
|
||||||
);
|
|
||||||
QCommandLineOption traceDurationOption(
|
|
||||||
"traceDuration",
|
|
||||||
"Automatically quit interface after duration. Only works if \"--traceFile\" is specified.",
|
|
||||||
"seconds"
|
|
||||||
);
|
|
||||||
QCommandLineOption clockSkewOption(
|
|
||||||
"clockSkew",
|
|
||||||
"Forces client instance's clock to skew for demonstration purposes.",
|
|
||||||
"integer"
|
|
||||||
); // This should probably be removed.
|
|
||||||
QCommandLineOption testScriptOption(
|
|
||||||
"testScript",
|
|
||||||
"Undocumented. Accepts parameter as U.R.L.",
|
|
||||||
"string"
|
|
||||||
);
|
|
||||||
QCommandLineOption testResultsLocationOption(
|
|
||||||
"testResultsLocation",
|
|
||||||
"Undocumented",
|
|
||||||
"path"
|
|
||||||
);
|
|
||||||
QCommandLineOption quitWhenFinishedOption(
|
QCommandLineOption quitWhenFinishedOption(
|
||||||
"quitWhenFinished",
|
"quitWhenFinished",
|
||||||
"Only works if \"--testScript\" is provided."
|
"Only works if \"--testScript\" is provided."); // Should probably also be made to work on testResultsLocationOption.
|
||||||
); // Should probably also be made to work on testResultsLocationOption.
|
QCommandLineOption fastHeartbeatOption("fast-heartbeat", "Change stats polling interval from 10000ms to 1000ms.");
|
||||||
QCommandLineOption fastHeartbeatOption(
|
QCommandLineOption logOption("logOptions",
|
||||||
"fast-heartbeat",
|
"Logging options, comma separated: "
|
||||||
"Change stats polling interval from 10000ms to 1000ms."
|
"color,nocolor,process_id,thread_id,milliseconds,keep_repeats,journald,nojournald",
|
||||||
);
|
"options");
|
||||||
QCommandLineOption logOption(
|
|
||||||
"logOptions",
|
|
||||||
"Logging options, comma separated: color,nocolor,process_id,thread_id,milliseconds,keep_repeats,journald,nojournald",
|
|
||||||
"options"
|
|
||||||
);
|
|
||||||
// "--qmljsdebugger", which appears in output from "--help-all".
|
// "--qmljsdebugger", which appears in output from "--help-all".
|
||||||
// Those below don't seem to be optional.
|
// Those below don't seem to be optional.
|
||||||
// --ignore-gpu-blacklist
|
// --ignore-gpu-blacklist
|
||||||
|
@ -296,7 +205,7 @@ int main(int argc, const char* argv[]) {
|
||||||
{
|
{
|
||||||
QCoreApplication tempApp(argc, const_cast<char**>(argv));
|
QCoreApplication tempApp(argc, const_cast<char**>(argv));
|
||||||
|
|
||||||
parser.process(QCoreApplication::arguments()); // Must be run after QCoreApplication is initalised.
|
parser.process(QCoreApplication::arguments()); // Must be run after QCoreApplication is initalised.
|
||||||
|
|
||||||
#ifdef Q_OS_OSX
|
#ifdef Q_OS_OSX
|
||||||
if (QFileInfo::exists(QCoreApplication::applicationDirPath() + "/../../../config.json")) {
|
if (QFileInfo::exists(QCoreApplication::applicationDirPath() + "/../../../config.json")) {
|
||||||
|
@ -310,10 +219,10 @@ int main(int argc, const char* argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We want to configure the logging system as early as possible
|
// We want to configure the logging system as early as possible
|
||||||
auto &logHandler = LogHandler::getInstance();
|
auto& logHandler = LogHandler::getInstance();
|
||||||
if (parser.isSet(logOption)) {
|
if (parser.isSet(logOption)) {
|
||||||
if (!logHandler.parseOptions(parser.value(logOption).toUtf8(), logOption.names().first())) {
|
if (!logHandler.parseOptions(parser.value(logOption).toUtf8(), logOption.names().first())) {
|
||||||
QCoreApplication mockApp(argc, const_cast<char**>(argv)); // required for call to showHelp()
|
QCoreApplication mockApp(argc, const_cast<char**>(argv)); // required for call to showHelp()
|
||||||
parser.showHelp();
|
parser.showHelp();
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -325,7 +234,7 @@ int main(int argc, const char* argv[]) {
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
if (parser.isSet(helpOption)) {
|
if (parser.isSet(helpOption)) {
|
||||||
QCoreApplication mockApp(argc, const_cast<char**>(argv)); // required for call to showHelp()
|
QCoreApplication mockApp(argc, const_cast<char**>(argv)); // required for call to showHelp()
|
||||||
parser.showHelp();
|
parser.showHelp();
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -378,7 +287,7 @@ int main(int argc, const char* argv[]) {
|
||||||
|
|
||||||
// Early check for --traceFile argument
|
// Early check for --traceFile argument
|
||||||
auto tracer = DependencyManager::set<tracing::Tracer>();
|
auto tracer = DependencyManager::set<tracing::Tracer>();
|
||||||
const char * traceFile = nullptr;
|
const char* traceFile = nullptr;
|
||||||
float traceDuration = 0.0f;
|
float traceDuration = 0.0f;
|
||||||
if (parser.isSet(traceFileOption)) {
|
if (parser.isSet(traceFileOption)) {
|
||||||
traceFile = parser.value(traceFileOption).toStdString().c_str();
|
traceFile = parser.value(traceFileOption).toStdString().c_str();
|
||||||
|
@ -412,6 +321,8 @@ int main(int argc, const char* argv[]) {
|
||||||
|
|
||||||
// Instance UserActivityLogger now that the settings are loaded
|
// Instance UserActivityLogger now that the settings are loaded
|
||||||
auto& ual = UserActivityLogger::getInstance();
|
auto& ual = UserActivityLogger::getInstance();
|
||||||
|
auto& ch = CrashHandler::getInstance();
|
||||||
|
|
||||||
// once the settings have been loaded, check if we need to flip the default for UserActivityLogger
|
// once the settings have been loaded, check if we need to flip the default for UserActivityLogger
|
||||||
if (!ual.isDisabledSettingSet()) {
|
if (!ual.isDisabledSettingSet()) {
|
||||||
// the user activity logger is opt-out for Interface
|
// the user activity logger is opt-out for Interface
|
||||||
|
@ -423,13 +334,12 @@ int main(int argc, const char* argv[]) {
|
||||||
|
|
||||||
if (parser.isSet(forceCrashReportingOption)) {
|
if (parser.isSet(forceCrashReportingOption)) {
|
||||||
qInfo() << "Crash reporting enabled on the command-line";
|
qInfo() << "Crash reporting enabled on the command-line";
|
||||||
ual.setCrashReportingEnabled(true);
|
ch.setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto crashHandlerStarted = startCrashHandler(argv[0]);
|
auto crashHandlerStarted = ch.start(argv[0]);
|
||||||
if (crashHandlerStarted) {
|
if (crashHandlerStarted) {
|
||||||
ual.setCrashMonitorStarted(true);
|
qDebug() << "Crash handler started";
|
||||||
qDebug() << "Crash handler started:" << crashHandlerStarted;
|
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "Crash handler failed to start";
|
qWarning() << "Crash handler failed to start";
|
||||||
}
|
}
|
||||||
|
@ -472,9 +382,9 @@ int main(int argc, const char* argv[]) {
|
||||||
if (socket.waitForConnected(LOCAL_SERVER_TIMEOUT_MS)) {
|
if (socket.waitForConnected(LOCAL_SERVER_TIMEOUT_MS)) {
|
||||||
if (parser.isSet(urlOption)) {
|
if (parser.isSet(urlOption)) {
|
||||||
QUrl url = QUrl(parser.value(urlOption));
|
QUrl url = QUrl(parser.value(urlOption));
|
||||||
if (url.isValid() && (url.scheme() == URL_SCHEME_OVERTE || url.scheme() == URL_SCHEME_OVERTEAPP
|
if (url.isValid() && (url.scheme() == URL_SCHEME_OVERTE || url.scheme() == URL_SCHEME_OVERTEAPP ||
|
||||||
|| url.scheme() == HIFI_URL_SCHEME_HTTP || url.scheme() == HIFI_URL_SCHEME_HTTPS
|
url.scheme() == HIFI_URL_SCHEME_HTTP || url.scheme() == HIFI_URL_SCHEME_HTTPS ||
|
||||||
|| url.scheme() == HIFI_URL_SCHEME_FILE)) {
|
url.scheme() == HIFI_URL_SCHEME_FILE)) {
|
||||||
qDebug() << "Writing URL to local socket";
|
qDebug() << "Writing URL to local socket";
|
||||||
socket.write(url.toString().toUtf8());
|
socket.write(url.toString().toUtf8());
|
||||||
if (!socket.waitForBytesWritten(5000)) {
|
if (!socket.waitForBytesWritten(5000)) {
|
||||||
|
@ -495,7 +405,6 @@ int main(int argc, const char* argv[]) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIXME this method of checking the OpenGL version screws up the `QOpenGLContext::globalShareContext()` value, which in turn
|
// FIXME this method of checking the OpenGL version screws up the `QOpenGLContext::globalShareContext()` value, which in turn
|
||||||
// leads to crashes when creating the real OpenGL instance. Disabling for now until we come up with a better way of checking
|
// leads to crashes when creating the real OpenGL instance. Disabling for now until we come up with a better way of checking
|
||||||
// the GL version on the system without resorting to creating a full Qt application
|
// the GL version on the system without resorting to creating a full Qt application
|
||||||
|
@ -522,7 +431,6 @@ int main(int argc, const char* argv[]) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Debug option to demonstrate that the client's local time does not
|
// Debug option to demonstrate that the client's local time does not
|
||||||
// need to be in sync with any other network node. This forces clock
|
// need to be in sync with any other network node. This forces clock
|
||||||
// skew for the individual client
|
// skew for the individual client
|
||||||
|
@ -590,7 +498,8 @@ int main(int argc, const char* argv[]) {
|
||||||
#if defined(Q_OS_LINUX)
|
#if defined(Q_OS_LINUX)
|
||||||
app.setWindowIcon(QIcon(PathUtils::resourcesPath() + "images/brand-logo.svg"));
|
app.setWindowIcon(QIcon(PathUtils::resourcesPath() + "images/brand-logo.svg"));
|
||||||
#endif
|
#endif
|
||||||
startCrashHookMonitor(&app);
|
ch.startMonitor(&app);
|
||||||
|
|
||||||
|
|
||||||
QTimer exitTimer;
|
QTimer exitTimer;
|
||||||
if (traceDuration > 0.0f) {
|
if (traceDuration > 0.0f) {
|
||||||
|
@ -618,14 +527,14 @@ int main(int argc, const char* argv[]) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Setup local server
|
// Setup local server
|
||||||
QLocalServer server { &app };
|
QLocalServer server{ &app };
|
||||||
|
|
||||||
// We failed to connect to a local server, so we remove any existing servers.
|
// We failed to connect to a local server, so we remove any existing servers.
|
||||||
server.removeServer(applicationName);
|
server.removeServer(applicationName);
|
||||||
server.listen(applicationName);
|
server.listen(applicationName);
|
||||||
|
|
||||||
QObject::connect(&server, &QLocalServer::newConnection,
|
QObject::connect(&server, &QLocalServer::newConnection, &app, &Application::handleLocalServerConnection,
|
||||||
&app, &Application::handleLocalServerConnection, Qt::DirectConnection);
|
Qt::DirectConnection);
|
||||||
|
|
||||||
printSystemInformation();
|
printSystemInformation();
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,6 @@ link_hifi_libraries(shared networking)
|
||||||
add_crashpad()
|
add_crashpad()
|
||||||
target_breakpad()
|
target_breakpad()
|
||||||
|
|
||||||
|
|
||||||
if (UNIX AND NOT APPLE)
|
|
||||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
|
||||||
find_package(Threads REQUIRED)
|
|
||||||
target_link_libraries(Threads::Threads)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
add_compile_definitions(_USE_MATH_DEFINES)
|
add_compile_definitions(_USE_MATH_DEFINES)
|
||||||
endif()
|
endif()
|
||||||
|
|
61
libraries/monitoring/src/crash-handler/CrashHandler.cpp
Normal file
61
libraries/monitoring/src/crash-handler/CrashHandler.cpp
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
//
|
||||||
|
// CrashHandler.cpp
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Dale Glass on 25/06/2023.
|
||||||
|
// Copyright 2023 Overte e.V.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "CrashHandler.h"
|
||||||
|
#include "CrashHandlerBackend.h"
|
||||||
|
|
||||||
|
|
||||||
|
CrashHandler& CrashHandler::getInstance() {
|
||||||
|
static CrashHandler sharedInstance;
|
||||||
|
return sharedInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CrashHandler::start(const QString &path) {
|
||||||
|
if (isStarted()) {
|
||||||
|
qCWarning(crash_handler) << "Crash handler already started";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto started = startCrashHandler(path.toStdString());
|
||||||
|
setStarted(started);
|
||||||
|
|
||||||
|
if ( started ) {
|
||||||
|
qCInfo(crash_handler) << "Crash handler started";
|
||||||
|
} else {
|
||||||
|
qCWarning(crash_handler) << "Crash handler failed to start";
|
||||||
|
}
|
||||||
|
|
||||||
|
return started;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CrashHandler::startMonitor(QCoreApplication *app) {
|
||||||
|
startCrashHookMonitor(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CrashHandler::setEnabled(bool enabled) {
|
||||||
|
if (enabled != _crashReportingEnabled.get()) {
|
||||||
|
_crashReportingEnabled.set(enabled);
|
||||||
|
|
||||||
|
setCrashReportingEnabled(enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CrashHandler::setAnnotation(const std::string &key, const char *value) {
|
||||||
|
setCrashAnnotation(key, std::string(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CrashHandler::setAnnotation(const std::string &key, const QString &value) {
|
||||||
|
setCrashAnnotation(key, value.toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CrashHandler::setAnnotation(const std::string &key, const std::string &value) {
|
||||||
|
setCrashAnnotation(key, value);
|
||||||
|
}
|
|
@ -1,27 +1,107 @@
|
||||||
//
|
//
|
||||||
// CrashHandler.h
|
// CrashHandler.cpp
|
||||||
// interface/src
|
|
||||||
//
|
//
|
||||||
// Created by Clement Brisset on 01/19/18.
|
//
|
||||||
// Copyright 2018 High Fidelity, Inc.
|
// Created by Dale Glass on 25/06/2023.
|
||||||
|
// Copyright 2023 Overte e.V.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef hifi_CrashHandler_h
|
#pragma once
|
||||||
#define hifi_CrashHandler_h
|
|
||||||
|
|
||||||
#include <string>
|
#include <QObject>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QLoggingCategory>
|
#include <SettingHandle.h>
|
||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(crash_handler)
|
|
||||||
|
|
||||||
bool startCrashHandler(std::string appPath);
|
|
||||||
void setCrashAnnotation(std::string name, std::string value);
|
/**
|
||||||
void startCrashHookMonitor(QCoreApplication* app);
|
* @brief The global object in charge of setting up and controlling crash reporting.
|
||||||
void setCrashReportingEnabled(bool value);
|
*
|
||||||
|
* This object initializes and talks to crash reporting backends.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class CrashHandler : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
static CrashHandler& getInstance();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Start the crash handler
|
||||||
|
*
|
||||||
|
* @param path Database path
|
||||||
|
* @return true Started successfully
|
||||||
|
* @return false Failed to start
|
||||||
|
*/
|
||||||
|
bool start(const QString &path);
|
||||||
|
|
||||||
|
|
||||||
|
void startMonitor(QCoreApplication *app);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Whether the crash monitor has been successfully started
|
||||||
|
*
|
||||||
|
* Reasons for it failing to start include:
|
||||||
|
*
|
||||||
|
* * Not having a crash reporter for the platform
|
||||||
|
* * Crash reporter not being configured with reporting URLs (CMAKE_BACKTRACE_TOKEN and CMAKE_BACKTRACE_URL)
|
||||||
|
* * Crash reporter is present and configured, but failed to initialize for some reason
|
||||||
|
*
|
||||||
|
* @return true Crash reporter is present, configured and working.
|
||||||
|
* @return false Crash reporter has not been started for one of the above reasons.
|
||||||
|
*/
|
||||||
|
bool isStarted() const { return _crashMonitorStarted; }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Whether the crash monitor will report crashes if they occur
|
||||||
|
*
|
||||||
|
* This setting is independent of isCrashMonitorStarted() -- crash reporting may be enabled but fail to work
|
||||||
|
* due to the crash reporting component being missing or failing to initialize.
|
||||||
|
*
|
||||||
|
* @return true Crashes will be reported to CMAKE_BACKTRACE_URL
|
||||||
|
* @return false Crashes will not be reported
|
||||||
|
*/
|
||||||
|
bool isEnabled() const { return _crashReportingEnabled.get(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set whether we want to submit crash reports to the report server
|
||||||
|
*
|
||||||
|
* The report server is configured with CMAKE_BACKTRACE_URL.
|
||||||
|
* Emits crashReportingEnabledChanged signal.
|
||||||
|
*
|
||||||
|
* @param enabled Whether it's enabled.
|
||||||
|
*/
|
||||||
|
void setEnabled(bool enabled);
|
||||||
|
|
||||||
|
|
||||||
|
void setAnnotation(const std::string &key, const char *value);
|
||||||
|
void setAnnotation(const std::string &key, const QString &value);
|
||||||
|
void setAnnotation(const std::string &key, const std::string &value);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Marks the crash monitor as started
|
||||||
|
*
|
||||||
|
* @warning Only to be used as part of the startup process
|
||||||
|
*
|
||||||
|
* @param started
|
||||||
|
*/
|
||||||
|
void setStarted(bool started) { _crashMonitorStarted = started; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Setting::Handle<bool> _crashReportingEnabled { "CrashReportingEnabled", false };
|
||||||
|
bool _crashMonitorStarted {false};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // hifi_CrashHandler_h
|
|
||||||
|
|
27
libraries/monitoring/src/crash-handler/CrashHandlerBackend.h
Normal file
27
libraries/monitoring/src/crash-handler/CrashHandlerBackend.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
//
|
||||||
|
// CrashHandler.h
|
||||||
|
// interface/src
|
||||||
|
//
|
||||||
|
// Created by Clement Brisset on 01/19/18.
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_CrashHandlerBackend_h
|
||||||
|
#define hifi_CrashHandlerBackend_h
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(crash_handler)
|
||||||
|
|
||||||
|
bool startCrashHandler(std::string appPath);
|
||||||
|
void setCrashAnnotation(std::string name, std::string value);
|
||||||
|
void startCrashHookMonitor(QCoreApplication* app);
|
||||||
|
void setCrashReportingEnabled(bool value);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // hifi_CrashHandlerBackend_h
|
|
@ -421,12 +421,12 @@ bool startCrashHandler(std::string appPath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable automated uploads.
|
// Enable automated uploads.
|
||||||
QObject::connect(&UserActivityLogger::getInstance(), &UserActivityLogger::crashReportingEnabledChanged, []() {
|
// QObject::connect(&UserActivityLogger::getInstance(), &UserActivityLogger::crashReportingEnabledChanged, []() {
|
||||||
auto &ual = UserActivityLogger::getInstance();
|
// auto &ual = UserActivityLogger::getInstance();
|
||||||
setCrashReportingEnabled(ual.isCrashReportingEnabled());
|
// setCrashReportingEnabled(ual.isCrashReportingEnabled());
|
||||||
});
|
// });
|
||||||
|
|
||||||
crashpadDatabase->GetSettings()->SetUploadsEnabled(UserActivityLogger::getInstance().isCrashReportingEnabled());
|
crashpadDatabase->GetSettings()->SetUploadsEnabled(CrashHandler::getInstance().isEnabled());
|
||||||
|
|
||||||
|
|
||||||
if (!client->StartHandler(handler, db, db, BACKTRACE_URL, annotations, arguments, true, true)) {
|
if (!client->StartHandler(handler, db, db, BACKTRACE_URL, annotations, arguments, true, true)) {
|
|
@ -82,15 +82,6 @@ void UserActivityLogger::requestError(QNetworkReply* errorReply) {
|
||||||
qCDebug(networking) << errorReply->error() << "-" << errorReply->errorString();
|
qCDebug(networking) << errorReply->error() << "-" << errorReply->errorString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserActivityLogger::setCrashReportingEnabled(bool enabled) {
|
|
||||||
bool old = _crashReportingEnabled.get();
|
|
||||||
_crashReportingEnabled.set(enabled);
|
|
||||||
|
|
||||||
if (old != enabled) {
|
|
||||||
emit crashReportingEnabledChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UserActivityLogger::launch(QString applicationVersion, bool previousSessionCrashed, int previousSessionRuntime) {
|
void UserActivityLogger::launch(QString applicationVersion, bool previousSessionCrashed, int previousSessionRuntime) {
|
||||||
const QString ACTION_NAME = "launch";
|
const QString ACTION_NAME = "launch";
|
||||||
QJsonObject actionDetails;
|
QJsonObject actionDetails;
|
|
@ -36,51 +36,6 @@ public slots:
|
||||||
bool isDisabledSettingSet() const { return _disabled.isSet(); }
|
bool isDisabledSettingSet() const { return _disabled.isSet(); }
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Whether the crash monitor has been successfully started
|
|
||||||
*
|
|
||||||
* Reasons for it failing to start include:
|
|
||||||
*
|
|
||||||
* * Not having a crash reporter for the platform
|
|
||||||
* * Crash reporter not being configured with reporting URLs (CMAKE_BACKTRACE_TOKEN and CMAKE_BACKTRACE_URL)
|
|
||||||
* * Crash reporter is present and configured, but failed to initialize for some reason
|
|
||||||
*
|
|
||||||
* @return true Crash reporter is present, configured and working.
|
|
||||||
* @return false Crash reporter has not been started for one of the above reasons.
|
|
||||||
*/
|
|
||||||
bool isCrashMonitorStarted() const { return _crashMonitorStarted; }
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Whether the crash monitor will report crashes if they occur
|
|
||||||
*
|
|
||||||
* This setting is independent of isCrashMonitorStarted() -- crash reporting may be enabled but fail to work
|
|
||||||
* due to the crash reporting component being missing or failing to initialize.
|
|
||||||
*
|
|
||||||
* @return true Crashes will be reported to CMAKE_BACKTRACE_URL
|
|
||||||
* @return false Crashes will not be reported
|
|
||||||
*/
|
|
||||||
bool isCrashReportingEnabled() { return _crashReportingEnabled.get(); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Marks the crash monitor as started
|
|
||||||
*
|
|
||||||
* @warning Only to be used as part of the startup process
|
|
||||||
*
|
|
||||||
* @param started
|
|
||||||
*/
|
|
||||||
void setCrashMonitorStarted(bool started) { _crashMonitorStarted = started; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set whether we want to submit crash reports to the report server
|
|
||||||
*
|
|
||||||
* The report server is configured with CMAKE_BACKTRACE_URL.
|
|
||||||
* Emits crashReportingEnabledChanged signal.
|
|
||||||
*
|
|
||||||
* @param enabled Whether it's enabled.
|
|
||||||
*/
|
|
||||||
void setCrashReportingEnabled(bool enabled);
|
|
||||||
|
|
||||||
void disable(bool disable);
|
void disable(bool disable);
|
||||||
void logAction(QString action, QJsonObject details = QJsonObject(), JSONCallbackParameters params = JSONCallbackParameters());
|
void logAction(QString action, QJsonObject details = QJsonObject(), JSONCallbackParameters params = JSONCallbackParameters());
|
||||||
|
|
||||||
|
@ -111,9 +66,9 @@ private slots:
|
||||||
private:
|
private:
|
||||||
UserActivityLogger();
|
UserActivityLogger();
|
||||||
Setting::Handle<bool> _disabled { "UserActivityLoggerDisabled", true };
|
Setting::Handle<bool> _disabled { "UserActivityLoggerDisabled", true };
|
||||||
Setting::Handle<bool> _crashReportingEnabled { "CrashReportingEnabled", false };
|
|
||||||
|
|
||||||
bool _crashMonitorStarted {false};
|
|
||||||
|
|
||||||
QElapsedTimer _timer;
|
QElapsedTimer _timer;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue