Mercurial > hg > svcore
comparison base/Debug.cpp @ 1061:c1e43c8d2527 tonioni
Thread-local debug was causing crash on exit with Qt 5.4.x. But we introduced that because QDebug itself was crashing when used from multiple threads. Replace with simpler fstream version
author | Chris Cannam |
---|---|
date | Tue, 31 Mar 2015 10:36:52 +0100 |
parents | c49d52386cde |
children | 8f076d02569a |
comparison
equal
deleted
inserted
replaced
1058:c49d52386cde | 1061:c1e43c8d2527 |
---|---|
14 */ | 14 */ |
15 | 15 |
16 #include "Debug.h" | 16 #include "Debug.h" |
17 #include "ResourceFinder.h" | 17 #include "ResourceFinder.h" |
18 | 18 |
19 #include <QString> | 19 #include <QMutex> |
20 #include <QDir> | |
20 #include <QUrl> | 21 #include <QUrl> |
21 #include <QMutex> | |
22 #include <QMutexLocker> | |
23 #include <QFile> | |
24 #include <QDir> | |
25 #include <QCoreApplication> | 22 #include <QCoreApplication> |
26 #include <QDateTime> | |
27 #include <QThreadStorage> | |
28 | 23 |
29 #include <cstdio> | 24 #ifndef NDEBUG |
30 | 25 |
31 static QThreadStorage<QDebug *> debugs; | 26 static SVDebug *debug = 0; |
32 static QMutex mutex; | 27 static QMutex mutex; |
33 static char *prefix = 0; | |
34 | 28 |
35 QDebug & | 29 SVDebug &getSVDebug() { |
36 getSVDebug() | 30 mutex.lock(); |
31 if (!debug) { | |
32 debug = new SVDebug(); | |
33 } | |
34 mutex.unlock(); | |
35 return *debug; | |
36 } | |
37 | |
38 SVDebug::SVDebug() : | |
39 m_prefix(0), | |
40 m_ok(false), | |
41 m_eol(false) | |
37 { | 42 { |
38 mutex.lock(); | |
39 | |
40 QDebug *debug = 0; | |
41 | |
42 QString pfx = ResourceFinder().getUserResourcePrefix(); | 43 QString pfx = ResourceFinder().getUserResourcePrefix(); |
43 QDir logdir(QString("%1/%2").arg(pfx).arg("log")); | 44 QDir logdir(QString("%1/%2").arg(pfx).arg("log")); |
44 | 45 |
45 if (!prefix) { | 46 m_prefix = strdup(QString("[%1]") |
46 prefix = strdup(QString("[%1]") | 47 .arg(QCoreApplication::applicationPid()) |
47 .arg(QCoreApplication::applicationPid()) | 48 .toLatin1().data()); |
48 .toLatin1().data()); | |
49 } | |
50 | 49 |
51 //!!! what to do if mkpath fails? | 50 //!!! what to do if mkpath fails? |
52 if (!logdir.exists()) logdir.mkpath(logdir.path()); | 51 if (!logdir.exists()) logdir.mkpath(logdir.path()); |
53 | 52 |
54 if (!debugs.hasLocalData()) { | 53 QString fileName = logdir.path() + "/sv-debug.log"; |
55 QFile *logFile = new QFile(logdir.path() + "/sv-debug.log"); | 54 |
56 if (logFile->open(QIODevice::WriteOnly | QIODevice::Append)) { | 55 m_stream.open(fileName.toLocal8Bit().data(), std::ios_base::out); |
57 QDebug(QtDebugMsg) << (const char *)prefix | 56 |
58 << "Opened debug log file " | 57 if (!m_stream) { |
59 << logFile->fileName(); | 58 QDebug(QtWarningMsg) << (const char *)m_prefix |
60 debug = new QDebug(logFile); | 59 << "Failed to open debug log file " |
61 } else { | 60 << fileName << " for writing"; |
62 QDebug(QtWarningMsg) << (const char *)prefix | |
63 << "Failed to open debug log file " | |
64 << logFile->fileName() | |
65 << " for writing, using console debug instead"; | |
66 delete logFile; | |
67 logFile = 0; | |
68 debug = new QDebug(QtDebugMsg); | |
69 } | |
70 debugs.setLocalData(debug); | |
71 *debug << endl << (const char *)prefix << "Log started at " | |
72 << QDateTime::currentDateTime().toString(); | |
73 } else { | 61 } else { |
74 debug = debugs.localData(); | 62 cerr << m_prefix << ": Log file is " << fileName << endl; |
63 m_ok = true; | |
75 } | 64 } |
65 } | |
76 | 66 |
77 mutex.unlock(); | 67 SVDebug::~SVDebug() |
78 | 68 { |
79 QDebug &dref = *debug; | 69 m_stream.close(); |
80 dref << endl << (const char *)prefix; | |
81 | |
82 return dref; | |
83 } | 70 } |
84 | 71 |
85 QDebug & | 72 QDebug & |
86 operator<<(QDebug &dbg, const std::string &s) | 73 operator<<(QDebug &dbg, const std::string &s) |
87 { | 74 { |
88 dbg << QString::fromUtf8(s.c_str()); | 75 dbg << QString::fromUtf8(s.c_str()); |
89 return dbg; | 76 return dbg; |
90 } | 77 } |
78 | |
79 #endif | |
91 | 80 |
92 std::ostream & | 81 std::ostream & |
93 operator<<(std::ostream &target, const QString &str) | 82 operator<<(std::ostream &target, const QString &str) |
94 { | 83 { |
95 return target << str.toStdString(); | 84 return target << str.toStdString(); |