X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Fquassel.cpp;h=84301f96d85d5a416d195e6830d625d6a033c9f5;hp=1ecc896976e2984933cedb8d0341ce0400a33c17;hb=9e531f113fbca51739ac6e2cf4eed7005b005c8f;hpb=de5e60aac1e7e993d2c82b2e22e3a47ff429f268 diff --git a/src/common/quassel.cpp b/src/common/quassel.cpp index 1ecc8969..84301f96 100644 --- a/src/common/quassel.cpp +++ b/src/common/quassel.cpp @@ -34,29 +34,29 @@ #include "types.h" #include "syncableobject.h" -#if defined(HAVE_EXECINFO) and not defined(Q_OS_MAC) -# define BUILD_CRASHHANDLER -# include -# include -# include -#endif - Quassel::BuildInfo Quassel::_buildInfo; CliParser *Quassel::_cliParser = 0; Quassel::RunMode Quassel::_runMode; bool Quassel::_initialized = false; bool Quassel::DEBUG = false; +QString Quassel::_coreDumpFileName; Quassel::Quassel() { + Q_INIT_RESOURCE(i18n); + // We catch SIGTERM and SIGINT (caused by Ctrl+C) to graceful shutdown Quassel. signal(SIGTERM, handleSignal); signal(SIGINT, handleSignal); -#ifdef BUILD_CRASHHANDLER + // we have crashhandler for win32 and unix (based on execinfo). + // on mac os we use it's integrated backtrace generator +#if defined(Q_OS_WIN32) || (defined(HAVE_EXECINFO) && !defined(Q_OS_MAC)) signal(SIGABRT, handleSignal); - signal(SIGBUS, handleSignal); signal(SIGSEGV, handleSignal); -#endif // #if defined(HAVE_EXECINFO) and not defined(Q_OS_MAC) +# ifndef Q_OS_WIN32 + signal(SIGBUS, handleSignal); +# endif +#endif _cliParser = new CliParser(); @@ -70,14 +70,13 @@ Quassel::~Quassel() { } bool Quassel::init() { - if(_initialized) return true; // allow multiple invocations because of MonolithicApplication + if(_initialized) + return true; // allow multiple invocations because of MonolithicApplication + _initialized = true; qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); registerMetaTypes(); - setupBuildInfo(); - Global::setupVersion(); - setupTranslations(); QCoreApplication::setApplicationName(buildInfo().applicationName); QCoreApplication::setOrganizationName(buildInfo().organizationName); @@ -105,6 +104,7 @@ void Quassel::registerMetaTypes() { qRegisterMetaType("Message"); qRegisterMetaType("BufferInfo"); qRegisterMetaType("NetworkInfo"); + qRegisterMetaType("Network::Server"); qRegisterMetaType("Identity"); qRegisterMetaType("Network::ConnectionState"); @@ -112,6 +112,7 @@ void Quassel::registerMetaTypes() { qRegisterMetaTypeStreamOperators("Message"); qRegisterMetaTypeStreamOperators("BufferInfo"); qRegisterMetaTypeStreamOperators("NetworkInfo"); + qRegisterMetaTypeStreamOperators("Network::Server"); qRegisterMetaTypeStreamOperators("Identity"); qRegisterMetaTypeStreamOperators("Network::ConnectionState"); @@ -130,161 +131,107 @@ void Quassel::registerMetaTypes() { qRegisterMetaTypeStreamOperators("MsgId"); } -void Quassel::setupTranslations() { - // Set up i18n support - QLocale locale = QLocale::system(); - - QTranslator *qtTranslator = new QTranslator(qApp); - qtTranslator->setObjectName("QtTr"); - qtTranslator->load(QString(":i18n/qt_%1").arg(locale.name())); - qApp->installTranslator(qtTranslator); - - QTranslator *quasselTranslator = new QTranslator(qApp); - quasselTranslator->setObjectName("QuasselTr"); - quasselTranslator->load(QString(":i18n/quassel_%1").arg(locale.name())); - qApp->installTranslator(quasselTranslator); -} - -void Quassel::setupBuildInfo() { +void Quassel::setupBuildInfo(const QString &generated) { _buildInfo.applicationName = "Quassel IRC"; _buildInfo.coreApplicationName = "Quassel Core"; _buildInfo.clientApplicationName = "Quassel Client"; _buildInfo.organizationName = "Quassel Project"; _buildInfo.organizationDomain = "quassel-irc.org"; -/* -# include "version.inc" -# include "version.gen" - if(quasselGeneratedVersion.isEmpty()) { - if(quasselCommit.isEmpty()) - quasselVersion = QString("v%1 (unknown rev)").arg(quasselBaseVersion); - else - quasselVersion = QString("v%1 (dist-%2, %3)").arg(quasselBaseVersion).arg(quasselCommit.left(7)) - .arg(QDateTime::fromTime_t(quasselArchiveDate).toLocalTime().toString("yyyy-MM-dd")); + QStringList gen = generated.split(','); + Q_ASSERT(gen.count() == 10); + _buildInfo.baseVersion = gen[0]; + _buildInfo.generatedVersion = gen[1]; + _buildInfo.isSourceDirty = !gen[2].isEmpty(); + _buildInfo.commitHash = gen[3]; + _buildInfo.commitDate = gen[4].toUInt(); + _buildInfo.protocolVersion = gen[5].toUInt(); + _buildInfo.clientNeedsProtocol = gen[6].toUInt(); + _buildInfo.coreNeedsProtocol = gen[7].toUInt(); + _buildInfo.buildDate = QString("%1 %2").arg(gen[8], gen[9]); + // create a nice version string + if(_buildInfo.generatedVersion.isEmpty()) { + if(!_buildInfo.commitHash.isEmpty()) { + // dist version + _buildInfo.plainVersionString = QString("v%1 (dist-%2)") + .arg(_buildInfo.baseVersion) + .arg(_buildInfo.commitHash.left(7)); + _buildInfo.fancyVersionString + = QString("v%1 (dist-%2)") + .arg(_buildInfo.baseVersion) + .arg(_buildInfo.commitHash.left(7)) + .arg(_buildInfo.commitHash); + } else { + // we only have a base version :( + _buildInfo.plainVersionString = QString("v%1 (unknown rev)").arg(_buildInfo.baseVersion); + } } else { - QStringList parts = quasselGeneratedVersion.split(':'); - quasselVersion = QString("v%1").arg(parts[0]); - if(parts.count() >= 2) quasselVersion.append(QString(" (%1)").arg(parts[1])); + // analyze what we got from git-describe + QRegExp rx("(.*)-(\\d+)-g([0-9a-f]+)$"); + if(rx.exactMatch(_buildInfo.generatedVersion)) { + QString distance = rx.cap(2) == "0" ? QString() : QString(" [+%1]").arg(rx.cap(2)); + _buildInfo.plainVersionString = QString("v%1%2 (git-%3%4)") + .arg(rx.cap(1), distance, rx.cap(3)) + .arg(_buildInfo.isSourceDirty ? "*" : ""); + if(!_buildInfo.commitHash.isEmpty()) { + _buildInfo.fancyVersionString = QString("v%1%2 (git-%3%4)") + .arg(rx.cap(1), distance, rx.cap(3)) + .arg(_buildInfo.isSourceDirty ? "*" : "") + .arg(_buildInfo.commitHash); + } + } else { + _buildInfo.plainVersionString = QString("v%1 (invalid rev)").arg(_buildInfo.baseVersion); + } } - quasselBuildDate = __DATE__; - quasselBuildTime = __TIME__; - */ + if(_buildInfo.fancyVersionString.isEmpty()) + _buildInfo.fancyVersionString = _buildInfo.plainVersionString; } //! Signal handler for graceful shutdown. void Quassel::handleSignal(int sig) { switch(sig) { - case SIGTERM: - case SIGINT: - qWarning("%s", qPrintable(QString("Caught signal %1 - exiting.").arg(sig))); - QCoreApplication::quit(); - break; - -#ifdef BUILD_CRASHHANDLER - case SIGABRT: - case SIGBUS: - case SIGSEGV: - handleCrash(); + case SIGTERM: + case SIGINT: + qWarning("%s", qPrintable(QString("Caught signal %1 - exiting.").arg(sig))); + QCoreApplication::quit(); + break; + case SIGABRT: + case SIGSEGV: +#ifndef Q_OS_WIN32 + case SIGBUS: #endif - break; - default: - break; + logBacktrace(coreDumpFileName()); + exit(EXIT_FAILURE); + break; + default: + break; } } -void Quassel::handleCrash() { -#ifdef BUILD_CRASHHANDLER - void* callstack[128]; - int i, frames = backtrace(callstack, 128); - - QFile dumpFile(QString("Quassel-Crash-%1").arg(QDateTime::currentDateTime().toString("yyyyMMdd-hhmm.log"))); - dumpFile.open(QIODevice::WriteOnly); +void Quassel::logFatalMessage(const char *msg) { +#ifdef Q_OS_MAC + Q_UNUSED(msg) +#else + QFile dumpFile(coreDumpFileName()); + dumpFile.open(QIODevice::Append); QTextStream dumpStream(&dumpFile); - for (i = 0; i < frames; ++i) { - Dl_info info; - dladdr (callstack[i], &info); - // as a reference: - // typedef struct - // { - // __const char *dli_fname; /* File name of defining object. */ - // void *dli_fbase; /* Load address of that object. */ - // __const char *dli_sname; /* Name of nearest symbol. */ - // void *dli_saddr; /* Exact value of nearest symbol. */ - // } Dl_info; - - #if __LP64__ - int addrSize = 16; - #else - int addrSize = 8; - #endif - - QString funcName; - if(info.dli_sname) { - char *func = abi::__cxa_demangle(info.dli_sname, 0, 0, 0); - if(func) { - funcName = QString(func); - free(func); - } else { - funcName = QString(info.dli_sname); - } - } else { - funcName = QString("0x%1").arg((long)info.dli_saddr, addrSize, QLatin1Char('0')); - } - - // prettificating the filename - QString fileName("???"); - if(info.dli_fname) { - fileName = QString(info.dli_fname); - int slashPos = fileName.lastIndexOf('/'); - if(slashPos != -1) - fileName = fileName.mid(slashPos + 1); - if(fileName.count() < 20) - fileName += QString(20 - fileName.count(), ' '); - } - - QString debugLine = QString("#%1 %2 0x%3 %4").arg(i, 3, 10) - .arg(fileName) - .arg((long)(callstack[i]), addrSize, 16, QLatin1Char('0')) - .arg(funcName); - - dumpStream << debugLine << "\n"; - qDebug() << qPrintable(debugLine); - } + dumpStream << "Fatal: " << msg << '\n'; + dumpStream.flush(); dumpFile.close(); - exit(27); -#endif /* BUILD_CRASHHANDLER */ +#endif } -// FIXME temporary - -void Global::setupVersion() { - - # include "version.inc" - # include "version.gen" - - if(quasselGeneratedVersion.isEmpty()) { - if(quasselCommit.isEmpty()) - quasselVersion = QString("v%1 (unknown rev)").arg(quasselBaseVersion); - else - quasselVersion = QString("v%1 (dist-%2, %3)").arg(quasselBaseVersion).arg(quasselCommit.left(7)) - .arg(QDateTime::fromTime_t(quasselArchiveDate).toLocalTime().toString("yyyy-MM-dd")); - } else { - QStringList parts = quasselGeneratedVersion.split(':'); - quasselVersion = QString("v%1").arg(parts[0]); - if(parts.count() >= 2) quasselVersion.append(QString(" (%1)").arg(parts[1])); +const QString &Quassel::coreDumpFileName() { + if(_coreDumpFileName.isEmpty()) { + _coreDumpFileName = QString("Quassel-Crash-%1.log").arg(QDateTime::currentDateTime().toString("yyyyMMdd-hhmm")); + QFile dumpFile(_coreDumpFileName); + dumpFile.open(QIODevice::Append); + QTextStream dumpStream(&dumpFile); + dumpStream << "Quassel IRC: " << _buildInfo.baseVersion << ' ' << _buildInfo.commitHash << '\n'; + qDebug() << "Quassel IRC: " << _buildInfo.baseVersion << ' ' << _buildInfo.commitHash; + dumpStream.flush(); + dumpFile.close(); } - quasselBuildDate = __DATE__; - quasselBuildTime = __TIME__; + return _coreDumpFileName; } - -QString Global::quasselVersion; -QString Global::quasselBaseVersion; -QString Global::quasselGeneratedVersion; -QString Global::quasselBuildDate; -QString Global::quasselBuildTime; -QString Global::quasselCommit; -uint Global::quasselArchiveDate; -uint Global::protocolVersion; -uint Global::clientNeedsProtocol; -uint Global::coreNeedsProtocol;