Logging and Debugging

Logging

The application manager installs its own message handler to format logging output neatly. If the QtDltLogging module is available, this message handler passes the output to GENIVI Diagnostic Log and Trace (DLT).

Categories

The application manager defines the following logging categories:

CategoryDLT Context IDDescription
am.systemSYSGeneral system messages
am.installerINSTInstaller sub-system messages
am.graphicsGRPHOpenGL/UI related messages
am.wayland.debugWAYLWayland related messages
am.qmlQMLGeneral QML related messages
am.runtimeRTRuntime messages
am.runtime.qmlQMRTQML runtime messages
am.notifyNTFYNotification sub-system messages
am.deploymentDPLMDeployment hints
am.intentINTNIntent sub-system messages
am.cacheCACHCache sub-system messages
generalGENUsed for DLT logging only and enabled by default. Categories that have no context ID mapping in DLT default to GEN; this includes uncategorized logging.

Environment Variables

This is a (incomplete) list of environment variables that influence the logging output at runtime:

VariableDescription
AM_STARTUP_TIMERIf set to 1, a startup performance analysis is printed on the console. Anything other than 1 is interpreted as the name of a file to use, instead of the console. For more information, see StartupTimer.
AM_FORCE_COLOR_OUTPUTCan be set to on to force color output to the console or to off to disable it. Any other value results in the default, auto-detection behavior.
AM_TIMEOUT_FACTORAn 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 1.
QT_MESSAGE_PATTERNSetting this variable has the same effect as described in Debugging Techniques and overwrites the default application manager message handler. Parallel DLT logging is still supported, if available.

Debugging

Introduction

When debugging the application manager, the System UI and applications are dependent on the mode in which the application manager runs:

  • In single-process mode, you can start the appman binary using any debugging tool directly, for example, 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 a single process, so you can only debug the entire process at once; not each application independently.
  • In 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.

To enable QML Debugging or QML Profiling in the application manager or an application, start it with the --qml-debug argument. For more information, see 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.

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:

  • Within your System UI, use debugApplication to start an application, instead of startApplication:
    ApplicationManager.debugApplication("io.qt.app", "/usr/bin/strace -f")
  • Via D-Bus, you can call the debugApplication method:
    qdbus io.qt.ApplicationManager /ApplicationManager debugApplication "gdbserver :5555" io.qt.app
  • Using the appman-controller which uses D-Bus internally, but is able to find the correct bus automatically and supports standard-IO redirection:
    appman-controller debug-application -ioe "valgrind --tool=helgrind" io.qt.app

    The optional -i, -o, and -e parameters redirect the respective IO streams (stdin, stdout, and stderr) to the calling terminal.

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 --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 %program% sub-string, it is replaced with the full path to the application's executable (or the appman-launcher-qml binary for QML applications). The same thing happens for %arguments%, which is replaced with potential command line arguments for the application. If you don't specify %program% or %arguments%, they are appended to the resulting command line.

This means that all of these debug wrappers are essentially the same:

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

The explicit %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:

appman-controller debug-application "%program% -qmljsdebugger=port:1234,block %arguments%" io.qt.browser

You can also specify environment variables for the debug wrapper - just like on the command line. This command runs your application through strace while also setting the WAYLAND_DEBUG environment variable to 1.

appman-controller debug-application "WAYLAND_DEBUG=1 strace -f" io.qt.browser

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:

appman-controller debug-application "QT_DEBUG_PLUGINS=1 QML_IMPORT_TRACE=1" io.qt.browser

When using complex debug wrappers on the command line often, it's advisable to create aliases or wrapper scripts.

© 2021 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.