debugged a crash, keys are now fetching, refactored main, added some exceptions instead of ints, debugged termination process

This commit is contained in:
Blue 2023-03-11 19:46:23 +03:00
parent 927bdf0dab
commit 4b68da458f
Signed by untrusted user: blue
GPG Key ID: 9B203B252A63EE38
9 changed files with 321 additions and 130 deletions

View File

@ -32,6 +32,12 @@ public:
infoForUser, infoForUser,
ownInfoForUser ownInfoForUser
}; };
inline static constexpr const char * const TypeString[] = {
"cardInternal",
"ownCardInternal",
"infoForUser",
"ownInfoForUser"
};
protected: protected:
Job(Id id, Type type); Job(Id id, Type type);
Job(const Job& other); Job(const Job& other);

View File

@ -67,8 +67,13 @@ void Core::DelayManager::Manager::getInfo(const QString& jid) {
Job* job = nullptr; Job* job = nullptr;
#ifdef WITH_OMEMO #ifdef WITH_OMEMO
std::map<QString, Job::Id>::const_iterator bitr = requestedBundles.find(jid); std::map<QString, Job::Id>::const_iterator bitr = requestedBundles.find(jid);
if (bitr != requestedBundles.end()) if (bitr != requestedBundles.end()) {
job = runningJobs.at(bitr->second); std::map<Job::Id, Job*>::const_iterator itr = runningJobs.find(bitr->second);
if (itr == runningJobs.end())
throw JobNotFound(bitr->second);
job = itr->second;
}
else else
#endif #endif
job = getVCardJob(jid); job = getVCardJob(jid);
@ -109,10 +114,19 @@ Core::DelayManager::Job* Core::DelayManager::Manager::getVCardJob(const QString&
std::map<QString, Job::Id>::const_iterator sitr = scheduledVCards.find(jid); std::map<QString, Job::Id>::const_iterator sitr = scheduledVCards.find(jid);
if (sitr == scheduledVCards.end()) { if (sitr == scheduledVCards.end()) {
std::map<QString, Job::Id>::const_iterator ritr = requestedVCards.find(jid); std::map<QString, Job::Id>::const_iterator ritr = requestedVCards.find(jid);
if (ritr != requestedVCards.end()) if (ritr != requestedVCards.end()) {
job = runningJobs.at(ritr->second); std::map<Job::Id, Job*>::const_iterator itr = runningJobs.find(ritr->second);
if (itr == runningJobs.end())
throw JobNotFound(ritr->second, "getVCardJob:1");
job = itr->second;
}
} else { } else {
job = *(scheduledJobsById.find(sitr->second)); StorageById::const_iterator itr = scheduledJobsById.find(sitr->second);
if (itr == scheduledJobsById.end())
throw JobNotFound(sitr->second, "getVCardJob:2");
job = *itr;
} }
return job; return job;
@ -177,7 +191,7 @@ void Core::DelayManager::Manager::executeJob(Job* job) {
void Core::DelayManager::Manager::jobIsDone(Job::Id jobId) { void Core::DelayManager::Manager::jobIsDone(Job::Id jobId) {
std::map<Job::Id, Job*>::const_iterator itr = runningJobs.find(jobId); std::map<Job::Id, Job*>::const_iterator itr = runningJobs.find(jobId);
if (itr == runningJobs.end()) { if (itr == runningJobs.end()) {
throw 8573; //not supposed to happen, ever throw JobNotFound(jobId, "jobIsDone");
} }
Job* job = itr->second; Job* job = itr->second;
delete job; delete job;
@ -201,9 +215,8 @@ void Core::DelayManager::Manager::replaceJob(Job* job) {
if (sitr != scheduledJobsById.end()) { if (sitr != scheduledJobsById.end()) {
delete *(sitr); delete *(sitr);
scheduledJobsById.replace(sitr, job); scheduledJobsById.replace(sitr, job);
} else { } else
throw 8574; //not supposed to happen, ever throw JobNotFound(job->id, "replaceJob");
}
} }
} }
@ -278,7 +291,12 @@ void Core::DelayManager::Manager::receivedVCard(const QString& jid, const Shared
} }
Job::Id jobId = cardItr->second; Job::Id jobId = cardItr->second;
requestedVCards.erase(cardItr); requestedVCards.erase(cardItr);
Job* job = runningJobs.at(jobId); std::map<Job::Id, Job*>::const_iterator itr = runningJobs.find(jobId);
if (itr == runningJobs.end()) {
throw JobNotFound(jobId, "receivedVCard");
}
Job* job = itr->second;
switch (job->type) { switch (job->type) {
case Job::Type::cardInternal: case Job::Type::cardInternal:
jobIsDone(jobId); jobIsDone(jobId);
@ -300,14 +318,22 @@ void Core::DelayManager::Manager::receivedVCard(const QString& jid, const Shared
} }
break; break;
default: default:
throw 8576; throw UnexpectedJobType(job->type, "receivedVCard");
} }
} }
void Core::DelayManager::Manager::receivedOwnVCard(const Shared::VCard& card) { void Core::DelayManager::Manager::receivedOwnVCard(const Shared::VCard& card) {
if (ownVCardJobId == 0) {
qDebug() << "received own VCard for" << ownJid << "but it was never requested through manager, ignoring";
return;
}
Job::Id jobId = ownVCardJobId; Job::Id jobId = ownVCardJobId;
ownVCardJobId = 0; ownVCardJobId = 0;
Job* job = runningJobs.at(jobId); std::map<Job::Id, Job*>::const_iterator itr = runningJobs.find(jobId);
if (itr == runningJobs.end()) {
throw JobNotFound(jobId, "receivedOwnVCard");
}
Job* job = itr->second;
switch (job->type) { switch (job->type) {
case Job::Type::ownCardInternal: case Job::Type::ownCardInternal:
jobIsDone(jobId); jobIsDone(jobId);
@ -328,19 +354,24 @@ void Core::DelayManager::Manager::receivedOwnVCard(const Shared::VCard& card) {
} }
break; break;
default: default:
throw 8576; throw UnexpectedJobType(job->type, "receivedVCard");
} }
} }
void Core::DelayManager::Manager::receivedBundles(const QString& jid, const std::list<Shared::KeyInfo>& keys) { void Core::DelayManager::Manager::receivedBundles(const QString& jid, const std::list<Shared::KeyInfo>& keys) {
std::map<QString, Job::Id>::const_iterator itr = requestedBundles.find(jid); std::map<QString, Job::Id>::const_iterator itr = requestedBundles.find(jid);
if (itr == requestedBundles.end()) { if (itr == requestedBundles.end()) {
throw 8577; //never supposed to happen, the state is not correct; qDebug() << "received bundles for" << jid << "but they were never requested through manager, ignoring";
return;
} }
Job::Id jobId = itr->second; Job::Id jobId = itr->second;
requestedBundles.erase(itr); requestedBundles.erase(itr);
Job* jb = runningJobs.at(jobId); std::map<Job::Id, Job*>::const_iterator jitr = runningJobs.find(jobId);
if (jitr == runningJobs.end()) {
throw JobNotFound(jobId, "receivedBundles");
}
Job* jb = jitr->second;
InfoForUser* job = dynamic_cast<InfoForUser*>(jb); InfoForUser* job = dynamic_cast<InfoForUser*>(jb);
Shared::Info info(jid); Shared::Info info(jid);
@ -350,9 +381,17 @@ void Core::DelayManager::Manager::receivedBundles(const QString& jid, const std:
} }
void Core::DelayManager::Manager::receivedOwnBundles(const std::list<Shared::KeyInfo>& keys) { void Core::DelayManager::Manager::receivedOwnBundles(const std::list<Shared::KeyInfo>& keys) {
if (ownInfoJobId == 0) {
qDebug() << "received own bundles for" << ownJid << "but they were never requested through manager, ignoring";
return;
}
Job::Id jobId = ownInfoJobId; Job::Id jobId = ownInfoJobId;
ownInfoJobId = 0; ownInfoJobId = 0;
Job* jb = runningJobs.at(jobId); std::map<Job::Id, Job*>::const_iterator jitr = runningJobs.find(jobId);
if (jitr == runningJobs.end()) {
throw JobNotFound(jobId, "receivedOwnBundles");
}
Job* jb = jitr->second;
OwnInfoForUser* job = dynamic_cast<OwnInfoForUser*>(jb); OwnInfoForUser* job = dynamic_cast<OwnInfoForUser*>(jb);
Shared::Info info(ownJid); Shared::Info info(ownJid);
@ -364,3 +403,35 @@ void Core::DelayManager::Manager::receivedOwnBundles(const std::list<Shared::Key
void Core::DelayManager::Manager::setOwnJid(const QString& jid) { void Core::DelayManager::Manager::setOwnJid(const QString& jid) {
ownJid = jid; ownJid = jid;
} }
Core::DelayManager::Manager::UnexpectedJobType::UnexpectedJobType(Job::Type p_type, const std::string& p_method):
Exception(),
type(p_type),
method(p_method)
{}
std::string Core::DelayManager::Manager::UnexpectedJobType::getMessage() const{
std::string msg("Unexpected job type: ");
msg += Job::TypeString[static_cast<int>(type)];
if (method.size() > 0) {
msg += " in method " + method;
}
return msg;
}
Core::DelayManager::Manager::JobNotFound::JobNotFound(Job::Id p_id, const std::string& p_method) :
Exception(),
id(p_id),
method(p_method)
{}
std::string Core::DelayManager::Manager::JobNotFound::getMessage() const {
std::string msg("Job with id ");
msg += std::to_string(id);
msg += " was not found";
if (method.size() > 0) {
msg += " in method " + method;
}
return msg;
}

View File

@ -19,6 +19,7 @@
#include <list> #include <list>
#include <set> #include <set>
#include <string>
#include <boost/multi_index_container.hpp> #include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/ordered_index.hpp>
@ -30,6 +31,7 @@
#include <shared/vcard.h> #include <shared/vcard.h>
#include <shared/info.h> #include <shared/info.h>
#include <shared/exception.h>
#include "job.h" #include "job.h"
@ -121,6 +123,25 @@ private:
std::map<QString, Job::Id> requestedBundles; std::map<QString, Job::Id> requestedBundles;
#endif #endif
QString ownJid; QString ownJid;
public:
class UnexpectedJobType: public Utils::Exception {
public:
UnexpectedJobType(Job::Type p_type, const std::string& p_method = "");
std::string getMessage() const override;
private:
Job::Type type;
std::string method;
};
class JobNotFound: public Utils::Exception {
public:
JobNotFound(Job::Id p_id, const std::string& p_method = "");
std::string getMessage() const override;
private:
Job::Id id;
std::string method;
};
}; };
} }

View File

@ -93,7 +93,9 @@ QXmppTask<QXmpp::TrustLevel> Core::TrustHandler::trustLevel(
Shared::TrustLevel level = Shared::TrustLevel::undecided; Shared::TrustLevel level = Shared::TrustLevel::undecided;
try { try {
Keys map = cache->getRecord(keyOwnerJid); Keys map = cache->getRecord(keyOwnerJid);
level = map.at(keyId); Keys::const_iterator itr = map.find(keyId);
if (itr != map.end())
level = itr->second;
} catch (const DataBase::NotFound& e) {} } catch (const DataBase::NotFound& e) {}
return Core::makeReadyTask(std::move(convert(level))); return Core::makeReadyTask(std::move(convert(level)));
} }

2
external/qxmpp vendored

@ -1 +1 @@
Subproject commit 9d5762499fbddb3dd1ed8eeca16f9db70adc27d0 Subproject commit d679ad1c49eeb28be2ac3a75bd7fd1a9be24d483

2
external/storage vendored

@ -1 +1 @@
Subproject commit a79dae8fd07b36446041f6f85e2ad42cf5ae5264 Subproject commit 6a8f67ac34de286588cd89e3218f55b54da47f42

View File

@ -17,22 +17,11 @@
*/ */
#include "root.h" #include "root.h"
#include "shared/global.h"
#include "shared/messageinfo.h" #include "shared/messageinfo.h"
#include "shared/pathcheck.h"
#include "shared/identity.h" #include "shared/identity.h"
#include "shared/info.h" #include "shared/info.h"
#include "main/application.h"
#include "core/signalcatcher.h"
#include "core/squawk.h"
#include <QLibraryInfo> #include <QObject>
#include <QSettings>
#include <QStandardPaths>
#include <QTranslator>
#include <QtCore/QObject>
#include <QtCore/QThread>
#include <QDir>
#ifdef WITH_OMEMO #ifdef WITH_OMEMO
#include <QXmppOmemoStorage.h> #include <QXmppOmemoStorage.h>
@ -60,97 +49,10 @@ int main(int argc, char *argv[])
#endif #endif
Root app(argc, argv); Root app(argc, argv);
SignalCatcher sc(&app); if (!app.initializeSettings())
Root::setApplicationName("squawk");
Root::setOrganizationName("macaw.me");
Root::setApplicationDisplayName("Squawk");
Root::setApplicationVersion("0.2.3");
app.setDesktopFileName("squawk");
QTranslator qtTranslator;
qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
app.installTranslator(&qtTranslator);
QTranslator myappTranslator;
QStringList shares = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
bool found = false;
for (QString share : shares) {
found = myappTranslator.load(QLocale(), QLatin1String("squawk"), ".", share + "/l10n");
if (found) {
break;
}
}
if (!found) {
myappTranslator.load(QLocale(), QLatin1String("squawk"), ".", QCoreApplication::applicationDirPath());
}
app.installTranslator(&myappTranslator);
QIcon icon;
icon.addFile(":images/logo.svg", QSize(16, 16));
icon.addFile(":images/logo.svg", QSize(24, 24));
icon.addFile(":images/logo.svg", QSize(32, 32));
icon.addFile(":images/logo.svg", QSize(48, 48));
icon.addFile(":images/logo.svg", QSize(64, 64));
icon.addFile(":images/logo.svg", QSize(96, 96));
icon.addFile(":images/logo.svg", QSize(128, 128));
icon.addFile(":images/logo.svg", QSize(256, 256));
icon.addFile(":images/logo.svg", QSize(512, 512));
Root::setWindowIcon(icon);
new Shared::Global(); //translates enums
QSettings settings;
QVariant vs = settings.value("style");
if (vs.isValid()) {
QString style = vs.toString().toLower();
if (style != "system") {
Shared::Global::setStyle(style);
}
}
if (Shared::Global::supported("colorSchemeTools")) {
QVariant vt = settings.value("theme");
if (vt.isValid()) {
QString theme = vt.toString();
if (theme.toLower() != "system") {
Shared::Global::setTheme(theme);
}
}
}
QString path = Shared::downloadsPathCheck();
if (path.size() > 0) {
settings.setValue("downloadsPath", path);
} else {
qDebug() << "couldn't initialize directory for downloads, quitting";
return -1; return -1;
}
Core::Squawk* squawk = new Core::Squawk(); return app.run();
QThread* coreThread = new QThread();
squawk->moveToThread(coreThread);
Application application(squawk);
QObject::connect(&sc, &SignalCatcher::interrupt, &application, &Application::quit);
QObject::connect(coreThread, &QThread::started, squawk, &Core::Squawk::start);
QObject::connect(&application, &Application::quitting, squawk, &Core::Squawk::stop);
//QObject::connect(&app, &QApplication::aboutToQuit, &w, &QMainWindow::close);
QObject::connect(squawk, &Core::Squawk::quit, squawk, &Core::Squawk::deleteLater);
QObject::connect(squawk, &Core::Squawk::destroyed, coreThread, &QThread::quit, Qt::QueuedConnection);
QObject::connect(coreThread, &QThread::finished, &app, &Root::quit, Qt::QueuedConnection);
coreThread->start();
int result = app.exec();
if (coreThread->isRunning()) {
//coreThread->wait();
//todo if I uncomment that, the app will not quit if it has reconnected at least once
//it feels like a symptom of something badly desinged in the core thread
//need to investigate;
}
return result;
} }

View File

@ -17,27 +17,174 @@
#include "root.h" #include "root.h"
#include <QDebug> #include <QDebug>
#include <QThread> #include <QThread>
#include <QLibraryInfo>
#include <QStandardPaths>
#include <string>
#include <shared/pathcheck.h>
const std::vector<unsigned int> Root::appIconSizes({
16, 24, 32, 48, 64, 96, 128, 256, 512
});
Root::Root(int& argc, char *argv[]) : Root::Root(int& argc, char *argv[]) :
QApplication(argc, argv) QApplication(argc, argv),
{} signalCatcher(this),
defaultTranslator(),
currentTranslator(),
appIcon(),
settings(),
componentsInitialized(false),
global(nullptr),
coreThread(nullptr),
core(nullptr),
gui(nullptr)
{
setApplicationName("squawk");
setOrganizationName("macaw.me");
setApplicationDisplayName("Squawk");
setApplicationVersion("0.2.3");
setDesktopFileName("squawk");
initializeTranslation();
initializeAppIcon();
global = new Shared::Global(); //important to instantiate after initialization of translations;
}
Root::~Root() {
if (componentsInitialized) {
delete gui;
if (core != nullptr)
delete core;
delete coreThread;
}
delete global;
}
void Root::initializeTranslation() {
defaultTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
installTranslator(&defaultTranslator);
QStringList shares = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
bool found = false;
for (QString share : shares) {
found = currentTranslator.load(QLocale(), QLatin1String("squawk"), ".", share + "/l10n");
if (found) {
break;
}
}
if (!found) {
currentTranslator.load(QLocale(), QLatin1String("squawk"), ".", QCoreApplication::applicationDirPath());
}
installTranslator(&currentTranslator);
}
void Root::initializeAppIcon() {
for (std::vector<unsigned int>::size_type i = 0; i < appIconSizes.size(); ++i)
appIcon.addFile(":images/logo.svg", QSize(appIconSizes[i], appIconSizes[i]));
Root::setWindowIcon(appIcon);
}
bool Root::initializeSettings() {
QVariant vs = settings.value("style");
if (vs.isValid()) {
QString style = vs.toString().toLower();
if (style != "system") {
Shared::Global::setStyle(style);
}
}
if (Shared::Global::supported("colorSchemeTools")) {
QVariant vt = settings.value("theme");
if (vt.isValid()) {
QString theme = vt.toString();
if (theme.toLower() != "system") {
Shared::Global::setTheme(theme);
}
}
}
QString path = Shared::downloadsPathCheck();
if (path.size() > 0) {
settings.setValue("downloadsPath", path);
} else {
qDebug() << "couldn't initialize directory for downloads, quitting";
return false;
}
return true;
}
int Root::run() {
if (!componentsInitialized)
initializeComponents();
coreThread->start();
int result = exec();
qDebug("Event loop stopped");
if (result == 0) {
processEvents(); //I dont like all of this mess
if (coreThread->isRunning()) { //but it's the best solution for now
if (core != nullptr) { //Ideally, following line should never appear in the log
qDebug() << "Core is still seems to be running, killing manually";
core->deleteLater();
coreThread->quit();
processEvents();
core = nullptr;
}
coreThread->wait();
}
}
return result;
}
void Root::initializeComponents() {
core = new Core::Squawk();
coreThread = new QThread();
core->moveToThread(coreThread);
gui = new Application(core);
QObject::connect(&signalCatcher, &SignalCatcher::interrupt, gui, &Application::quit);
QObject::connect(coreThread, &QThread::started, core, &Core::Squawk::start);
QObject::connect(gui, &Application::quitting, core, &Core::Squawk::stop);
QObject::connect(core, &Core::Squawk::quit, core, &Core::Squawk::deleteLater);
QObject::connect(core, &Core::Squawk::destroyed, this, &Root::onCoreDestroyed);
QObject::connect(core, &Core::Squawk::destroyed, coreThread, &QThread::quit, Qt::QueuedConnection);
QObject::connect(coreThread, &QThread::finished, this, &Root::quit, Qt::QueuedConnection);
componentsInitialized = true;
}
bool Root::notify(QObject* receiver, QEvent* e) { bool Root::notify(QObject* receiver, QEvent* e) {
try { try {
return QApplication::notify(receiver, e); return QApplication::notify(receiver, e);
} catch(const std::runtime_error& e) { } catch(const std::runtime_error& e) {
qDebug() << "std::runtime_error in thread:" << QThread::currentThreadId(); qDebug() << "std::runtime_error in thread:" << QThread::currentThreadId();
qDebug() << e.what(); qDebug() << "error message:" << e.what();
} catch(const std::exception& e) { } catch(const std::exception& e) {
qDebug() << "std::exception in thread:" << QThread::currentThreadId(); qDebug() << "std::exception in thread:" << QThread::currentThreadId();
qDebug() << e.what(); qDebug() << "error message:" << e.what();
} catch(const int& e) { } catch(const int& e) {
qDebug() << "int exception in thread : " << QThread::currentThreadId(); qDebug() << "integer exception in thread:" << QThread::currentThreadId();
qDebug() << e; qDebug() << "thrown integer:" << std::to_string(e).c_str();
} catch(...) { } catch(...) {
qDebug() << "exception thread : " << QThread::currentThreadId(); qDebug() << "unhandled exception thread:" << QThread::currentThreadId();
} }
qDebug() << "catch in notify "; qDebug() << "Squawk is crashing...";
exit(1);
return false; return false;
} }
void Root::onCoreDestroyed() {
core = nullptr;
}

View File

@ -18,11 +18,53 @@
#define ROOT_H #define ROOT_H
#include <QApplication> #include <QApplication>
#include <QTranslator>
#include <QIcon>
#include <QSettings>
#include <QThread>
#include <vector>
#include <core/squawk.h>
#include <core/signalcatcher.h>
#include <shared/global.h>
#include "application.h"
class Root : public QApplication { class Root : public QApplication {
Q_OBJECT
public: public:
Root(int& argc, char* argv[]); Root(int& argc, char* argv[]);
~Root();
bool notify(QObject* receiver, QEvent* e) override; bool notify(QObject* receiver, QEvent* e) override;
int run();
bool initializeSettings();
private slots:
void onCoreDestroyed();
private:
void initializeTranslation();
void initializeAppIcon();
void initializeComponents();
private:
static const std::vector<unsigned int> appIconSizes;
SignalCatcher signalCatcher;
QTranslator defaultTranslator;
QTranslator currentTranslator;
QIcon appIcon;
QSettings settings;
bool componentsInitialized;
Shared::Global* global;
QThread* coreThread;
Core::Squawk* core;
Application* gui;
}; };
#endif // ROOT_H #endif // ROOT_H