added setting to restart on SIGSEGV

This commit is contained in:
fourtf 2019-09-22 15:32:36 +02:00
parent 7e555843ca
commit 431d35e528
6 changed files with 96 additions and 44 deletions

View file

@ -32,7 +32,9 @@
#include "singletons/WindowManager.hpp" #include "singletons/WindowManager.hpp"
#include "util/IsBigEndian.hpp" #include "util/IsBigEndian.hpp"
#include "util/PostToThread.hpp" #include "util/PostToThread.hpp"
#include "widgets/Notebook.hpp"
#include "widgets/Window.hpp" #include "widgets/Window.hpp"
#include "widgets/splits/Split.hpp"
namespace chatterino { namespace chatterino {
@ -78,13 +80,35 @@ void Application::initialize(Settings &settings, Paths &paths)
assert(isAppInitialized == false); assert(isAppInitialized == false);
isAppInitialized = true; isAppInitialized = true;
Irc::getInstance().load(); //Irc::getInstance().load();
for (auto &singleton : this->singletons_) for (auto &singleton : this->singletons_)
{ {
singleton->initialize(settings, paths); singleton->initialize(settings, paths);
} }
// add crash message
if (getArgs().crashRecovery)
{
if (auto selected =
this->windows->getMainWindow().getNotebook().getSelectedPage())
{
if (auto container = dynamic_cast<SplitContainer *>(selected))
{
for (auto &&split : container->getSplits())
{
if (auto channel = split->getChannel(); !channel->isEmpty())
{
channel->addMessage(makeSystemMessage(
"Chatterino unexpectedly crashed and restarted. "
"You can disable automatic restarts in the "
"settings."));
}
}
}
}
}
this->windows->updateWordTypeMask(); this->windows->updateWordTypeMask();
this->initNm(paths); this->initNm(paths);

View file

@ -4,11 +4,14 @@
#include <QFile> #include <QFile>
#include <QPalette> #include <QPalette>
#include <QStyleFactory> #include <QStyleFactory>
#include <Qt>
#include <csignal>
#include "Application.hpp" #include "Application.hpp"
#include "common/NetworkManager.hpp" #include "common/NetworkManager.hpp"
#include "singletons/Paths.hpp" #include "singletons/Paths.hpp"
#include "singletons/Resources.hpp" #include "singletons/Resources.hpp"
#include "singletons/Settings.hpp"
#include "singletons/Updates.hpp" #include "singletons/Updates.hpp"
#include "util/CombinePath.hpp" #include "util/CombinePath.hpp"
#include "widgets/dialogs/LastRunCrashDialog.hpp" #include "widgets/dialogs/LastRunCrashDialog.hpp"
@ -21,12 +24,6 @@
# include <QBreakpadHandler.h> # include <QBreakpadHandler.h>
#endif #endif
// void initQt();
// void installCustomPalette();
// void showLastCrashDialog();
// void createRunningFile(const QString &path);
// void removeRunningFile(const QString &path);
namespace chatterino { namespace chatterino {
namespace { namespace {
void installCustomPalette() void installCustomPalette()
@ -109,13 +106,50 @@ namespace {
{ {
QFile::remove(path); QFile::remove(path);
} }
std::chrono::steady_clock::time_point signalsInitTime;
bool restartOnSignal = false;
[[noreturn]] void handleSignal(int signum)
{
using namespace std::chrono_literals;
// if (std::chrono::steady_clock::now() - signalsInitTime > 30s)
// {
QProcess proc;
proc.setProgram(QApplication::applicationFilePath());
proc.setArguments({"--crash-recovery"});
proc.startDetached();
// QProcess::startDetached(QApplication::applicationFilePath(),
// {"--crash-recovery"});
// }
_exit(signum);
}
// We want to restart chatterino when it crashes and the setting is set to
// true.
void initSignalHandler()
{
//#if not defined(DEBUG) && not defined(_DEBUG) && not defined(NDEBUG)
signalsInitTime = std::chrono::steady_clock::now();
// signal(SIGINT, handleSignal);
signal(SIGSEGV, handleSignal);
// signal(SIGABRT_COMPAT, handleSignal);
//#endif
}
} // namespace } // namespace
void runGui(QApplication &a, Paths &paths, Settings &settings) void runGui(QApplication &a, Paths &paths, Settings &settings)
{ {
initQt(); initQt();
initResources(); initResources();
initSignalHandler();
settings.restartOnCrash.connect(
[](const bool &value) { restartOnSignal = value; });
auto thread = std::thread([dir = paths.miscDirectory] { auto thread = std::thread([dir = paths.miscDirectory] {
{ {

View file

@ -1,13 +1,14 @@
#include "BrowserExtension.hpp"
#include "RunGui.hpp"
#include "singletons/Paths.hpp"
#include "singletons/Settings.hpp"
#include "util/IncognitoBrowser.hpp"
#include <QApplication> #include <QApplication>
#include <QStringList> #include <QStringList>
#include <memory> #include <memory>
#include "BrowserExtension.hpp"
#include "RunGui.hpp"
#include "common/Args.hpp"
#include "singletons/Paths.hpp"
#include "singletons/Settings.hpp"
#include "util/IncognitoBrowser.hpp"
using namespace chatterino; using namespace chatterino;
int main(int argc, char **argv) int main(int argc, char **argv)

View file

@ -1,15 +1,14 @@
#pragma once #pragma once
#include "BaseSettings.hpp" #include <pajlada/settings/setting.hpp>
#include <pajlada/settings/settinglistener.hpp>
#include "BaseSettings.hpp"
#include "common/Channel.hpp" #include "common/Channel.hpp"
#include "controllers/highlights/HighlightPhrase.hpp" #include "controllers/highlights/HighlightPhrase.hpp"
#include "controllers/moderationactions/ModerationAction.hpp" #include "controllers/moderationactions/ModerationAction.hpp"
#include "singletons/Toasts.hpp" #include "singletons/Toasts.hpp"
#include <pajlada/settings/setting.hpp>
#include <pajlada/settings/settinglistener.hpp>
namespace chatterino { namespace chatterino {
class Settings : public ABSettings class Settings : public ABSettings
@ -213,6 +212,7 @@ public:
BoolSetting openLinksIncognito = {"/misc/openLinksIncognito", 0}; BoolSetting openLinksIncognito = {"/misc/openLinksIncognito", 0};
QStringSetting cachePath = {"/cache/path", ""}; QStringSetting cachePath = {"/cache/path", ""};
BoolSetting restartOnCrash = {"/misc/restartOnCrash", true};
/// Debug /// Debug
BoolSetting showUnhandledIrcMessages = {"/debug/showUnhandledIrcMessages", BoolSetting showUnhandledIrcMessages = {"/debug/showUnhandledIrcMessages",

View file

@ -1,5 +1,16 @@
#include "singletons/WindowManager.hpp" #include "singletons/WindowManager.hpp"
#include <QDebug>
#include <QDesktopWidget>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMessageBox>
#include <QSaveFile>
#include <QScreen>
#include <boost/optional.hpp>
#include <chrono>
#include "Application.hpp" #include "Application.hpp"
#include "debug/AssertInGuiThread.hpp" #include "debug/AssertInGuiThread.hpp"
#include "debug/Log.hpp" #include "debug/Log.hpp"
@ -21,18 +32,6 @@
#include "widgets/splits/Split.hpp" #include "widgets/splits/Split.hpp"
#include "widgets/splits/SplitContainer.hpp" #include "widgets/splits/SplitContainer.hpp"
#include <QDebug>
#include <QDesktopWidget>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMessageBox>
#include <QSaveFile>
#include <QScreen>
#include <boost/optional.hpp>
#include <chrono>
#define SETTINGS_FILENAME "/window-layout.json" #define SETTINGS_FILENAME "/window-layout.json"
namespace chatterino { namespace chatterino {
@ -556,8 +555,7 @@ void WindowManager::encodeNodeRecusively(SplitNode *node, QJsonObject &obj)
{ {
switch (node->getType()) switch (node->getType())
{ {
case SplitNode::_Split: case SplitNode::_Split: {
{
obj.insert("type", "split"); obj.insert("type", "split");
obj.insert("moderationMode", node->getSplit()->getModerationMode()); obj.insert("moderationMode", node->getSplit()->getModerationMode());
QJsonObject split; QJsonObject split;
@ -568,8 +566,7 @@ void WindowManager::encodeNodeRecusively(SplitNode *node, QJsonObject &obj)
} }
break; break;
case SplitNode::HorizontalContainer: case SplitNode::HorizontalContainer:
case SplitNode::VerticalContainer: case SplitNode::VerticalContainer: {
{
obj.insert("type", node->getType() == SplitNode::HorizontalContainer obj.insert("type", node->getType() == SplitNode::HorizontalContainer
? "horizontal" ? "horizontal"
: "vertical"); : "vertical");
@ -593,29 +590,24 @@ void WindowManager::encodeChannel(IndirectChannel channel, QJsonObject &obj)
switch (channel.getType()) switch (channel.getType())
{ {
case Channel::Type::Twitch: case Channel::Type::Twitch: {
{
obj.insert("type", "twitch"); obj.insert("type", "twitch");
obj.insert("name", channel.get()->getName()); obj.insert("name", channel.get()->getName());
} }
break; break;
case Channel::Type::TwitchMentions: case Channel::Type::TwitchMentions: {
{
obj.insert("type", "mentions"); obj.insert("type", "mentions");
} }
break; break;
case Channel::Type::TwitchWatching: case Channel::Type::TwitchWatching: {
{
obj.insert("type", "watching"); obj.insert("type", "watching");
} }
break; break;
case Channel::Type::TwitchWhispers: case Channel::Type::TwitchWhispers: {
{
obj.insert("type", "whispers"); obj.insert("type", "whispers");
} }
break; break;
case Channel::Type::Irc: case Channel::Type::Irc: {
{
if (auto ircChannel = if (auto ircChannel =
dynamic_cast<IrcChannel *>(channel.get().get())) dynamic_cast<IrcChannel *>(channel.get().get()))
{ {

View file

@ -303,6 +303,7 @@ void GeneralPage::initLayout(SettingsLayout &layout)
#ifdef USEWINSDK #ifdef USEWINSDK
layout.addCheckbox("Start with Windows", s.autorun); layout.addCheckbox("Start with Windows", s.autorun);
#endif #endif
layout.addCheckbox("Restart on crash", s.restartOnCrash);
layout.addTitle("Chat"); layout.addTitle("Chat");