summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griebl <robert.griebl@pelagicore.com>2017-03-09 21:42:20 +0100
committerDominik Holland <dominik.holland@pelagicore.com>2017-03-13 15:44:36 +0000
commit3df2058ef31adcd10fdd43c71fcbedf1b10e7a19 (patch)
tree937962a337852bcbf9b8a90e57b08cf494ea1a4c
parent5e7e7da949977357f4621f6712529231a4c71809 (diff)
downloadqtapplicationmanager-3df2058ef31adcd10fdd43c71fcbedf1b10e7a19.tar.gz
common-lib cleanup
global.{h,cpp} and utilities.{h,cpp} have become the kitchensink of the AM. This commit splits out the logging functionality from global.{h,cpp} into the new files logging.{h,cpp} and also the crash handling functionality from utilities.{h,cpp} into the new crashhandler.{h,cpp} Change-Id: Idffdb424b1cbd8d92eb60b0ac7f08e17a46c749b Reviewed-by: Dominik Holland <dominik.holland@pelagicore.com>
-rw-r--r--src/common-lib/common-lib.pro8
-rw-r--r--src/common-lib/crashhandler.cpp327
-rw-r--r--src/common-lib/crashhandler.h55
-rw-r--r--src/common-lib/global.cpp353
-rw-r--r--src/common-lib/global.h31
-rw-r--r--src/common-lib/logging.cpp350
-rw-r--r--src/common-lib/logging.h89
-rw-r--r--src/common-lib/processtitle.cpp2
-rw-r--r--src/common-lib/processtitle.h1
-rw-r--r--src/common-lib/unixsignalhandler.cpp1
-rw-r--r--src/common-lib/unixsignalhandler.h3
-rw-r--r--src/common-lib/utilities.cpp295
-rw-r--r--src/common-lib/utilities.h4
-rw-r--r--src/installer-lib/applicationinstaller.cpp1
-rw-r--r--src/installer-lib/deinstallationtask.cpp1
-rw-r--r--src/installer-lib/installationtask.cpp1
-rw-r--r--src/installer-lib/scopeutilities.cpp1
-rw-r--r--src/installer-lib/sudo.cpp1
-rw-r--r--src/launcher-lib/applicationmanagerwindow.cpp1
-rw-r--r--src/launcher-lib/qmlapplicationinterfaceextension.cpp1
-rw-r--r--src/launchers/qml/main.cpp18
-rw-r--r--src/manager-lib/abstractcontainer.h3
-rw-r--r--src/manager-lib/abstractruntime.cpp1
-rw-r--r--src/manager-lib/abstractruntime.h1
-rw-r--r--src/manager-lib/applicationipcinterface.cpp1
-rw-r--r--src/manager-lib/applicationipcmanager.cpp1
-rw-r--r--src/manager-lib/applicationmanager.cpp2
-rw-r--r--src/manager-lib/containerfactory.cpp1
-rw-r--r--src/manager-lib/containerfactory.h2
-rw-r--r--src/manager-lib/fakeapplicationmanagerwindow.cpp1
-rw-r--r--src/manager-lib/memorymonitor.cpp1
-rw-r--r--src/manager-lib/nativeruntime.cpp3
-rw-r--r--src/manager-lib/nativeruntime.h1
-rw-r--r--src/manager-lib/notificationmanager.cpp2
-rw-r--r--src/manager-lib/processcontainer.cpp1
-rw-r--r--src/manager-lib/processmonitor.cpp1
-rw-r--r--src/manager-lib/qmlinprocessapplicationinterface.cpp1
-rw-r--r--src/manager-lib/qmlinprocessruntime.cpp1
-rw-r--r--src/manager-lib/quicklauncher.cpp1
-rw-r--r--src/manager-lib/runtimefactory.cpp1
-rw-r--r--src/manager-lib/systemmonitor.cpp7
-rw-r--r--src/manager-lib/systemmonitor_p.cpp1
-rw-r--r--src/manager/configuration.cpp1
-rw-r--r--src/manager/main.cpp11
-rw-r--r--src/manager/qmllogger.cpp1
-rw-r--r--src/tools/testrunner/testrunner.h1
-rw-r--r--src/window-lib/waylandcompositor.cpp1
-rw-r--r--src/window-lib/waylandwindow.cpp1
-rw-r--r--src/window-lib/windowmanager.cpp1
49 files changed, 910 insertions, 685 deletions
diff --git a/src/common-lib/common-lib.pro b/src/common-lib/common-lib.pro
index 2ee61ff9..13481fa7 100644
--- a/src/common-lib/common-lib.pro
+++ b/src/common-lib/common-lib.pro
@@ -26,7 +26,9 @@ SOURCES += \
startuptimer.cpp \
dbus-policy.cpp \
unixsignalhandler.cpp \
- processtitle.cpp
+ processtitle.cpp \
+ crashhandler.cpp \
+ logging.cpp
qtHaveModule(qml):SOURCES += \
qml-utilities.cpp \
@@ -43,7 +45,9 @@ HEADERS += \
startuptimer.h \
dbus-policy.h \
unixsignalhandler.h \
- processtitle.h
+ processtitle.h \
+ crashhandler.h \
+ logging.h
qtHaveModule(qml):HEADERS += \
qml-utilities.h \
diff --git a/src/common-lib/crashhandler.cpp b/src/common-lib/crashhandler.cpp
new file mode 100644
index 00000000..637ebcc8
--- /dev/null
+++ b/src/common-lib/crashhandler.cpp
@@ -0,0 +1,327 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+#include "crashhandler.h"
+#include "global.h"
+
+#if !defined(Q_OS_LINUX)
+
+QT_BEGIN_NAMESPACE_AM
+
+void CrashHandler::setCrashActionConfiguration(const QVariantMap &config)
+{
+ Q_UNUSED(config)
+}
+
+QT_END_NAMESPACE_AM
+
+#else
+
+#include <cxxabi.h>
+#include <execinfo.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <inttypes.h>
+
+#if defined(AM_USE_LIBBACKTRACE)
+# include <libbacktrace/backtrace.h>
+# include <libbacktrace/backtrace-supported.h>
+#endif
+
+#include "unixsignalhandler.h"
+#include "utilities.h"
+#include "processtitle.h"
+
+QT_BEGIN_NAMESPACE_AM
+
+static bool printBacktrace;
+static bool useAnsiColor;
+static bool dumpCore;
+static int waitForGdbAttach;
+
+static char *demangleBuffer;
+static size_t demangleBufferSize;
+
+// this will make it run before all other static constructor functions
+static void initBacktrace() __attribute__((constructor(101)));
+
+static void crashHandler(const char *why, int stackFramesToIgnore) __attribute__((noreturn));
+
+void CrashHandler::setCrashActionConfiguration(const QVariantMap &config)
+{
+ printBacktrace = config.value(qSL("printBacktrace"), printBacktrace).toBool();
+ waitForGdbAttach = config.value(qSL("waitForGdbAttach"), waitForGdbAttach).toInt();
+ dumpCore = config.value(qSL("dumpCore"), dumpCore).toBool();
+}
+
+
+static void initBacktrace()
+{
+ // This can catch and pretty-print all of the following:
+
+ // SIGFPE
+ // volatile int i = 2;
+ // int zero = 0;
+ // i /= zero;
+
+ // SIGSEGV
+ // *((int *)1) = 1;
+
+ // uncaught arbitrary exception
+ // throw 42;
+
+ // uncaught std::exception derived exception (prints what())
+ // throw std::logic_error("test output");
+
+ printBacktrace = true;
+ dumpCore = true;
+ waitForGdbAttach = false;
+
+ getOutputInformation(&useAnsiColor, nullptr, nullptr);
+
+ demangleBufferSize = 512;
+ demangleBuffer = (char *) malloc(demangleBufferSize);
+
+ UnixSignalHandler::instance()->install(UnixSignalHandler::RawSignalHandler,
+ { SIGFPE, SIGSEGV, SIGILL, SIGBUS, SIGPIPE, SIGABRT },
+ [](int sig) {
+ UnixSignalHandler::instance()->resetToDefault(sig);
+ static char buffer[256];
+ snprintf(buffer, sizeof(buffer), "uncaught signal %d (%s)", sig, UnixSignalHandler::signalName(sig));
+ // 6 means to remove 6 stack frames: this way the backtrace starts at the point where
+ // the signal reception interrupted the normal program flow
+ crashHandler(buffer, 6);
+ });
+
+ std::set_terminate([]() {
+ static char buffer [1024];
+
+ auto type = abi::__cxa_current_exception_type();
+ if (!type) {
+ // 3 means to remove 3 stack frames: this way the backtrace starts at std::terminate
+ crashHandler("terminate was called although no exception was thrown", 3);
+ }
+
+ const char *typeName = type->name();
+ if (typeName) {
+ int status;
+ abi::__cxa_demangle(typeName, demangleBuffer, &demangleBufferSize, &status);
+ if (status == 0 && *demangleBuffer) {
+ typeName = demangleBuffer;
+ }
+ }
+ try {
+ throw;
+ } catch (const std::exception &exc) {
+ snprintf(buffer, sizeof(buffer), "uncaught exception of type %s (%s)", typeName, exc.what());
+ } catch (...) {
+ snprintf(buffer, sizeof(buffer), "uncaught exception of type %s", typeName);
+ }
+
+ // 4 means to remove 4 stack frames: this way the backtrace starts at std::terminate
+ crashHandler(buffer, 4);
+ });
+}
+
+static void crashHandler(const char *why, int stackFramesToIgnore)
+{
+ pid_t pid = getpid();
+ char who[256];
+ int whoLen = readlink("/proc/self/exe", who, sizeof(who) -1);
+ who[qMax(0, whoLen)] = '\0';
+ const char *title = ProcessTitle::title();
+
+ fprintf(stderr, "\n*** process %s (%d) crashed ***\n\n > why: %s\n", title ? title : who, pid, why);
+
+ if (printBacktrace) {
+#if defined(AM_USE_LIBBACKTRACE) && defined(BACKTRACE_SUPPORTED)
+ struct btData
+ {
+ backtrace_state *state;
+ int level;
+ };
+
+ static auto printBacktraceLine = [](int level, const char *symbol, uintptr_t offset, const char *file = nullptr, int line = -1) {
+ const char *fmt1 = " %3d: %s [%" PRIxPTR "]";
+ const char *fmt2 = " in %s:%d";
+ if (useAnsiColor) {
+ fmt1 = " %3d: \x1b[1m%s\x1b[0m [\x1b[36m%" PRIxPTR "\x1b[0m]";
+ fmt2 = " in \x1b[35m%s\x1b[0m:\x1b[35;1m%d\x1b[0m";
+ }
+
+ fprintf(stderr, fmt1, level, symbol, offset);
+ if (file)
+ fprintf(stderr, fmt2, file, line);
+ fputs("\n", stderr);
+ };
+
+ static auto errorCallback = [](void *data, const char *msg, int errnum) {
+ const char *fmt = " %3d: ERROR: %s (%d)\n";
+ if (useAnsiColor)
+ fmt = " %3d: \x1b[31;1mERROR: \x1b[0;1m%s (%d)\x1b[0m\n";
+
+ fprintf(stderr, fmt, static_cast<btData *>(data)->level, msg, errnum);
+ };
+
+ static auto syminfoCallback = [](void *data, uintptr_t pc, const char *symname, uintptr_t symval, uintptr_t symsize) {
+ Q_UNUSED(symval)
+ Q_UNUSED(symsize)
+
+ int level = static_cast<btData *>(data)->level;
+ if (symname) {
+ int status;
+ abi::__cxa_demangle(symname, demangleBuffer, &demangleBufferSize, &status);
+
+ if (status == 0 && *demangleBuffer)
+ printBacktraceLine(level, demangleBuffer, pc);
+ else
+ printBacktraceLine(level, symname, pc);
+ } else {
+ printBacktraceLine(level, nullptr, pc);
+ }
+ };
+
+ static auto fullCallback = [](void *data, uintptr_t pc, const char *filename, int lineno, const char *function) -> int {
+ if (function) {
+ int status;
+ abi::__cxa_demangle(function, demangleBuffer, &demangleBufferSize, &status);
+
+ printBacktraceLine(static_cast<btData *>(data)->level,
+ (status == 0 && *demangleBuffer) ? demangleBuffer : function,
+ pc, filename ? filename : "<unknown>", lineno);
+ } else {
+ backtrace_syminfo (static_cast<btData *>(data)->state, pc, syminfoCallback, errorCallback, data);
+ }
+ return 0;
+ };
+
+ static auto simpleCallback = [](void *data, uintptr_t pc) -> int {
+ backtrace_pcinfo(static_cast<btData *>(data)->state, pc, fullCallback, errorCallback, data);
+ static_cast<btData *>(data)->level++;
+ return 0;
+ };
+
+ struct backtrace_state *state = backtrace_create_state(nullptr, BACKTRACE_SUPPORTS_THREADS,
+ errorCallback, nullptr);
+
+ fprintf(stderr, "\n > backtrace:\n");
+ btData data = { state, 0 };
+ //backtrace_print(state, stackFramesToIgnore, stderr);
+ backtrace_simple(state, stackFramesToIgnore, simpleCallback, errorCallback, &data);
+#else // !defined(AM_USE_LIBBACKTRACE) && defined(BACKTRACE_SUPPORTED)
+ Q_UNUSED(stackFramesToIgnore);
+ void *addrArray[1024];
+ int addrCount = backtrace(addrArray, sizeof(addrArray) / sizeof(*addrArray));
+
+ if (!addrCount) {
+ fprintf(stderr, " > no backtrace available\n");
+ } else {
+ char **symbols = backtrace_symbols(addrArray, addrCount);
+ //backtrace_symbols_fd(addrArray, addrCount, 2);
+
+ if (!symbols) {
+ fprintf(stderr, " > no symbol names available\n");
+ } else {
+ fprintf(stderr, " > backtrace:\n");
+ for (int i = 1; i < addrCount; ++i) {
+ char *function = nullptr;
+ char *offset = nullptr;
+ char *end = nullptr;
+
+ for (char *ptr = symbols[i]; ptr && *ptr; ++ptr) {
+ if (!function && *ptr == '(')
+ function = ptr + 1;
+ else if (function && !offset && *ptr == '+')
+ offset = ptr;
+ else if (function && !end && *ptr == ')')
+ end = ptr;
+ }
+
+ if (function && offset && end && (function != offset)) {
+ *offset = 0;
+ *end = 0;
+
+ int status;
+ abi::__cxa_demangle(function, demangleBuffer, &demangleBufferSize, &status);
+
+ if (status == 0 && *demangleBuffer) {
+ fprintf(stderr, " %3d: %s [+%s]\n", i, demangleBuffer, offset + 1);
+ } else {
+ fprintf(stderr, " %3d: %s [+%s]\n", i, function, offset + 1);
+ }
+ } else {
+ fprintf(stderr, " %3d: %s\n", i, symbols[i]);
+ }
+ }
+ fprintf(stderr, "\n");
+ }
+ }
+#endif // defined(AM_USE_LIBBACKTRACE) && defined(BACKTRACE_SUPPORTED)
+ }
+ if (waitForGdbAttach > 0) {
+ fprintf(stderr, "\n > the process will be suspended for %d seconds and you can attach a debugger to it via\n\n gdb -p %d\n",
+ waitForGdbAttach, pid);
+ static jmp_buf jmpenv;
+ signal(SIGALRM, [](int) {
+ longjmp(jmpenv, 1);
+ });
+ if (!setjmp(jmpenv)) {
+ alarm(waitForGdbAttach);
+
+ sigset_t mask;
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGALRM);
+ sigsuspend(&mask);
+ } else {
+ fprintf(stderr, "\n > no gdb attached\n");
+ }
+ }
+ if (dumpCore) {
+ fprintf(stderr, "\n > the process will be aborted (core dump)\n\n");
+ UnixSignalHandler::instance()->resetToDefault({ SIGFPE, SIGSEGV, SIGILL, SIGBUS, SIGPIPE, SIGABRT });
+ abort();
+ }
+ _Exit(-1);
+}
+
+QT_END_NAMESPACE_AM
+
+#endif // !Q_OS_LINUX
diff --git a/src/common-lib/crashhandler.h b/src/common-lib/crashhandler.h
new file mode 100644
index 00000000..9c6f32d3
--- /dev/null
+++ b/src/common-lib/crashhandler.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QtAppManCommon/global.h>
+#include <QVariantMap>
+
+QT_BEGIN_NAMESPACE_AM
+
+namespace CrashHandler {
+
+void setCrashActionConfiguration(const QVariantMap &config);
+
+}
+
+QT_END_NAMESPACE_AM
diff --git a/src/common-lib/global.cpp b/src/common-lib/global.cpp
index 4b0cb491..e69de29b 100644
--- a/src/common-lib/global.cpp
+++ b/src/common-lib/global.cpp
@@ -1,353 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Pelagicore AG
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Pelagicore Application Manager.
-**
-** $QT_BEGIN_LICENSE:LGPL-QTAS$
-** Commercial License Usage
-** Licensees holding valid commercial Qt Automotive Suite licenses may use
-** this file in accordance with the commercial license agreement provided
-** with the Software or, alternatively, in accordance with the terms
-** contained in a written agreement between you and The Qt Company. For
-** licensing terms and conditions see https://www.qt.io/terms-conditions.
-** For further information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-** SPDX-License-Identifier: LGPL-3.0
-**
-****************************************************************************/
-
-#include <QFile>
-#include <QNetworkInterface>
-#include <QThreadStorage>
-#include <QAtomicInteger>
-
-#include "global.h"
-#include "utilities.h"
-
-#include <stdio.h>
-#if defined(Q_OS_WIN)
-Q_CORE_EXPORT void qWinMsgHandler(QtMsgType t, const char* str);
-# include <windows.h>
-#endif
-#if defined(Q_OS_ANDROID)
-# include <QCoreApplication>
-# include <android/log.h>
-#endif
-
-#if defined(QT_GENIVIEXTRAS_LIB)
-# include <QtGeniviExtras/QtDlt>
-# include <QtGeniviExtras/QDltRegistration>
-#else
-# define QDLT_LOGGING_CATEGORY(a,b,c,d) Q_LOGGING_CATEGORY(a,b)
-# define QDLT_FALLBACK_CATEGORY(a)
-# define QDLT_REGISTER_APPLICATION(a,b)
-#endif
-
-#ifndef QDLT_REGISTER_CONTEXT_ON_FIRST_USE
-# define QDLT_REGISTER_CONTEXT_ON_FIRST_USE(a)
-#endif
-
-QT_BEGIN_NAMESPACE_AM
-
-/*
-//! [am-logging-categories]
-\list
-\li \c am.installer - Installer sub-system
-\li \c am.notify - Notification sub-system
-\li \c am.qml - QML messages
-\li \c am.qml.ipc - QML IPC
-\li \c am.runtime.qml - QML runtime
-\li \c am.system - General system messages
-\li \c am.wayland - Wayland sub-system
-\li \c general - General messages not part of any ApplicationManager sub-system
-\endlist
-//! [am-logging-categories]
-*/
-QDLT_REGISTER_CONTEXT_ON_FIRST_USE(true)
-QDLT_REGISTER_APPLICATION("PCAM", "Pelagicore Application-Manager")
-QDLT_LOGGING_CATEGORY(LogSystem, "am.system", "SYS", "General system messages")
-QDLT_LOGGING_CATEGORY(LogInstaller, "am.installer", "INST", "Installer sub-system")
-QDLT_LOGGING_CATEGORY(LogWayland, "am.wayland", "WAYL", "Wayland sub-system")
-QDLT_LOGGING_CATEGORY(LogQml, "am.qml", "QML", "QML messages")
-QDLT_LOGGING_CATEGORY(LogNotifications, "am.notify", "NTFY", "Notification sub-system")
-QDLT_LOGGING_CATEGORY(LogQmlRuntime, "am.runtime.qml", "QMRT", "QML runtime")
-QDLT_LOGGING_CATEGORY(LogQmlIpc, "am.qml.ipc", "QMIP", "QML IPC")
-QDLT_LOGGING_CATEGORY(LogGeneral, "general", "GEN", "General messages not part of any ApplicationManager sub-system")
-QDLT_FALLBACK_CATEGORY(LogGeneral)
-
-
-QByteArray colorLogApplicationId = QByteArray();
-bool dltLoggingEnabled = true;
-
-static void colorLogToStderr(QtMsgType msgType, const QMessageLogContext &context, const QString &message)
-{
-#if defined(QT_GENIVIEXTRAS_LIB)
- if (dltLoggingEnabled)
- QDltRegistration::messageHandler(msgType, context, message);
-#endif
-
- if (msgType < QtDebugMsg || msgType > QtInfoMsg)
- msgType = QtCriticalMsg;
-
- // Try to re-use a 512 byte buffer per thread as much as possible to avoid allocations.
- static QThreadStorage<QByteArray> outBuffers;
- QByteArray &out = outBuffers.localData();
- if (out.capacity() > 512)
- out.clear();
- if (!out.capacity())
- out.reserve(512);
- out.resize(0);
-
- int consoleWidth = -1;
- bool ansiColorSupport = false;
- bool runningInCreator = false;
- getOutputInformation(&ansiColorSupport, &runningInCreator, &consoleWidth);
-
- // Find out, if we have a valid code location and prepare the output strings
- const char *filename = nullptr;
- int filenameLength = 0;
- char linenumber[8];
- int linenumberLength = 0;
-
- if (context.line > 0 && context.file && context.file[0]) {
- QByteArray ba = QByteArray::fromRawData(context.file, strlen(context.file));
- int pos = -1;
-#if defined(Q_OS_WIN)
- pos = ba.lastIndexOf('\\');
-#endif
- if (pos < 0)
- pos = ba.lastIndexOf('/');
- if (pos >= 0) {
- filename = context.file + pos + 1;
- filenameLength = ba.size() - pos - 1;
-
- linenumberLength = qsnprintf(linenumber, 8, "%d", qMin(context.line, 9999999));
- if (linenumberLength < 0 || linenumberLength >= int(sizeof(linenumber)))
- linenumberLength = 0;
- linenumber[linenumberLength] = 0;
- }
- }
-
- enum ConsoleColor { Off = 0, Black, Red, Green, Yellow, Blue, Magenta, Cyan, Gray, BrightFlag = 0x80 };
-
- // helper function to append ANSI color codes to a string
- static auto color = [ansiColorSupport](QByteArray &out, int consoleColor) -> void {
- static const char *ansiColors[] = {
- "\x1b[1m", // bright
- "\x1b[0m", // off
- "\x1b[30m", // black
- "\x1b[31m", // red
- "\x1b[32m", // green
- "\x1b[33m", // yellow
- "\x1b[34m", // blue
- "\x1b[35m", // magenta
- "\x1b[36m", // cyan
- "\x1b[37m" // gray
- };
-
- if (!ansiColorSupport)
- return;
- if (consoleColor & BrightFlag)
- out.append(ansiColors[0]);
- out.append(ansiColors[1 + (consoleColor & ~BrightFlag)]);
- };
-
- static const char *msgTypeStr[] = { "DBG ", "WARN", "CRIT", "FATL", "INFO" };
- static const ConsoleColor msgTypeColor[] = { Green, Yellow, Red, Magenta, Blue };
- int categoryLength = strlen(context.category);
- QByteArray msg = message.toLocal8Bit(); // sadly this allocates, but there's no other way in Qt
-
- // the visible character length
- int outLength = 10 + strlen(context.category) + msg.length(); // 10 = strlen("[XXXX | ] ")
- out.append('[');
-
- color(out, BrightFlag | msgTypeColor[msgType]);
- out.append(msgTypeStr[msgType], 4); // all msgTypeStrs are 4 characters
- color(out, Off);
-
- out.append(" | ");
-
- color(out, Red + qHash(QByteArray::fromRawData(context.category, categoryLength)) % 7);
- out.append(context.category, categoryLength);
- color(out, Off);
-
- if (!colorLogApplicationId.isEmpty()) {
- out.append(" | ");
-
- color(out, Red + qHash(colorLogApplicationId) % 7);
- out.append(colorLogApplicationId);
- color(out, Off);
-
- outLength += (3 + colorLogApplicationId.length()); // 3 == strlen(" | ")
- }
-
- out.append("] ");
- out.append(msg);
-
- if (filenameLength && linenumberLength) {
- int spacing = 1;
- if (consoleWidth > 0) {
- // right-align the location mark
- spacing = consoleWidth - outLength - linenumberLength - filenameLength - 4; // 4 == strlen(" [:]")
-
- // keep the location mark right-aligned, even if the message contains newlines
- int lastNewline = msg.lastIndexOf('\n');
- if (lastNewline >= 0)
- spacing += (outLength - msg.length() + lastNewline + 1);
-
- // keep the location mark right-aligned, even if the message is longer than the window width
- while (spacing < 0)
- spacing += consoleWidth;
- }
-#if QT_VERSION < QT_VERSION_CHECK(5,7,0)
- // efficiently appending spaces without allocating is hard in Qt 5.6
- static const char spacingStr[] = " ";
- Q_STATIC_ASSERT(sizeof(spacingStr) == 80);
- while (spacing > 0) {
- int spacingLen = qMin(spacing, int(sizeof(spacingStr)) - 1);
- out.append(spacingStr, spacingLen);
- spacing -= spacingLen;
- }
-#else
- out.append(spacing, ' ');
-#endif
- out.append('[');
-
- color(out, Magenta);
- out.append(filename, filenameLength);
- color(out, Off);
-
- out.append(':');
-
- color(out, BrightFlag | Magenta);
- out.append(linenumber, linenumberLength);
- color(out, Off);
-
- out.append("]\n");
- } else {
- out.append('\n');
- }
-
- if (consoleWidth <= 0) {
-#if defined(Q_OS_WIN)
- // do not use QMutex to avoid possible recursions
- static CRITICAL_SECTION cs;
- static bool csInitialized = false;
- if (!csInitialized)
- InitializeCriticalSection(&cs);
-
- EnterCriticalSection(&cs);
- OutputDebugStringA(out.constData());
- LeaveCriticalSection(&cs);
- return;
-
-#elif defined(Q_OS_ANDROID)
- android_LogPriority pri = ANDROID_LOG_DEBUG;
- switch (msgType) {
- default:
- case QtDebugMsg: pri = ANDROID_LOG_DEBUG; break;
- case QtWarningMsg: pri = ANDROID_LOG_WARN; break;
- case QtCriticalMsg: pri = ANDROID_LOG_ERROR; break;
- case QtFatalMsg: pri = ANDROID_LOG_FATAL; break;
- };
-
- static QByteArray appName = QCoreApplication::applicationName().toLocal8Bit();
-
- __android_log_print(pri, appName.constData(), out.constData());
- return;
-#endif
- }
- fputs(out.constData(), stderr);
-}
-
-#if defined(QT_GENIVIEXTRAS_LIB)
-
-static QtMessageHandler defaultQtMsgHandler;
-
-static void compositeMsgHandler(QtMsgType msgType, const QMessageLogContext &context, const QString &message)
-{
- if (dltLoggingEnabled)
- QDltRegistration::messageHandler(msgType, context, message);
- defaultQtMsgHandler(msgType, context, message);
-}
-
-#endif
-
-void installMessageHandlers()
-{
- if (Q_LIKELY(!qEnvironmentVariableIsSet("QT_MESSAGE_PATTERN")))
- qInstallMessageHandler(colorLogToStderr);
-#if defined(QT_GENIVIEXTRAS_LIB)
- else
- defaultQtMsgHandler = qInstallMessageHandler(compositeMsgHandler);
-#endif
-}
-
-QString hardwareId()
-{
-#if defined(AM_HARDWARE_ID)
- return QString::fromLocal8Bit(AM_HARDWARE_ID);
-#elif defined(AM_HARDWARE_ID_FROM_FILE)
- QFile f(QString::fromLocal8Bit(AM_HARDWARE_ID_FROM_FILE));
- if (f.open(QFile::ReadOnly))
- return f.readAll().trimmed();
-#else
- foreach (const QNetworkInterface &iface, QNetworkInterface::allInterfaces()) {
- if (iface.isValid() && (iface.flags() & QNetworkInterface::IsUp)
- && !(iface.flags() & (QNetworkInterface::IsPointToPoint | QNetworkInterface::IsLoopBack))
- && !iface.hardwareAddress().isEmpty()) {
- return iface.hardwareAddress().replace(qL1C(':'), qL1S("-"));
- }
- }
-#endif
- return QString();
-}
-
-void am_trace(QDebug)
-{ }
-
-void registerUnregisteredDLTContexts()
-{
- if (!dltLoggingEnabled)
- return;
-#ifdef AM_GENIVIEXTRAS_LAZY_INIT
- globalDltRegistration()->registerUnregisteredContexts();
-#endif
-}
-
-void changeDLTApplication(const char *dltAppID, const char *dltAppDescription)
-{
- if (!dltLoggingEnabled)
- return;
-#if defined(QT_GENIVIEXTRAS_LIB)
- globalDltRegistration()->registerApplication(dltAppID, dltAppDescription);
-#else
- Q_UNUSED(dltAppID)
- Q_UNUSED(dltAppDescription)
-#endif
-}
-
-QT_END_NAMESPACE_AM
diff --git a/src/common-lib/global.h b/src/common-lib/global.h
index ce8ae9b0..18d35061 100644
--- a/src/common-lib/global.h
+++ b/src/common-lib/global.h
@@ -41,44 +41,15 @@
#pragma once
#include <qglobal.h>
-#include <QLoggingCategory>
#define QT_BEGIN_NAMESPACE_AM namespace QtAM {
#define QT_END_NAMESPACE_AM }
#define QT_USE_NAMESPACE_AM using namespace QtAM;
#define QT_PREPEND_NAMESPACE_AM(name) QtAM::name
-QT_BEGIN_NAMESPACE_AM
-
-Q_DECLARE_LOGGING_CATEGORY(LogSystem)
-Q_DECLARE_LOGGING_CATEGORY(LogInstaller)
-Q_DECLARE_LOGGING_CATEGORY(LogWayland)
-Q_DECLARE_LOGGING_CATEGORY(LogQml)
-Q_DECLARE_LOGGING_CATEGORY(LogNotifications)
-Q_DECLARE_LOGGING_CATEGORY(LogQmlRuntime)
-Q_DECLARE_LOGGING_CATEGORY(LogQmlIpc)
-
-void registerUnregisteredDLTContexts();
-void changeDLTApplication(const char *dltAppID, const char *dltAppDescription);
-
-void installMessageHandlers();
-
-extern QByteArray colorLogApplicationId;
-extern bool dltLoggingEnabled;
-
-QString hardwareId();
-
-void am_trace(QDebug);
-template <typename T, typename... TRest> void am_trace(QDebug dbg, T t, TRest... trest)
-{ dbg << t; am_trace(dbg, trest...); }
-
+QT_BEGIN_NAMESPACE_AM // make sure the namespace exists
QT_END_NAMESPACE_AM
-#define AM_TRACE(category, ...) \
- for (bool qt_category_enabled = category().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) { \
- QT_PREPEND_NAMESPACE_AM(am_trace(QMessageLogger(__FILE__, __LINE__, __FUNCTION__, category().categoryName()).debug(), "TRACE", __FUNCTION__, __VA_ARGS__)); \
- }
-
// make the source a lot less ugly and more readable (until we can finally use user defined literals)
#define qL1S(x) QLatin1String(x)
#define qL1C(x) QLatin1Char(x)
diff --git a/src/common-lib/logging.cpp b/src/common-lib/logging.cpp
new file mode 100644
index 00000000..47272549
--- /dev/null
+++ b/src/common-lib/logging.cpp
@@ -0,0 +1,350 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+#include <QThreadStorage>
+#include <QAtomicInteger>
+
+#include "global.h"
+#include "logging.h"
+#include "utilities.h"
+
+#include <stdio.h>
+#if defined(Q_OS_WIN)
+Q_CORE_EXPORT void qWinMsgHandler(QtMsgType t, const char* str);
+# include <windows.h>
+#endif
+#if defined(Q_OS_ANDROID)
+# include <QCoreApplication>
+# include <android/log.h>
+#endif
+
+#if defined(QT_GENIVIEXTRAS_LIB)
+# include <QtGeniviExtras/QtDlt>
+# include <QtGeniviExtras/QDltRegistration>
+#else
+# define QDLT_LOGGING_CATEGORY(a,b,c,d) Q_LOGGING_CATEGORY(a,b)
+# define QDLT_FALLBACK_CATEGORY(a)
+# define QDLT_REGISTER_APPLICATION(a,b)
+#endif
+
+#ifndef QDLT_REGISTER_CONTEXT_ON_FIRST_USE
+# define QDLT_REGISTER_CONTEXT_ON_FIRST_USE(a)
+#endif
+
+QT_BEGIN_NAMESPACE_AM
+
+/*
+//! [am-logging-categories]
+\list
+\li \c am.installer - Installer sub-system
+\li \c am.notify - Notification sub-system
+\li \c am.qml - QML messages
+\li \c am.qml.ipc - QML IPC
+\li \c am.runtime.qml - QML runtime
+\li \c am.system - General system messages
+\li \c am.wayland - Wayland sub-system
+\li \c general - General messages not part of any ApplicationManager sub-system
+\endlist
+//! [am-logging-categories]
+*/
+QDLT_REGISTER_CONTEXT_ON_FIRST_USE(true)
+QDLT_REGISTER_APPLICATION("PCAM", "Pelagicore Application-Manager")
+QDLT_LOGGING_CATEGORY(LogSystem, "am.system", "SYS", "General system messages")
+QDLT_LOGGING_CATEGORY(LogInstaller, "am.installer", "INST", "Installer sub-system")
+QDLT_LOGGING_CATEGORY(LogWayland, "am.wayland", "WAYL", "Wayland sub-system")
+QDLT_LOGGING_CATEGORY(LogQml, "am.qml", "QML", "QML messages")
+QDLT_LOGGING_CATEGORY(LogNotifications, "am.notify", "NTFY", "Notification sub-system")
+QDLT_LOGGING_CATEGORY(LogQmlRuntime, "am.runtime.qml", "QMRT", "QML runtime")
+QDLT_LOGGING_CATEGORY(LogQmlIpc, "am.qml.ipc", "QMIP", "QML IPC")
+QDLT_LOGGING_CATEGORY(LogGeneral, "general", "GEN", "General messages not part of any ApplicationManager sub-system")
+QDLT_FALLBACK_CATEGORY(LogGeneral)
+
+
+bool Logging::s_dltEnabled =
+#if defined(QT_GENIVIEXTRAS_LIB)
+ true;
+#else
+ false;
+#endif
+bool Logging::s_useDefaultQtHandler = false;
+QtMessageHandler Logging::s_defaultQtHandler = nullptr;
+QByteArray Logging::s_applicationId = QByteArray();
+
+
+static void colorLogToStderr(QtMsgType msgType, const QMessageLogContext &context, const QString &message)
+{
+ if (msgType < QtDebugMsg || msgType > QtInfoMsg)
+ msgType = QtCriticalMsg;
+
+ // Try to re-use a 512 byte buffer per thread as much as possible to avoid allocations.
+ static QThreadStorage<QByteArray> outBuffers;
+ QByteArray &out = outBuffers.localData();
+ if (out.capacity() > 512)
+ out.clear();
+ if (!out.capacity())
+ out.reserve(512);
+ out.resize(0);
+
+ int consoleWidth = -1;
+ bool ansiColorSupport = false;
+ bool runningInCreator = false;
+ getOutputInformation(&ansiColorSupport, &runningInCreator, &consoleWidth);
+
+ // Find out, if we have a valid code location and prepare the output strings
+ const char *filename = nullptr;
+ int filenameLength = 0;
+ char linenumber[8];
+ int linenumberLength = 0;
+
+ if (context.line > 0 && context.file && context.file[0]) {
+ QByteArray ba = QByteArray::fromRawData(context.file, strlen(context.file));
+ int pos = -1;
+#if defined(Q_OS_WIN)
+ pos = ba.lastIndexOf('\\');
+#endif
+ if (pos < 0)
+ pos = ba.lastIndexOf('/');
+ if (pos >= 0) {
+ filename = context.file + pos + 1;
+ filenameLength = ba.size() - pos - 1;
+
+ linenumberLength = qsnprintf(linenumber, 8, "%d", qMin(context.line, 9999999));
+ if (linenumberLength < 0 || linenumberLength >= int(sizeof(linenumber)))
+ linenumberLength = 0;
+ linenumber[linenumberLength] = 0;
+ }
+ }
+
+ enum ConsoleColor { Off = 0, Black, Red, Green, Yellow, Blue, Magenta, Cyan, Gray, BrightFlag = 0x80 };
+
+ // helper function to append ANSI color codes to a string
+ static auto color = [ansiColorSupport](QByteArray &out, int consoleColor) -> void {
+ static const char *ansiColors[] = {
+ "\x1b[1m", // bright
+ "\x1b[0m", // off
+ "\x1b[30m", // black
+ "\x1b[31m", // red
+ "\x1b[32m", // green
+ "\x1b[33m", // yellow
+ "\x1b[34m", // blue
+ "\x1b[35m", // magenta
+ "\x1b[36m", // cyan
+ "\x1b[37m" // gray
+ };
+
+ if (!ansiColorSupport)
+ return;
+ if (consoleColor & BrightFlag)
+ out.append(ansiColors[0]);
+ out.append(ansiColors[1 + (consoleColor & ~BrightFlag)]);
+ };
+
+ static const char *msgTypeStr[] = { "DBG ", "WARN", "CRIT", "FATL", "INFO" };
+ static const ConsoleColor msgTypeColor[] = { Green, Yellow, Red, Magenta, Blue };
+ int categoryLength = strlen(context.category);
+ QByteArray msg = message.toLocal8Bit(); // sadly this allocates, but there's no other way in Qt
+
+ // the visible character length
+ int outLength = 10 + strlen(context.category) + msg.length(); // 10 = strlen("[XXXX | ] ")
+ out.append('[');
+
+ color(out, BrightFlag | msgTypeColor[msgType]);
+ out.append(msgTypeStr[msgType], 4); // all msgTypeStrs are 4 characters
+ color(out, Off);
+
+ out.append(" | ");
+
+ color(out, Red + qHash(QByteArray::fromRawData(context.category, categoryLength)) % 7);
+ out.append(context.category, categoryLength);
+ color(out, Off);
+
+ const QByteArray appId = Logging::applicationId();
+ if (!appId.isEmpty()) {
+ out.append(" | ");
+
+ color(out, Red + qHash(appId) % 7);
+ out.append(appId);
+ color(out, Off);
+
+ outLength += (3 + appId.length()); // 3 == strlen(" | ")
+ }
+
+ out.append("] ");
+ out.append(msg);
+
+ if (filenameLength && linenumberLength) {
+ int spacing = 1;
+ if (consoleWidth > 0) {
+ // right-align the location mark
+ spacing = consoleWidth - outLength - linenumberLength - filenameLength - 4; // 4 == strlen(" [:]")
+
+ // keep the location mark right-aligned, even if the message contains newlines
+ int lastNewline = msg.lastIndexOf('\n');
+ if (lastNewline >= 0)
+ spacing += (outLength - msg.length() + lastNewline + 1);
+
+ // keep the location mark right-aligned, even if the message is longer than the window width
+ while (spacing < 0)
+ spacing += consoleWidth;
+ }
+#if QT_VERSION < QT_VERSION_CHECK(5,7,0)
+ // efficiently appending spaces without allocating is hard in Qt 5.6
+ static const char spacingStr[] = " ";
+ Q_STATIC_ASSERT(sizeof(spacingStr) == 80);
+ while (spacing > 0) {
+ int spacingLen = qMin(spacing, int(sizeof(spacingStr)) - 1);
+ out.append(spacingStr, spacingLen);
+ spacing -= spacingLen;
+ }
+#else
+ out.append(spacing, ' ');
+#endif
+ out.append('[');
+
+ color(out, Magenta);
+ out.append(filename, filenameLength);
+ color(out, Off);
+
+ out.append(':');
+
+ color(out, BrightFlag | Magenta);
+ out.append(linenumber, linenumberLength);
+ color(out, Off);
+
+ out.append("]\n");
+ } else {
+ out.append('\n');
+ }
+
+ if (consoleWidth <= 0) {
+#if defined(Q_OS_WIN)
+ // do not use QMutex to avoid possible recursions
+ static CRITICAL_SECTION cs;
+ static bool csInitialized = false;
+ if (!csInitialized)
+ InitializeCriticalSection(&cs);
+
+ EnterCriticalSection(&cs);
+ OutputDebugStringA(out.constData());
+ LeaveCriticalSection(&cs);
+ return;
+
+#elif defined(Q_OS_ANDROID)
+ android_LogPriority pri = ANDROID_LOG_DEBUG;
+ switch (msgType) {
+ default:
+ case QtDebugMsg: pri = ANDROID_LOG_DEBUG; break;
+ case QtWarningMsg: pri = ANDROID_LOG_WARN; break;
+ case QtCriticalMsg: pri = ANDROID_LOG_ERROR; break;
+ case QtFatalMsg: pri = ANDROID_LOG_FATAL; break;
+ };
+
+ static QByteArray appName = QCoreApplication::applicationName().toLocal8Bit();
+
+ __android_log_print(pri, appName.constData(), out.constData());
+ return;
+#endif
+ }
+ fputs(out.constData(), stderr);
+}
+
+void Logging::initialize()
+{
+ auto messageHandler = [](QtMsgType msgType, const QMessageLogContext &context, const QString &message) {
+#if defined(QT_GENIVIEXTRAS_LIB)
+ if (s_dltEnabled)
+ QDltRegistration::messageHandler(msgType, context, message);
+#endif
+ if (Q_UNLIKELY(s_useDefaultQtHandler))
+ s_defaultQtHandler(msgType, context, message);
+ else
+ colorLogToStderr(msgType, context, message);
+ };
+
+ s_useDefaultQtHandler = qEnvironmentVariableIsSet("QT_MESSAGE_PATTERN");
+ s_defaultQtHandler = qInstallMessageHandler(messageHandler);
+}
+
+QByteArray Logging::applicationId()
+{
+ return s_applicationId;
+}
+
+void Logging::setApplicationId(const QByteArray &appId)
+{
+ s_applicationId = appId;
+}
+
+bool Logging::isDltEnabled()
+{
+ return s_dltEnabled;
+}
+
+void Logging::setDltEnabled(bool enabled)
+{
+ s_dltEnabled = enabled;
+}
+
+void Logging::registerUnregisteredDltContexts()
+{
+ if (!s_dltEnabled)
+ return;
+#ifdef AM_GENIVIEXTRAS_LAZY_INIT
+ globalDltRegistration()->registerUnregisteredContexts();
+#endif
+}
+
+void Logging::setDltApplicationId(const QByteArray &dltAppId, const QByteArray &dltAppDescription)
+{
+ if (!s_dltEnabled)
+ return;
+#if defined(QT_GENIVIEXTRAS_LIB)
+ globalDltRegistration()->registerApplication(dltAppId, dltAppDescription);
+#else
+ Q_UNUSED(dltAppId)
+ Q_UNUSED(dltAppDescription)
+#endif
+}
+
+void am_trace(QDebug)
+{ }
+
+QT_END_NAMESPACE_AM
diff --git a/src/common-lib/logging.h b/src/common-lib/logging.h
new file mode 100644
index 00000000..0b8a61cb
--- /dev/null
+++ b/src/common-lib/logging.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+#pragma once
+
+#include "global.h"
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE_AM
+
+Q_DECLARE_LOGGING_CATEGORY(LogSystem)
+Q_DECLARE_LOGGING_CATEGORY(LogInstaller)
+Q_DECLARE_LOGGING_CATEGORY(LogWayland)
+Q_DECLARE_LOGGING_CATEGORY(LogQml)
+Q_DECLARE_LOGGING_CATEGORY(LogNotifications)
+Q_DECLARE_LOGGING_CATEGORY(LogQmlRuntime)
+Q_DECLARE_LOGGING_CATEGORY(LogQmlIpc)
+
+class Logging
+{
+public:
+ static void initialize();
+
+ static QByteArray applicationId();
+ static void setApplicationId(const QByteArray &appId);
+
+ // DLT functionality
+ static bool isDltEnabled();
+ static void setDltEnabled(bool enabled);
+
+ static void registerUnregisteredDltContexts();
+ static void setDltApplicationId(const QByteArray &dltAppId, const QByteArray &dltAppDescription);
+
+private:
+ static bool s_dltEnabled;
+ static bool s_useDefaultQtHandler;
+ static QtMessageHandler s_defaultQtHandler;
+ static QByteArray s_applicationId;
+};
+
+
+void am_trace(QDebug);
+template <typename T, typename... TRest> void am_trace(QDebug dbg, T t, TRest... trest)
+{ dbg << t; am_trace(dbg, trest...); }
+
+#define AM_TRACE(category, ...) \
+ for (bool qt_category_enabled = category().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) { \
+ QT_PREPEND_NAMESPACE_AM(am_trace(QMessageLogger(__FILE__, __LINE__, __FUNCTION__, category().categoryName()).debug(), "TRACE", __FUNCTION__, __VA_ARGS__)); \
+ }
+
+QT_END_NAMESPACE_AM
diff --git a/src/common-lib/processtitle.cpp b/src/common-lib/processtitle.cpp
index 0b799037..61a07f2a 100644
--- a/src/common-lib/processtitle.cpp
+++ b/src/common-lib/processtitle.cpp
@@ -48,6 +48,8 @@ const char *ProcessTitle::title() { return nullptr; }
QT_END_NAMESPACE_AM
#else
+#include "logging.h"
+
#include <QVarLengthArray>
#include <QByteArray>
diff --git a/src/common-lib/processtitle.h b/src/common-lib/processtitle.h
index 67a687af..e4ad2527 100644
--- a/src/common-lib/processtitle.h
+++ b/src/common-lib/processtitle.h
@@ -41,7 +41,6 @@
#pragma once
-#include <stdlib.h>
#include <QtAppManCommon/global.h>
QT_BEGIN_NAMESPACE_AM
diff --git a/src/common-lib/unixsignalhandler.cpp b/src/common-lib/unixsignalhandler.cpp
index ba4b2c8f..997a8df2 100644
--- a/src/common-lib/unixsignalhandler.cpp
+++ b/src/common-lib/unixsignalhandler.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "unixsignalhandler.h"
+#include "logging.h"
#include <QSocketNotifier>
#include <QCoreApplication>
diff --git a/src/common-lib/unixsignalhandler.h b/src/common-lib/unixsignalhandler.h
index fa4d79e0..d126231a 100644
--- a/src/common-lib/unixsignalhandler.h
+++ b/src/common-lib/unixsignalhandler.h
@@ -41,8 +41,9 @@
#pragma once
-#include <QAtomicInteger>
#include <QtAppManCommon/global.h>
+#include <QObject>
+#include <QAtomicInteger>
#include <initializer_list>
#include <list>
#include <vector>
diff --git a/src/common-lib/utilities.cpp b/src/common-lib/utilities.cpp
index 34e50d18..fe1cf827 100644
--- a/src/common-lib/utilities.cpp
+++ b/src/common-lib/utilities.cpp
@@ -48,11 +48,11 @@
#include <QFileInfo>
#include <QFile>
#include <QCoreApplication>
+#include <QNetworkInterface>
#include "utilities.h"
#include "exception.h"
#include "unixsignalhandler.h"
-#include "processtitle.h"
#include <errno.h>
@@ -91,6 +91,26 @@ extern char **environ;
QT_BEGIN_NAMESPACE_AM
+QString hardwareId()
+{
+#if defined(AM_HARDWARE_ID)
+ return QString::fromLocal8Bit(AM_HARDWARE_ID);
+#elif defined(AM_HARDWARE_ID_FROM_FILE)
+ QFile f(QString::fromLocal8Bit(AM_HARDWARE_ID_FROM_FILE));
+ if (f.open(QFile::ReadOnly))
+ return f.readAll().trimmed();
+#else
+ foreach (const QNetworkInterface &iface, QNetworkInterface::allInterfaces()) {
+ if (iface.isValid() && (iface.flags() & QNetworkInterface::IsUp)
+ && !(iface.flags() & (QNetworkInterface::IsPointToPoint | QNetworkInterface::IsLoopBack))
+ && !iface.hardwareAddress().isEmpty()) {
+ return iface.hardwareAddress().replace(qL1C(':'), qL1S("-"));
+ }
+ }
+#endif
+ return QString();
+}
+
bool ensureCorrectLocale()
{
// We need to make sure we are running in a Unicode locale, since we are
@@ -475,279 +495,6 @@ QString findOnSDCard(const QString &file)
#endif
-#if defined(Q_OS_LINUX)
-
-QT_END_NAMESPACE_AM
-
-#include <cxxabi.h>
-#include <execinfo.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <inttypes.h>
-
-#if defined(AM_USE_LIBBACKTRACE)
-# include <libbacktrace/backtrace.h>
-# include <libbacktrace/backtrace-supported.h>
-#endif
-QT_BEGIN_NAMESPACE_AM
-
-static bool printBacktrace;
-static bool useAnsiColor;
-static bool dumpCore;
-static int waitForGdbAttach;
-
-static char *demangleBuffer;
-static size_t demangleBufferSize;
-
-
-static void crashHandler(const char *why, int stackFramesToIgnore) __attribute__((noreturn));
-
-static void crashHandler(const char *why, int stackFramesToIgnore)
-{
- pid_t pid = getpid();
- char who[256];
- int whoLen = readlink("/proc/self/exe", who, sizeof(who) -1);
- who[qMax(0, whoLen)] = '\0';
- const char *title = ProcessTitle::title();
-
- fprintf(stderr, "\n*** process %s (%d) crashed ***\n\n > why: %s\n", title ? title : who, pid, why);
-
- if (printBacktrace) {
-#if defined(AM_USE_LIBBACKTRACE) && defined(BACKTRACE_SUPPORTED)
- struct btData {
- backtrace_state *state;
- int level;
- };
-
- static auto printBacktraceLine = [](int level, const char *symbol, uintptr_t offset, const char *file = nullptr, int line = -1)
- {
- if (useAnsiColor) {
- fprintf(stderr, " %3d: \x1b[1m%s\x1b[0m [\x1b[36m%" PRIxPTR "\x1b[0m]", level, symbol, offset);
- if (file)
- fprintf(stderr, " in \x1b[35m%s\x1b[0m:\x1b[35;1m%d\x1b[0m", file, line);
- } else {
- fprintf(stderr, " %3d: %s [%" PRIxPTR "]", level, symbol, offset);
- if (file)
- fprintf(stderr, " in %s:%d", file, line);
- }
- fputs("\n", stderr);
- };
-
- static auto errorCallback = [](void *data, const char *msg, int errnum) {
- if (useAnsiColor)
- fprintf(stderr, " %3d: \x1b[31;1mERROR: \x1b[0;1m%s (%d)\x1b[0m\n", static_cast<btData *>(data)->level, msg, errnum);
- else
- fprintf(stderr, " %3d: ERROR: %s (%d)\n", static_cast<btData *>(data)->level, msg, errnum);
- };
-
- static auto syminfoCallback = [](void *data, uintptr_t pc, const char *symname, uintptr_t symval, uintptr_t symsize) {
- Q_UNUSED(symval)
- Q_UNUSED(symsize)
-
- int level = static_cast<btData *>(data)->level;
- if (symname) {
- int status;
- abi::__cxa_demangle(symname, demangleBuffer, &demangleBufferSize, &status);
-
- if (status == 0 && *demangleBuffer)
- printBacktraceLine(level, demangleBuffer, pc);
- else
- printBacktraceLine(level, symname, pc);
- } else {
- printBacktraceLine(level, nullptr, pc);
- }
- };
-
- static auto fullCallback = [](void *data, uintptr_t pc, const char *filename, int lineno, const char *function) -> int {
- if (function) {
- int status;
- abi::__cxa_demangle(function, demangleBuffer, &demangleBufferSize, &status);
-
- printBacktraceLine(static_cast<btData *>(data)->level,
- (status == 0 && *demangleBuffer) ? demangleBuffer : function,
- pc, filename ? filename : "<unknown>", lineno);
- } else {
- backtrace_syminfo (static_cast<btData *>(data)->state, pc, syminfoCallback, errorCallback, data);
- }
- return 0;
- };
-
- static auto simpleCallback = [](void *data, uintptr_t pc) -> int {
- backtrace_pcinfo(static_cast<btData *>(data)->state, pc, fullCallback, errorCallback, data);
- static_cast<btData *>(data)->level++;
- return 0;
- };
-
- struct backtrace_state *state = backtrace_create_state(nullptr, BACKTRACE_SUPPORTS_THREADS,
- errorCallback, nullptr);
-
- fprintf(stderr, "\n > backtrace:\n");
- btData data = { state, 0 };
- //backtrace_print(state, stackFramesToIgnore, stderr);
- backtrace_simple(state, stackFramesToIgnore, simpleCallback, errorCallback, &data);
-#else
- Q_UNUSED(stackFramesToIgnore);
- void *addrArray[1024];
- int addrCount = backtrace(addrArray, sizeof(addrArray) / sizeof(*addrArray));
-
- if (!addrCount) {
- fprintf(stderr, " > no backtrace available\n");
- } else {
- char **symbols = backtrace_symbols(addrArray, addrCount);
- //backtrace_symbols_fd(addrArray, addrCount, 2);
-
- if (!symbols) {
- fprintf(stderr, " > no symbol names available\n");
- } else {
- fprintf(stderr, " > backtrace:\n");
- for (int i = 1; i < addrCount; ++i) {
- char *function = nullptr;
- char *offset = nullptr;
- char *end = nullptr;
-
- for (char *ptr = symbols[i]; ptr && *ptr; ++ptr) {
- if (!function && *ptr == '(')
- function = ptr + 1;
- else if (function && !offset && *ptr == '+')
- offset = ptr;
- else if (function && !end && *ptr == ')')
- end = ptr;
- }
-
- if (function && offset && end && (function != offset)) {
- *offset = 0;
- *end = 0;
-
- int status;
- abi::__cxa_demangle(function, demangleBuffer, &demangleBufferSize, &status);
-
- if (status == 0 && *demangleBuffer) {
- fprintf(stderr, " %3d: %s [+%s]\n", i, demangleBuffer, offset + 1);
- } else {
- fprintf(stderr, " %3d: %s [+%s]\n", i, function, offset + 1);
- }
- } else {
- fprintf(stderr, " %3d: %s\n", i, symbols[i]);
- }
- }
- fprintf(stderr, "\n");
- }
- }
-#endif
- }
- if (waitForGdbAttach > 0) {
- fprintf(stderr, "\n > the process will be suspended for %d seconds and you can attach a debugger to it via\n\n gdb -p %d\n",
- waitForGdbAttach, pid);
- static jmp_buf jmpenv;
- signal(SIGALRM, [](int) {
- longjmp(jmpenv, 1);
- });
- if (!setjmp(jmpenv)) {
- alarm(waitForGdbAttach);
-
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, SIGALRM);
- sigsuspend(&mask);
- } else {
- fprintf(stderr, "\n > no gdb attached\n");
- }
- }
- if (dumpCore) {
- fprintf(stderr, "\n > the process will be aborted (core dump)\n\n");
- UnixSignalHandler::instance()->resetToDefault({ SIGFPE, SIGSEGV, SIGILL, SIGBUS, SIGPIPE, SIGABRT });
- abort();
- }
- _Exit(-1);
-}
-
-// this will make it run before all other static constructor functions
-static void initBacktrace() __attribute__((constructor(1000)));
-
-static void initBacktrace()
-{
- // This can catch and pretty-print all of the following:
-
- // SIGFPE
- // volatile int i = 2;
- // int zero = 0;
- // i /= zero;
-
- // SIGSEGV
- // *((int *)1) = 1;
-
- // uncaught arbitrary exception
- // throw 42;
-
- // uncaught std::exception derived exception (prints what())
- // throw std::logic_error("test output");
-
- printBacktrace = true;
- dumpCore = true;
- waitForGdbAttach = false;
-
- getOutputInformation(&useAnsiColor, nullptr, nullptr);
-
- demangleBufferSize = 512;
- demangleBuffer = (char *) malloc(demangleBufferSize);
-
- UnixSignalHandler::instance()->install(UnixSignalHandler::RawSignalHandler,
- { SIGFPE, SIGSEGV, SIGILL, SIGBUS, SIGPIPE, SIGABRT },
- [](int sig) {
- UnixSignalHandler::instance()->resetToDefault(sig);
- static char buffer[256];
- snprintf(buffer, sizeof(buffer), "uncaught signal %d (%s)", sig, UnixSignalHandler::signalName(sig));
- // 6 means to remove 6 stack frames: this way the backtrace starts at the point where
- // the signal reception interrupted the normal program flow
- crashHandler(buffer, 6);
- });
-
- std::set_terminate([]() {
- static char buffer [1024];
-
- auto type = abi::__cxa_current_exception_type();
- if (!type) {
- // 3 means to remove 3 stack frames: this way the backtrace starts at std::terminate
- crashHandler("terminate was called although no exception was thrown", 3);
- }
-
- const char *typeName = type->name();
- if (typeName) {
- int status;
- abi::__cxa_demangle(typeName, demangleBuffer, &demangleBufferSize, &status);
- if (status == 0 && *demangleBuffer) {
- typeName = demangleBuffer;
- }
- }
- try {
- throw;
- } catch (const std::exception &exc) {
- snprintf(buffer, sizeof(buffer), "uncaught exception of type %s (%s)", typeName, exc.what());
- } catch (...) {
- snprintf(buffer, sizeof(buffer), "uncaught exception of type %s", typeName);
- }
-
- // 4 means to remove 4 stack frames: this way the backtrace starts at std::terminate
- crashHandler(buffer, 4);
- });
-}
-
-void setCrashActionConfiguration(const QVariantMap &config)
-{
- printBacktrace = config.value(qSL("printBacktrace"), printBacktrace).toBool();
- waitForGdbAttach = config.value(qSL("waitForGdbAttach"), waitForGdbAttach).toInt();
- dumpCore = config.value(qSL("dumpCore"), dumpCore).toBool();
-}
-
-#else // Q_OS_LINUX
-
-void setCrashActionConfiguration(const QVariantMap &config)
-{
- Q_UNUSED(config)
-}
-
-#endif // !Q_OS_LINUX
-
void getOutputInformation(bool *ansiColorSupport, bool *runningInCreator, int *consoleWidth)
{
static bool ansiColorSupportDetected = false;
diff --git a/src/common-lib/utilities.h b/src/common-lib/utilities.h
index bac006ee..2a280167 100644
--- a/src/common-lib/utilities.h
+++ b/src/common-lib/utilities.h
@@ -62,6 +62,8 @@
QT_BEGIN_NAMESPACE_AM
+QString hardwareId();
+
bool ensureCorrectLocale();
bool checkCorrectLocale();
@@ -182,8 +184,6 @@ private:
QString findOnSDCard(const QString &file);
#endif
-void setCrashActionConfiguration(const QVariantMap &config);
-
void getOutputInformation(bool *ansiColorSupport, bool *runningInCreator, int *consoleWidth);
qint64 getParentPid(qint64 pid);
diff --git a/src/installer-lib/applicationinstaller.cpp b/src/installer-lib/applicationinstaller.cpp
index f6bc9a71..c3ef7416 100644
--- a/src/installer-lib/applicationinstaller.cpp
+++ b/src/installer-lib/applicationinstaller.cpp
@@ -43,6 +43,7 @@
#include <QDir>
#include <QUuid>
+#include "logging.h"
#include "application.h"
#include "applicationinstaller.h"
#include "applicationinstaller_p.h"
diff --git a/src/installer-lib/deinstallationtask.cpp b/src/installer-lib/deinstallationtask.cpp
index 6dc917dc..e4a429cf 100644
--- a/src/installer-lib/deinstallationtask.cpp
+++ b/src/installer-lib/deinstallationtask.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include "logging.h"
#include "applicationinstaller.h"
#include "applicationinstaller_p.h"
#include "applicationmanager.h"
diff --git a/src/installer-lib/installationtask.cpp b/src/installer-lib/installationtask.cpp
index 008da8e0..2adf827d 100644
--- a/src/installer-lib/installationtask.cpp
+++ b/src/installer-lib/installationtask.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include "logging.h"
#include "applicationinstaller_p.h"
#include "application.h"
#include "packageextractor.h"
diff --git a/src/installer-lib/scopeutilities.cpp b/src/installer-lib/scopeutilities.cpp
index 9e8012ea..312bfb3b 100644
--- a/src/installer-lib/scopeutilities.cpp
+++ b/src/installer-lib/scopeutilities.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include "logging.h"
#include "scopeutilities.h"
#include "applicationinstaller_p.h"
#include "utilities.h"
diff --git a/src/installer-lib/sudo.cpp b/src/installer-lib/sudo.cpp
index cec70692..34b093da 100644
--- a/src/installer-lib/sudo.cpp
+++ b/src/installer-lib/sudo.cpp
@@ -48,6 +48,7 @@
#include <qplatformdefs.h>
#include <QDataStream>
+#include "logging.h"
#include "sudo.h"
#include "utilities.h"
#include "exception.h"
diff --git a/src/launcher-lib/applicationmanagerwindow.cpp b/src/launcher-lib/applicationmanagerwindow.cpp
index 98380517..4de5aca6 100644
--- a/src/launcher-lib/applicationmanagerwindow.cpp
+++ b/src/launcher-lib/applicationmanagerwindow.cpp
@@ -44,6 +44,7 @@
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformwindow.h>
+#include "logging.h"
#include "applicationmanagerwindow_p.h"
QT_BEGIN_NAMESPACE_AM
diff --git a/src/launcher-lib/qmlapplicationinterfaceextension.cpp b/src/launcher-lib/qmlapplicationinterfaceextension.cpp
index e853acc0..86dad19d 100644
--- a/src/launcher-lib/qmlapplicationinterfaceextension.cpp
+++ b/src/launcher-lib/qmlapplicationinterfaceextension.cpp
@@ -41,6 +41,7 @@
#include <QDBusInterface>
+#include "logging.h"
#include "qmlapplicationinterfaceextension.h"
#include "qmlapplicationinterface.h"
#include "ipcwrapperobject.h"
diff --git a/src/launchers/qml/main.cpp b/src/launchers/qml/main.cpp
index fa4e0ef2..0f8412bb 100644
--- a/src/launchers/qml/main.cpp
+++ b/src/launchers/qml/main.cpp
@@ -79,7 +79,9 @@
#include "notification.h"
#include "qtyaml.h"
#include "global.h"
+#include "logging.h"
#include "utilities.h"
+#include "crashhandler.h"
#include "yamlapplicationscanner.h"
#include "application.h"
#include "startupinterface.h"
@@ -174,7 +176,7 @@ int main(int argc, char *argv[])
StartupTimer::instance()->checkpoint("entered main");
if (qEnvironmentVariableIsSet("AM_NO_DLT_LOGGING"))
- dltLoggingEnabled = false;
+ Logging::setDltEnabled(false);
// The common-lib is already registering the DLT Application for the application manager.
// As the appID needs to be unique within the system, we cannot use the same appID and
@@ -182,10 +184,10 @@ int main(int argc, char *argv[])
// As we don't know the app-id yet, we are registering a place holder so we are able to see
// something in the dlt logs if general errors occur.
- changeDLTApplication("PCLQ", "Pelagicore Application-Manager Launcher QML");
+ Logging::setDltApplicationId("PCLQ", "Pelagicore Application-Manager Launcher QML");
+ Logging::setApplicationId("qml-launcher");
+ Logging::initialize();
- colorLogApplicationId = "qml-launcher";
- installMessageHandlers();
QLoggingCategory::setFilterRules(QString::fromUtf8(qgetenv("AM_LOGGING_RULES")));
#if defined(AM_HEADLESS)
@@ -276,7 +278,7 @@ Controller::Controller(QCoreApplication *a, const QString &directLoad)
if (docs.size() == 1)
m_configuration = docs.first().toMap();
- setCrashActionConfiguration(m_configuration.value(qSL("crashAction")).toMap());
+ CrashHandler::setCrashActionConfiguration(m_configuration.value(qSL("crashAction")).toMap());
const QString baseDir = QString::fromLocal8Bit(qgetenv("AM_BASE_DIR") + "/");
@@ -364,8 +366,8 @@ void Controller::startApplication(const QString &baseDir, const QString &qmlFile
//Change the DLT Application description, to easily identify the application on the DLT logs.
char dltAppId[5];
qsnprintf(dltAppId, 5, "A%03d", application.value("uniqueNumber").toInt());
- changeDLTApplication(dltAppId, QString("Application-Manager App: %1").arg(applicationId).toLocal8Bit());
- registerUnregisteredDLTContexts();
+ Logging::setDltApplicationId(dltAppId, QByteArray("Application-Manager App: ") + applicationId.toLocal8Bit());
+ Logging::registerUnregisteredDltContexts();
// Dress up the ps output to make it easier to correlate all the launcher processes
{
@@ -396,7 +398,7 @@ void Controller::startApplication(const QString &baseDir, const QString &qmlFile
applicationId.append(qL1C('.'));
}
applicationId.append(sl.last());
- colorLogApplicationId = applicationId.toLocal8Bit();
+ Logging::setApplicationId(applicationId.toLocal8Bit());
} else {
qCCritical(LogQmlRuntime) << "did not receive an application id";
QCoreApplication::exit(2);
diff --git a/src/manager-lib/abstractcontainer.h b/src/manager-lib/abstractcontainer.h
index feac1f82..d97be936 100644
--- a/src/manager-lib/abstractcontainer.h
+++ b/src/manager-lib/abstractcontainer.h
@@ -44,7 +44,8 @@
#include <QObject>
#include <QString>
#include <QProcess>
-#include <QDir>
+#include <QVariantMap>
+#include <QVector>
#include <QtAppManCommon/global.h>
diff --git a/src/manager-lib/abstractruntime.cpp b/src/manager-lib/abstractruntime.cpp
index 6eb95b34..5a6137ad 100644
--- a/src/manager-lib/abstractruntime.cpp
+++ b/src/manager-lib/abstractruntime.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "global.h"
+#include "logging.h"
#include "application.h"
#include "abstractruntime.h"
#include "abstractcontainer.h"
diff --git a/src/manager-lib/abstractruntime.h b/src/manager-lib/abstractruntime.h
index 8812f608..2d37bc4c 100644
--- a/src/manager-lib/abstractruntime.h
+++ b/src/manager-lib/abstractruntime.h
@@ -45,6 +45,7 @@
#include <QString>
#include <QProcess>
#include <QPointer>
+#include <QVariantMap>
#include <QtAppManCommon/global.h>
diff --git a/src/manager-lib/applicationipcinterface.cpp b/src/manager-lib/applicationipcinterface.cpp
index 3c39b88a..98a7db35 100644
--- a/src/manager-lib/applicationipcinterface.cpp
+++ b/src/manager-lib/applicationipcinterface.cpp
@@ -54,6 +54,7 @@
#include <QDebug>
+#include "logging.h"
#include "application.h"
#include "utilities.h"
#include "dbus-utilities.h"
diff --git a/src/manager-lib/applicationipcmanager.cpp b/src/manager-lib/applicationipcmanager.cpp
index 59ec1a02..1b681a74 100644
--- a/src/manager-lib/applicationipcmanager.cpp
+++ b/src/manager-lib/applicationipcmanager.cpp
@@ -44,6 +44,7 @@
#include "applicationipcinterface_p.h"
#include "qml-utilities.h"
#include "global.h"
+#include "logging.h"
/*!
diff --git a/src/manager-lib/applicationmanager.cpp b/src/manager-lib/applicationmanager.cpp
index 93e09f0a..4e8dfc12 100644
--- a/src/manager-lib/applicationmanager.cpp
+++ b/src/manager-lib/applicationmanager.cpp
@@ -53,7 +53,7 @@
#include <qplatformdefs.h>
#include "global.h"
-
+#include "logging.h"
#include "applicationdatabase.h"
#include "applicationmanager.h"
#include "applicationmanager_p.h"
diff --git a/src/manager-lib/containerfactory.cpp b/src/manager-lib/containerfactory.cpp
index 8b8eeb11..08e55a35 100644
--- a/src/manager-lib/containerfactory.cpp
+++ b/src/manager-lib/containerfactory.cpp
@@ -43,6 +43,7 @@
#include <QCoreApplication>
#include <QThreadPool>
+#include "logging.h"
#include "application.h"
#include "abstractruntime.h"
#include "abstractcontainer.h"
diff --git a/src/manager-lib/containerfactory.h b/src/manager-lib/containerfactory.h
index 58da8e01..19287646 100644
--- a/src/manager-lib/containerfactory.h
+++ b/src/manager-lib/containerfactory.h
@@ -43,7 +43,7 @@
#include <QMap>
#include <QObject>
-
+#include <QVector>
#include <QtAppManCommon/global.h>
QT_BEGIN_NAMESPACE_AM
diff --git a/src/manager-lib/fakeapplicationmanagerwindow.cpp b/src/manager-lib/fakeapplicationmanagerwindow.cpp
index ae5de0fd..b328d951 100644
--- a/src/manager-lib/fakeapplicationmanagerwindow.cpp
+++ b/src/manager-lib/fakeapplicationmanagerwindow.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include "logging.h"
#include "fakeapplicationmanagerwindow.h"
#include "qmlinprocessruntime.h"
#include <QSGSimpleRectNode>
diff --git a/src/manager-lib/memorymonitor.cpp b/src/manager-lib/memorymonitor.cpp
index 2d8c9f7c..712e6f94 100644
--- a/src/manager-lib/memorymonitor.cpp
+++ b/src/manager-lib/memorymonitor.cpp
@@ -43,6 +43,7 @@
#include <QFile>
#include <QVector>
#include "global.h"
+#include "logging.h"
#include "memorymonitor.h"
#if defined(Q_OS_OSX)
diff --git a/src/manager-lib/nativeruntime.cpp b/src/manager-lib/nativeruntime.cpp
index 87782fd6..7823a478 100644
--- a/src/manager-lib/nativeruntime.cpp
+++ b/src/manager-lib/nativeruntime.cpp
@@ -48,6 +48,7 @@
#include <QUuid>
#include "global.h"
+#include "logging.h"
#include "application.h"
#include "applicationmanager.h"
#include "nativeruntime.h"
@@ -200,7 +201,7 @@ bool NativeRuntime::start()
if (!m_needsLauncher && !m_isQuickLauncher)
env.insert(qSL("AM_RUNTIME_SYSTEM_PROPERTIES"), QString::fromUtf8(QtYaml::yamlFromVariantDocuments({ systemProperties() })));
env.insert(qSL("AM_BASE_DIR"), QDir::currentPath());
- if (!dltLoggingEnabled)
+ if (Logging::isDltEnabled())
env.insert(qSL("AM_NO_DLT_LOGGING"), qSL("1"));
for (QMapIterator<QString, QVariant> it(configuration().value(qSL("environmentVariables")).toMap()); it.hasNext(); ) {
diff --git a/src/manager-lib/nativeruntime.h b/src/manager-lib/nativeruntime.h
index da017cdf..f3dd515f 100644
--- a/src/manager-lib/nativeruntime.h
+++ b/src/manager-lib/nativeruntime.h
@@ -47,6 +47,7 @@
#include <QtPlugin>
#include <QProcess>
+#include <QVector>
#include <QtAppManManager/abstractruntime.h>
#include <QtAppManManager/abstractcontainer.h>
diff --git a/src/manager-lib/notificationmanager.cpp b/src/manager-lib/notificationmanager.cpp
index bf891aeb..7689aa0c 100644
--- a/src/manager-lib/notificationmanager.cpp
+++ b/src/manager-lib/notificationmanager.cpp
@@ -44,7 +44,7 @@
#include <QTimer>
#include "global.h"
-
+#include "logging.h"
#include "application.h"
#include "applicationmanager.h"
#include "notificationmanager.h"
diff --git a/src/manager-lib/processcontainer.cpp b/src/manager-lib/processcontainer.cpp
index 3ff1d805..42a64dc8 100644
--- a/src/manager-lib/processcontainer.cpp
+++ b/src/manager-lib/processcontainer.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "global.h"
+#include "logging.h"
#include "containerfactory.h"
#include "application.h"
#include "processcontainer.h"
diff --git a/src/manager-lib/processmonitor.cpp b/src/manager-lib/processmonitor.cpp
index 38fc40ec..71b97802 100644
--- a/src/manager-lib/processmonitor.cpp
+++ b/src/manager-lib/processmonitor.cpp
@@ -41,6 +41,7 @@
#include <QDebug>
#include <QCoreApplication>
+#include "logging.h"
#include "processmonitor.h"
#include "memorymonitor.h"
#include "application.h"
diff --git a/src/manager-lib/qmlinprocessapplicationinterface.cpp b/src/manager-lib/qmlinprocessapplicationinterface.cpp
index b4b07daa..6b4bb4a2 100644
--- a/src/manager-lib/qmlinprocessapplicationinterface.cpp
+++ b/src/manager-lib/qmlinprocessapplicationinterface.cpp
@@ -42,6 +42,7 @@
#include <QQmlEngine>
#include <QQmlExpression>
+#include "logging.h"
#include "qmlinprocessapplicationinterface.h"
#include "qmlinprocessruntime.h"
#include "application.h"
diff --git a/src/manager-lib/qmlinprocessruntime.cpp b/src/manager-lib/qmlinprocessruntime.cpp
index ca650e27..2fb02bbb 100644
--- a/src/manager-lib/qmlinprocessruntime.cpp
+++ b/src/manager-lib/qmlinprocessruntime.cpp
@@ -51,6 +51,7 @@
# include "fakeapplicationmanagerwindow.h"
#endif
+#include "logging.h"
#include "application.h"
#include "qmlinprocessruntime.h"
#include "qmlinprocessapplicationinterface.h"
diff --git a/src/manager-lib/quicklauncher.cpp b/src/manager-lib/quicklauncher.cpp
index 5fbfc5ae..cd719ab5 100644
--- a/src/manager-lib/quicklauncher.cpp
+++ b/src/manager-lib/quicklauncher.cpp
@@ -42,6 +42,7 @@
#include <QCoreApplication>
#include <QTimer>
+#include "logging.h"
#include "abstractcontainer.h"
#include "abstractruntime.h"
#include "containerfactory.h"
diff --git a/src/manager-lib/runtimefactory.cpp b/src/manager-lib/runtimefactory.cpp
index 89d77b7e..0fd009cb 100644
--- a/src/manager-lib/runtimefactory.cpp
+++ b/src/manager-lib/runtimefactory.cpp
@@ -42,6 +42,7 @@
#include <QScopedPointer>
#include <QCoreApplication>
+#include "logging.h"
#include "application.h"
#include "abstractruntime.h"
#include "abstractcontainer.h"
diff --git a/src/manager-lib/systemmonitor.cpp b/src/manager-lib/systemmonitor.cpp
index 9b6d6704..e737243b 100644
--- a/src/manager-lib/systemmonitor.cpp
+++ b/src/manager-lib/systemmonitor.cpp
@@ -48,15 +48,14 @@
#include <vector>
#include <QGuiApplication>
+#include "global.h"
+#include "logging.h"
+#include "qml-utilities.h"
#include "applicationmanager.h"
#include "systemmonitor.h"
#include "systemmonitor_p.h"
#include "processmonitor.h"
-#include "global.h"
-
-#include "qml-utilities.h"
-
/*!
\qmltype SystemMonitor
diff --git a/src/manager-lib/systemmonitor_p.cpp b/src/manager-lib/systemmonitor_p.cpp
index 60685fde..49a73af5 100644
--- a/src/manager-lib/systemmonitor_p.cpp
+++ b/src/manager-lib/systemmonitor_p.cpp
@@ -43,6 +43,7 @@
#include "systemmonitor_p.h"
#include "global.h"
+#include "logging.h"
QT_BEGIN_NAMESPACE_AM
diff --git a/src/manager/configuration.cpp b/src/manager/configuration.cpp
index e13eab1c..ffb8d092 100644
--- a/src/manager/configuration.cpp
+++ b/src/manager/configuration.cpp
@@ -47,6 +47,7 @@
#include <functional>
#include "global.h"
+#include "logging.h"
#include "qtyaml.h"
#include "utilities.h"
#include "configuration.h"
diff --git a/src/manager/main.cpp b/src/manager/main.cpp
index 956795b8..7618b6e1 100644
--- a/src/manager/main.cpp
+++ b/src/manager/main.cpp
@@ -83,7 +83,7 @@
#endif
#include "global.h"
-
+#include "logging.h"
#include "application.h"
#include "applicationmanager.h"
#include "applicationdatabase.h"
@@ -120,6 +120,7 @@
#include "configuration.h"
#include "utilities.h"
+#include "crashhandler.h"
#include "qmllogger.h"
#include "startuptimer.h"
#include "systemmonitor.h"
@@ -502,11 +503,11 @@ int main(int argc, char *argv[])
QCoreApplication::setApplicationVersion(qSL(AM_VERSION));
for (int i = 1; i < argc; ++i) {
if (strcmp("--no-dlt-logging", argv[i]) == 0) {
- dltLoggingEnabled = false;
+ Logging::setDltEnabled(false);
break;
}
}
- installMessageHandlers();
+ Logging::initialize();
QString error;
@@ -552,7 +553,7 @@ int main(int argc, char *argv[])
StartupTimer::instance()->checkpoint("after command line parse");
- setCrashActionConfiguration(configuration->managerCrashAction());
+ CrashHandler::setCrashActionConfiguration(configuration->managerCrashAction());
#if !defined(QT_NO_QML_DEBUGGER)
QQmlDebuggingEnabler *debuggingEnabler = nullptr;
@@ -584,7 +585,7 @@ int main(int argc, char *argv[])
// setting this for child processes //TODO: use a more generic IPC approach
qputenv("AM_LOGGING_RULES", loggingRules.join(qL1C('\n')).toUtf8());
- registerUnregisteredDLTContexts();
+ Logging::registerUnregisteredDltContexts();
StartupTimer::instance()->checkpoint("after logging setup");
diff --git a/src/manager/qmllogger.cpp b/src/manager/qmllogger.cpp
index bb4f275b..4c8a703b 100644
--- a/src/manager/qmllogger.cpp
+++ b/src/manager/qmllogger.cpp
@@ -43,6 +43,7 @@
#include "qmllogger.h"
#include "global.h"
+#include "logging.h"
QT_BEGIN_NAMESPACE_AM
diff --git a/src/tools/testrunner/testrunner.h b/src/tools/testrunner/testrunner.h
index 4e3a4fe4..9199bae8 100644
--- a/src/tools/testrunner/testrunner.h
+++ b/src/tools/testrunner/testrunner.h
@@ -44,6 +44,7 @@
#include <QtAppManCommon/global.h>
QT_FORWARD_DECLARE_CLASS(QQmlEngine)
+QT_FORWARD_DECLARE_CLASS(QStringList)
QT_BEGIN_NAMESPACE_AM
diff --git a/src/window-lib/waylandcompositor.cpp b/src/window-lib/waylandcompositor.cpp
index e16eca5c..10c47291 100644
--- a/src/window-lib/waylandcompositor.cpp
+++ b/src/window-lib/waylandcompositor.cpp
@@ -44,6 +44,7 @@
#include <QWaylandOutput>
#include "global.h"
+#include "logging.h"
#include "windowmanager.h"
#include "application.h"
#include "applicationmanager.h"
diff --git a/src/window-lib/waylandwindow.cpp b/src/window-lib/waylandwindow.cpp
index a54c40b1..4d7e7bed 100644
--- a/src/window-lib/waylandwindow.cpp
+++ b/src/window-lib/waylandwindow.cpp
@@ -42,6 +42,7 @@
#if defined(AM_MULTI_PROCESS)
#include "global.h"
+#include "logging.h"
#include "applicationmanager.h"
#include "application.h"
#include "windowmanager.h"
diff --git a/src/window-lib/windowmanager.cpp b/src/window-lib/windowmanager.cpp
index eabf95af..900326c0 100644
--- a/src/window-lib/windowmanager.cpp
+++ b/src/window-lib/windowmanager.cpp
@@ -57,6 +57,7 @@
#endif
#include "global.h"
+#include "logging.h"
#include "application.h"
#include "applicationmanager.h"
#include "abstractruntime.h"