Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git i/examples/gui/rasterwindow/main.cpp w/examples/gui/rasterwindow/main.cpp
- index bd5c0df1fc..bc7009e641 100644
- --- i/examples/gui/rasterwindow/main.cpp
- +++ w/examples/gui/rasterwindow/main.cpp
- @@ -50,6 +50,8 @@
- #include "rasterwindow.h"
- +//#include <Foundation/Foundation.h>
- +
- //! [1]
- int main(int argc, char **argv)
- {
- @@ -57,6 +59,9 @@ int main(int argc, char **argv)
- RasterWindow window;
- window.show();
- +
- + // NSLog(@"Testing NSLOG");
- + printf("%s\n", qgetenv("OS_ACTIVITY_DT_MODE").constData());
- return app.exec();
- }
- diff --git i/examples/gui/rasterwindow/rasterwindow.cpp w/examples/gui/rasterwindow/rasterwindow.cpp
- index 68d1d7f524..239a242976 100644
- --- i/examples/gui/rasterwindow/rasterwindow.cpp
- +++ w/examples/gui/rasterwindow/rasterwindow.cpp
- @@ -50,11 +50,13 @@
- #include "rasterwindow.h"
- +#include <QDebug>
- //! [1]
- RasterWindow::RasterWindow(QWindow *parent)
- : QWindow(parent)
- , m_backingStore(new QBackingStore(this))
- {
- + qDebug() << "heisan";
- setGeometry(100, 100, 300, 200);
- }
- //! [1]
- diff --git i/src/corelib/global/qlogging.cpp w/src/corelib/global/qlogging.cpp
- index b5ba935194..e97a89dd0f 100644
- --- i/src/corelib/global/qlogging.cpp
- +++ w/src/corelib/global/qlogging.cpp
- @@ -68,6 +68,17 @@
- #include <android/log.h>
- #endif
- +#if defined(Q_OS_DARWIN) && \
- + (QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_12) || !defined(Q_OS_MACOS))
- +#define QT_USE_APPLE_UNIFIED_LOGGING
- +#include <CoreFoundation/CoreFoundation.h>
- +#include <os/availability.h>
- +#include <os/log.h>
- +#include "private/qcore_mac_p.h"
- +#include <sys/uio.h>
- +#include <QThreadStorage>
- +#endif
- +
- #if QT_CONFIG(journald)
- # define SD_JOURNAL_SUPPRESS_LOCATION
- # include <systemd/sd-journal.h>
- @@ -171,6 +182,11 @@ static bool isFatal(QtMsgType msgType)
- return false;
- }
- +static bool is_default_category(const char *category)
- +{
- + return !category || strcmp(category, "default") == 0;
- +}
- +
- static bool willLogToConsole()
- {
- #if defined(Q_OS_WINRT)
- @@ -976,7 +992,6 @@ static const char emptyTokenC[] = "";
- static const char defaultPattern[] = "%{if-category}%{category}: %{endif}%{message}";
- -
- struct QMessagePattern {
- QMessagePattern();
- ~QMessagePattern();
- @@ -997,7 +1012,6 @@ struct QMessagePattern {
- };
- QVector<BacktraceParams> backtraceArgs; // backtrace argumens in sequence of %{backtrace
- #endif
- -
- bool fromEnvironment;
- static QBasicMutex mutex;
- };
- @@ -1339,33 +1353,10 @@ static void slog2_default_handler(QtMsgType msgType, const char *message)
- Q_GLOBAL_STATIC(QMessagePattern, qMessagePattern)
- -/*!
- - \relates <QtGlobal>
- - \since 5.4
- -
- - Generates a formatted string out of the \a type, \a context, \a str arguments.
- -
- - qFormatLogMessage returns a QString that is formatted according to the current message pattern.
- - It can be used by custom message handlers to format output similar to Qt's default message
- - handler.
- -
- - The function is thread-safe.
- -
- - \sa qInstallMessageHandler(), qSetMessagePattern()
- - */
- -QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, const QString &str)
- +static QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, const QString &str, const QMessagePattern &pattern)
- {
- QString message;
- - QMutexLocker lock(&QMessagePattern::mutex);
- -
- - QMessagePattern *pattern = qMessagePattern();
- - if (!pattern) {
- - // after destruction of static QMessagePattern instance
- - message.append(str);
- - return message;
- - }
- -
- bool skip = false;
- #ifndef QT_BOOTSTRAPPED
- @@ -1376,8 +1367,8 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con
- #endif
- // we do not convert file, function, line literals to local encoding due to overhead
- - for (int i = 0; pattern->tokens[i] != 0; ++i) {
- - const char *token = pattern->tokens[i];
- + for (int i = 0; pattern.tokens[i] != 0; ++i) {
- + const char *token = pattern.tokens[i];
- if (token == endifTokenC) {
- skip = false;
- } else if (skip) {
- @@ -1428,15 +1419,15 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con
- message.append(QString::number(qlonglong(QThread::currentThread()->currentThread()), 16));
- #ifdef QLOGGING_HAVE_BACKTRACE
- } else if (token == backtraceTokenC) {
- - QMessagePattern::BacktraceParams backtraceParams = pattern->backtraceArgs.at(backtraceArgsIdx);
- + QMessagePattern::BacktraceParams backtraceParams = pattern.backtraceArgs.at(backtraceArgsIdx);
- backtraceArgsIdx++;
- message.append(formatBacktraceForLogMessage(backtraceParams, context.function));
- #endif
- } else if (token == timeTokenC) {
- - QString timeFormat = pattern->timeArgs.at(timeArgsIdx);
- + QString timeFormat = pattern.timeArgs.at(timeArgsIdx);
- timeArgsIdx++;
- if (timeFormat == QLatin1String("process")) {
- - quint64 ms = pattern->timer.elapsed();
- + quint64 ms = pattern.timer.elapsed();
- message.append(QString::asprintf("%6d.%03d", uint(ms / 1000), uint(ms % 1000)));
- } else if (timeFormat == QLatin1String("boot")) {
- // just print the milliseconds since the elapsed timer reference
- @@ -1454,7 +1445,7 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con
- }
- #endif // !QT_BOOTSTRAPPED
- } else if (token == ifCategoryTokenC) {
- - if (!context.category || (strcmp(context.category, "default") == 0))
- + if (is_default_category(context.category))
- skip = true;
- #define HANDLE_IF_TOKEN(LEVEL) \
- } else if (token == if##LEVEL##TokenC) { \
- @@ -1472,6 +1463,30 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con
- return message;
- }
- +/*!
- + \relates <QtGlobal>
- + \since 5.4
- +
- + Generates a formatted string out of the \a type, \a context, \a str arguments.
- +
- + qFormatLogMessage returns a QString that is formatted according to the current message pattern.
- + It can be used by custom message handlers to format output similar to Qt's default message
- + handler.
- +
- + The function is thread-safe.
- +
- + \sa qInstallMessageHandler(), qSetMessagePattern()
- + */
- +QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, const QString &str)
- +{
- + QMutexLocker lock(&QMessagePattern::mutex);
- + QMessagePattern *pattern = qMessagePattern();
- + if (!pattern)
- + return str; // after destruction of static QMessagePattern instance
- +
- + return qFormatLogMessage(type, context, str, *pattern);
- +}
- +
- #if !QT_DEPRECATED_SINCE(5, 0)
- // make sure they're defined to be exported
- typedef void (*QtMsgHandler)(QtMsgType, const char *);
- @@ -1566,6 +1581,93 @@ static void android_default_message_handler(QtMsgType type,
- }
- #endif //Q_OS_ANDROID
- +#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
- +
- +#if 0
- +QThreadStorage<bool> stderrMirroringDisabled;
- +
- +static ssize_t writev_without_stderr_mirroring(int fd, const struct iovec *iov, int iovcnt)
- +{
- + static bool mirroringToStderr = qEnvironmentVariableIsSet("OS_ACTIVITY_DT_MODE")
- + || qEnvironmentVariableIsSet("ACTIVITY_LOG_STDERR")
- + || qEnvironmentVariableIsSet("CFLOG_FORCE_STDERR");
- +
- + if (fd == STDERR_FILENO && Q_UNLIKELY(mirroringToStderr) && stderrMirroringDisabled.localData()) {
- + ssize_t len = 0;
- + for (int i = 0; i < iovcnt; ++i)
- + len += iov[i].iov_len;
- + return len;
- + }
- +
- + return writev(fd, iov, iovcnt);
- +}
- +
- +
- +#define DYLD_INTERPOSE(_replacee, _replacement) \
- + __attribute__((used)) static struct { const void* replacement; const void* replacee; } _interpose_##_replacee \
- + __attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacement, (const void*)(unsigned long)&_replacee };
- +
- +DYLD_INTERPOSE(writev, writev_without_stderr_mirroring);
- +#endif
- +
- +static void apple_unified_logging_message_handler(QtMsgType type,
- + const QMessageLogContext &context,
- + const QString &message)
- + API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
- +{
- + os_log_type_t priority = OS_LOG_TYPE_DEFAULT;
- + switch (type) {
- + case QtDebugMsg: priority = OS_LOG_TYPE_DEBUG; break;
- + case QtInfoMsg: priority = OS_LOG_TYPE_INFO; break;
- + case QtWarningMsg: priority = OS_LOG_TYPE_DEFAULT; break;
- + case QtCriticalMsg: priority = OS_LOG_TYPE_ERROR; break;
- + case QtFatalMsg: priority = OS_LOG_TYPE_FAULT; break;
- + }
- +
- + static QHash<const char *, os_log_t> appleNativeLogContexts;
- + os_log_t log = is_default_category(context.category) ? OS_LOG_DEFAULT
- + : appleNativeLogContexts.value(context.category);
- +
- + if (!log) {
- + QString subsystem;
- + if (CFBundleRef bundle = CFBundleGetMainBundle()) {
- + if (CFStringRef identifier = CFBundleGetIdentifier(bundle))
- + subsystem = QString::fromCFString(identifier);
- + }
- + log = os_log_create(subsystem.toLocal8Bit().constData(), context.category);
- + appleNativeLogContexts.insert(context.category, log);
- +
- + // Technically we should release the os_log_t resource when done
- + // with it, but since we don't know when a category is disabled
- + // we keep all cached os_log_t instances until shutdown, where
- + // the OS will clean them up for us.
- + }
- +
- + // Logging best practices says we should not include symbolication
- + // information or source file line numbers in messages, as the system
- + // will automatically captures this information. In our case, what
- + // the system captures is the call below, which isn't really useful,
- + // but we still don't want to include the context's info, as that
- + // would clutter the logging output. Swift's _swift_os_log has the
- + // same issue, so when Apple fixes that hopefully they will add an
- + // API that lets you specify the file and line numbers.
- +
- + // Disable _os_log_impl_mirror_to_stderr's writes to stderr while
- + // logging out message, as we do our own stderr printing, without
- + // any timestamp/pid/process name formatting.
- + //stderrMirroringDisabled.setLocalData(true);
- +
- + // The format must be a string constant, so we can't pass on the
- + // message. This means we won't be able to take advantage of the
- + // unified logging's custom format specifiers such as %{BOOL}d.
- + os_log_with_type(log, priority, "%s", qPrintable(message));
- +
- + // Restore normal writev operation for this thread
- + //stderrMirroringDisabled.setLocalData(false);
- +}
- +
- +#endif // QT_USE_APPLE_UNIFIED_LOGGING
- +
- /*!
- \internal
- */
- @@ -1579,6 +1681,17 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
- if (logMessage.isNull())
- return;
- +#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
- + if (__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *)) {
- + apple_unified_logging_message_handler(type, context, logMessage);
- + static bool mirroringToStderr = qEnvironmentVariableIsSet("OS_ACTIVITY_DT_MODE")
- + || qEnvironmentVariableIsSet("ACTIVITY_LOG_STDERR")
- + || qEnvironmentVariableIsSet("CFLOG_FORCE_STDERR");
- + if (mirroringToStderr)
- + return; // Don't log to stderr twice
- + }
- +#endif
- +
- if (!qt_logging_to_console()) {
- #if defined(Q_OS_WIN)
- logMessage.append(QLatin1Char('\n'));
- @@ -1639,11 +1752,10 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex
- {
- #ifndef QT_BOOTSTRAPPED
- // qDebug, qWarning, ... macros do not check whether category is enabled
- - if (!context.category || (strcmp(context.category, "default") == 0)) {
- - if (QLoggingCategory *defaultCategory = QLoggingCategory::defaultCategory()) {
- + if (is_default_category(context.category)) {
- + if (QLoggingCategory *defaultCategory = QLoggingCategory::defaultCategory())
- if (!defaultCategory->isEnabled(msgType))
- return;
- - }
- }
- #endif
Add Comment
Please, Sign In to add comment