diff --git a/oscar/logger.cpp b/oscar/logger.cpp index 1ded710a..39955e37 100644 --- a/oscar/logger.cpp +++ b/oscar/logger.cpp @@ -12,8 +12,6 @@ #include "version.h" #include -#define ASSERTS_SUCK - QThreadPool * otherThreadPool = NULL; void MyOutputHandler(QtMsgType type, const QMessageLogContext &context, const QString &msgtxt) @@ -51,11 +49,7 @@ void MyOutputHandler(QtMsgType type, const QMessageLogContext &context, const QS if (logger && logger->isRunning()) { logger->append(msg); } -#ifdef ASSERTS_SUCK -// else { -// fprintf(stderr, "%s\n", msg.toLocal8Bit().data()); -// } -#endif + fprintf(stderr, "%s\n", msg.toLocal8Bit().constData()); if (type == QtFatalMsg) { abort(); @@ -91,6 +85,25 @@ void LogThread::connectionReady() qDebug() << "Logging UI initialized"; } +void LogThread::logToFile() +{ + QString debugLog = GetLogDir() + "/debug.txt"; + rotateLogs(debugLog); // keep a limited set of previous logs + + strlock.lock(); + m_logFile = new QFile(debugLog); + Q_ASSERT(m_logFile); + if (m_logFile->open(QFile::ReadWrite | QFile::Text)) { + m_logStream = new QTextStream(m_logFile); + } + strlock.unlock(); + if (m_logStream) { + qDebug().noquote() << "Logging to" << debugLog; + } else { + qWarning().noquote() << "Unable to open" << debugLog; + } +} + void shutdownLogger() { if (logger) { @@ -126,7 +139,16 @@ void LogThread::quit() { strlock.lock(); while (!buffer.isEmpty()) { QString msg = buffer.takeFirst(); - fprintf(stderr, "%s\n", msg.toLocal8Bit().constData()); + if (m_logStream) { + *m_logStream << msg << endl; + } + } + if (m_logStream) { + delete m_logStream; + m_logStream = nullptr; + Q_ASSERT(m_logFile); + delete m_logFile; + m_logFile = nullptr; } strlock.unlock(); } @@ -139,10 +161,13 @@ void LogThread::run() do { strlock.lock(); //int r = receivers(SIGNAL(outputLog(QString()))); - while (connected && !buffer.isEmpty()) { + // Wait to flush the buffer until the UI is connected and the log file has been opened. + while (connected && m_logFile && !buffer.isEmpty()) { QString msg = buffer.takeFirst(); - fprintf(stderr, "%s\n", msg.toLocal8Bit().data()); - emit outputLog(msg); + if (m_logStream) { + *m_logStream << msg << endl; + } + emit outputLog(msg); } strlock.unlock(); QThread::msleep(1000); @@ -154,6 +179,7 @@ QString GetLogDir() { static const QString LOG_DIR_NAME = "logs"; + Q_ASSERT(!GetAppData().isEmpty()); // If GetLogDir gets called before GetAppData() is valid, this would point at root. QDir oscarData(GetAppData()); Q_ASSERT(oscarData.exists()); if (!oscarData.exists(LOG_DIR_NAME)) { diff --git a/oscar/logger.h b/oscar/logger.h index 65ddf948..df1d0045 100644 --- a/oscar/logger.h +++ b/oscar/logger.h @@ -20,7 +20,7 @@ class LogThread:public QObject, public QRunnable { Q_OBJECT public: - explicit LogThread() : QRunnable() { running = false; logtime.start(); connected = false; } + explicit LogThread() : QRunnable() { running = false; logtime.start(); connected = false; m_logFile = nullptr; m_logStream = nullptr; } virtual ~LogThread() {} void run(); @@ -28,6 +28,7 @@ public: void appendClean(QString msg); bool isRunning() { return running; } void connectionReady(); + void logToFile(); void quit(); @@ -40,6 +41,8 @@ protected: volatile bool running; QTime logtime; bool connected; + class QFile* m_logFile; + class QTextStream* m_logStream; }; extern LogThread * logger; diff --git a/oscar/main.cpp b/oscar/main.cpp index dcccb77a..cc19464d 100644 --- a/oscar/main.cpp +++ b/oscar/main.cpp @@ -545,6 +545,16 @@ int main(int argc, char *argv[]) { } } + // Make sure the data directory exists. + if (!newDir.mkpath(".")) { + QMessageBox::warning(nullptr, QObject::tr("Exiting"), + QObject::tr("Unable to create the OSCAR data folder at")+"\n"+ + GetAppData()); + return 0; + } + + // Begin logging to file now that there's a data folder. + logger->logToFile(); /////////////////////////////////////////////////////////////////////////////////////////// // Initialize preferences system (Don't use p_pref before this point!) diff --git a/oscar/oscar.pro b/oscar/oscar.pro index 37aa096f..5becfa8d 100644 --- a/oscar/oscar.pro +++ b/oscar/oscar.pro @@ -500,6 +500,7 @@ lessThan(QT_MAJOR_VERSION,5)|lessThan(QT_MINOR_VERSION,9) { # Create a debug GUI build by adding "CONFIG+=memdebug" to your qmake command memdebug { + CONFIG += debug !win32 { # add memory checking on Linux and macOS debug builds QMAKE_CFLAGS += -g -Werror -fsanitize=address -fno-omit-frame-pointer -fno-common -fsanitize-address-use-after-scope lessThan(QT_MAJOR_VERSION,5)|lessThan(QT_MINOR_VERSION,9) {