每当有消息发送到我的自定义消息处理程序时,它会通过分段错误错误使标记行处的应用程序崩溃。
// main.cpp
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QStringList data;
data.append(context.category);
data.append(context.file);
data.append(context.function);
data.append(QString(context.line));
data.append(QString(context.version));
Logger::get_obj()->myMessageOutput(type, data, msg);
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setApplicationName("MyApp");
a.setWindowIcon(QIcon(":/Icons/MyApp.png"));
Logger log;
qInstallMessageHandler(myMessageOutput);
log.turnOnDebug();
MySplashScreen splash;
splash.show();
a.processEvents();
...
splash.close();
MainWindow *w = new MainWindow();
int errorCode = a.exec();
delete w;
session.destruct();
qDebug() << "\n*** Application exited with error code " << errorCode << " ***";
return errorCode;
}
// logger.h
#ifndef LOGGER_H
#define LOGGER_H
#include <QObject>
#include <QFile>
#include <QTextStream>
#include <QMutex>
class Logger : public QObject
{
Q_OBJECT
public:
void myMessageOutput(QtMsgType type, QStringList context, const QString msg);
explicit Logger(QObject *parent = 0);
~Logger();
static Logger *get_obj() {return ptr;}
static void turnOnDebug() {get_obj()->debugMode = true;}
static void turnOffDebug() {get_obj()->debugMode = false;}
static void moveLogToSession(QString sessionName);
private:
QFile *logFile;
QTextStream *stream;
QMutex *mutex;
bool debugMode;
bool errorMsg;
static Logger *ptr;
void write(QString str);
signals:
void SaveSession();
void FatalSaveSession();
public slots:
};
#endif // LOGGER_H
// logger.cpp
#include <QDir>
#include <QFile>
#include <QMessageBox>
#include <QApplication>
#include "logger.h"
#include "systemvariables.h"
Logger *Logger::ptr = NULL;
Logger::Logger(QObject *parent) : QObject(parent)
{
logFile = NULL;
stream = NULL;
mutex = NULL;
debugMode = false;
errorMsg = false;
ptr = this;
QString path = SystemVariables::getAppData();
QDir dir = QDir(path);
if(dir.exists())
{
path.append("/MyApp/Logs");
dir = QDir(path);
if(!dir.exists())
dir.mkpath(path);
logFile = new QFile(path + "/Session.log");
if(logFile->exists())
logFile->remove();
if(!logFile->open(QFile::WriteOnly | QFile::Text))
{
qFatal("Could not create log file.");
}
stream = new QTextStream(logFile);
stream->setRealNumberNotation(QTextStream::SmartNotation);
stream->setRealNumberPrecision(15);
*stream << "*** MyApp Session Begins ***\n";
}
else
qFatal("Could not create log file.");
mutex = new QMutex();
}
void Logger::myMessageOutput(QtMsgType type, QStringList context, const QString msg)
{
mutex->lock();
QString str = "";
switch (type)
{
case QtDebugMsg:
if(!debugMode)
{
mutex->unlock();
return;
}
write(msg);
break;
case QtInfoMsg:
str.append("\n*** Information ***\n");
str.append(msg + "\n");
str.append("Category: " + context.at(0) + "\n");
str.append("File: " + context.at(1) + "\n");
str.append("Function: " + context.at(2) + "\n");
str.append("Line: " + context.at(3) + "\n");
str.append("Version: " + context.at(4));
str.append("\n*** Information Complete ***\n");
write(str);
break;
case QtWarningMsg:
if(!(context.at(2).contains("setGeometry")))
{
str.append("\n*** Warning ***\n");
...
str.append("\n*** Warning Complete ***\n");
write(str);
errorMsg = true;
emit Logger::ptr->SaveSession();
}
break;
case QtCriticalMsg:
str.append("\n*** Critical ***\n");
...
str.append("\n*** Critical Complete ***\n");
write(str);
errorMsg = true;
emit Logger::ptr->SaveSession();
break;
case QtFatalMsg:
str.append("\n*** Fatal ***\n");
...
str.append("\n*** Fatal Complete ***\n");
write(str);
errorMsg = false;
emit Logger::ptr->FatalSaveSession();
QApplication::exit(-2);
}
Logger::mutex->unlock();
}
void Logger::write(QString str)
{
if(!stream)
return;
if(str.isEmpty())
return;
(*stream) << str; //!!!!!!!!!!!!CRASHES HERE***********
stream->flush();
}
void Logger::moveLogToSession(QString sessionName)
{
QMutex *myMutex = get_obj()->mutex;
myMutex->lock();
QTextStream *myStream = get_obj()->stream;
myStream->flush();
QFile *myLogFile = get_obj()->logFile;
myLogFile->flush();
myLogFile->close();
delete myStream;
QString path = SystemVariables::getAppData() + "/Smovault/Logs";
if(!myLogFile->open(QFile::ReadOnly | QFile::Text))
{
QString errtitle = "FATAL ERROR!";
QString errtxt = myLogFile->errorString() + "\nCould not open the log file: ";
errtxt.append(path + "/Session.log");
errtxt.append(".\nApplication Abort!");
QMessageBox *mb = new QMessageBox(QMessageBox::Critical, errtitle, errtxt);
mb->exec();
delete mb;
QApplication::exit(-1);
}
QTextStream in(myLogFile);
QString data = in.readAll();
myLogFile->close();
myLogFile->remove();
delete myLogFile;
path = SystemVariables::getAppData() + "/Smovault/Sessions/" + sessionName;
myLogFile = new QFile(path + "/Session.log");
if(!myLogFile->open(QFile::WriteOnly | QFile::Text))
{
QString errtitle = "FATAL ERROR!";
QString errtxt = myLogFile->errorString() + "\nCould not write to the log file: ";
errtxt.append(path + "/Session.log");
errtxt.append(".\nApplication Abort!");
QMessageBox *mb = new QMessageBox(QMessageBox::Critical, errtitle, errtxt);
mb->exec();
delete mb;
QApplication::exit(-1);
}
QTextStream out(myLogFile);
out << data;
out.flush();
myLogFile->flush();
myStream = new QTextStream(myLogFile);
myStream->setRealNumberNotation(QTextStream::SmartNotation);
myStream->setRealNumberPrecision(15);
myMutex->unlock();
}
如果有人可以通过指出我的错误来帮助我,我真的很感激。
答案 0 :(得分:2)
如果在调用moveLogToSession后发生崩溃,我想这是因为你破坏了流
QTextStream *myStream = get_obj()->stream;
myStream->flush();
...
delete myStream; // here
永远不会设置新流
myStream = new QTextStream(myLogFile);
get_obj()->stream = myStream; // you need THIS