// Copyright (C) 2021 The Qt Company Ltd. // Copyright (C) 2019 Luxoft Sweden AB // Copyright (C) 2018 Pelagicore AG // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \page debugging.html \ingroup qtappman \ingroup qtappman-highlights \title Logging and Debugging \brief The application manager installs its own message handler to format logging output neatly. \section1 Logging The application manager installs its own message handler to format logging output neatly. If the \l {Qt DLT Logging} {QtDltLogging} module is available, this message handler passes the output to GENIVI Diagnostic Log and Trace (DLT). \section2 Categories The application manager defines the following logging categories: \include logging.cpp am-logging-categories \section2 Environment Variables This is a (incomplete) list of environment variables that influence the logging output at runtime: \table \header \li Variable \li Description \row \li AM_NO_CUSTOM_LOGGING \li If set to \c 1, debug output is not redirected to DLT, colorized or nicely formatted. \row \li AM_NO_DLT_LOGGING \li If set to \c 1, debug output is not redirected to DLT. \row \li AM_STARTUP_TIMER \li If set to \c 1, a startup performance analysis is printed to the console. Anything other than \c 1 is interpreted as the name of a file to use, instead of the console. For more information, see StartupTimer. \row \li AM_FORCE_COLOR_OUTPUT \li Can be set to \c on to force color output to the console or to \c off to disable it. Any other value enables the default, auto-detection behavior. \row \li AM_TIMEOUT_FACTOR \li An integer factor that slows down all timed wait statements within the application manager. Useful if running in slow wrappers, such as Valgrind. The default value is \c 1. \row \li QT_MESSAGE_PATTERN \li Setting this variable has the same effect as described in \l{Warning and Debugging Messages}{Debugging Techniques} and overwrites the default application manager message handler. Parallel DLT logging is still supported, if available. \endtable \section1 Debugging \section2 Introduction When debugging the application manager, the System UI and applications are dependent on the mode in which the application manager runs: \list \li In \b single-process mode, you can start the \c appman binary using any debugging tool directly, for example, \c{gdb --args appman -c config.yaml}. Since everything runs in a single process, you can't debug applications separately. Instead, all applications started are loaded into \b{a single process}, so you can only debug the entire process at once; not each application independently. \li In \b multi-process mode, you have to distinguish between debugging the application manager itself or the System UI and debugging individual applications: The application manager and System UI can be debugged in the same way as for a single-process setup above. Debugging is a bit more tricky for applications, as they have to be started by the application manager. You can accomplish this by running the application through a debug wrapper which describes how to start an application using your favorite debugging tool. \endlist To enable QML Debugging or QML Profiling in the application manager or an application, start it with the \c --qml-debug argument. For more information, see \l{QML Debugging Infrastructure}. \note Although the concept is called "debug" wrappers, these wrappers are not limited to debugging tasks only. They are also useful for various other tasks that involve running the application under test through a wrapper, like profiling tools. When it comes to debugging via \c gdb or \c gdbserver specifically, you might also want to have a look at \l{https://doc.qt.io/qtcreator/creator-debugger-operating-modes.html} {the debugging documentation in the QtCreator manual}. If you need to use \c gdbserver (to debug apps in multi-process mode, or to debug the appman process itself), check out \l{https://doc.qt.io/qtcreator/creator-debugger-operating-modes.html#remote-debugging} {the chapter about remote debugging}. \section2 Environment Variables This is a (incomplete) list of environment variables that influence debugging at runtime: \table \header \li Variable \li Description \row \li AM_NO_CRASH_HANDLER \li If set to \c 1, no crash handler is installed. Use this, if the application manager's crash handler is interfering with other debugging tools you are using. \endtable \target DebugWrappers \section2 Use Debug Wrappers There are three ways to start applications using debug wrappers - all of them rely on a common way to specify which debug wrapper to use: \list \li Within your System UI, use \c debugApplication to start an application, instead of \c startApplication: \badcode ApplicationManager.debugApplication("io.qt.app", "/usr/bin/strace -f") \endcode \li Via D-Bus, you can call the debugApplication method: \badcode qdbus io.qt.ApplicationManager /ApplicationManager debugApplication "gdbserver :5555" io.qt.app \endcode \li Using the \c appman-controller which uses D-Bus internally, but is able to find the correct bus automatically and supports standard-IO redirection: \badcode appman-controller debug-application -ioe "valgrind --tool=helgrind" io.qt.app \endcode The optional \c -i, \c -o, and \c -e parameters redirect the respective IO streams (\c stdin, \c stdout, and \c stderr) to the calling terminal. \endlist \note To use the D-Bus options, the application manager has to be connected to either a session- or system-bus; don't run it with \c{--dbus none}. The debug wrapper specification has to be a single argument string, that is interpreted as a command line. If this string contains the \c{%program%} sub-string, it is replaced with the full path to the application's executable (or the \c appman-launcher-qml binary for QML applications). The same thing happens for \c{%arguments%}, which is replaced with potential command line arguments for the application. If you don't specify \c{%program%} or \c{%arguments%}, they are appended to the resulting command line. This means that all of these debug wrappers are essentially the same: \badcode appman-controller debug-application "gdbserver :5555 %program% %arguments%" io.qt.music appman-controller debug-application "gdbserver :5555 %program%" io.qt.music appman-controller debug-application "gdbserver :5555" io.qt.music \endcode The explicit \c{%program%} argument is important, if the "wrapper" works differently. An example for this would be to start the application with the JavaScript debugger on port 1234 in blocking mode: \badcode appman-controller debug-application "%program% -qmljsdebugger=port:1234,block %arguments%" io.qt.browser \endcode You can also specify environment variables for the debug wrapper - just like on the command line. This command runs your application through \c strace while also setting the \c WAYLAND_DEBUG environment variable to \c 1. \badcode appman-controller debug-application "WAYLAND_DEBUG=1 strace -f" io.qt.browser \endcode For added convenience, you can even set environment variables only, without any actual debug wrapper, to debug imports and plugin loading in a QML application: \badcode appman-controller debug-application "QT_DEBUG_PLUGINS=1 QML_IMPORT_TRACE=1" io.qt.browser \endcode When using complex debug wrappers on the command line often, it's advisable to create aliases or wrapper scripts. */