Logging and Debugging

Logging

The application-manager installs its own message handler that neatly formats logging output. It will also pass the output to GENIVI DLT (Diagnostic Log and Trace), if the QtGeniviExtras module is available.

Categories

The following logging categories are defined by the application manager:

  • am.system - General system messages
  • am.installer - Installer sub-system
  • am.graphics - OpenGL/UI related messages
  • am.wayland.debug - Wayland protocol related messages
  • am.qml - QML messages
  • am.runtime.qml - QML runtime
  • am.qml.ipc - QML IPC
  • am.notify - Notification sub-system
  • am.deployment - Deployment hints
  • am.intent - Intent sub-system
  • general - General messages not part of any ApplicationManager sub-system

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 will be printed on the console. Anything other than 1 will be interpreted as the name of a file that is used instead of the console. For more in-depth information see StartupTimer.
AM_FORCE_COLOR_OUTPUTCan be set to on to force color output to the console and to off to disable it. Any other value will result in the default, auto-detection behavior.
AM_TIMEOUT_FACTORAll timed wait statements within the application-manager will be slowed down by this (integer) factor. Useful if executing in slow wrappers, like e.g. valgrind. Defaults to 1.
QT_MESSAGE_PATTERNSetting this variable has the same effect as described on the Debugging Techniques page and will overwrite the default application-manager message handler. Parallel DLT logging will still be supported, if available.

Debugging

Introduction

Debugging the application-manager, the System-UI and applications is dependent on the mode the application-manager is running in:

  • In single-process mode, you can just start the appman binary using your debugging tool of choice directly (e.g. gdb --args appman -c config.yaml). Since everything is running in a single process, you cannot debug applications independently though.
  • 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 described for a single-process setup above. Debugging applications is a bit more tricky though, since they have to be started by the application-manager: this is accomplished by running the app through a debug wrapper which describe how to start an application using your favorite debugging tool.

To enable QML Debugging/Profiling in the application-manager or an application it needs to be started with the --qml-debug argument. See QML Debugging Infrastructure for more information.

Please note that although the concept is called "debug" wrappers, these wrappers are not limited to actual debugging tasks. They are also useful for various other tasks that involve running the program under test through a wrapper, e.g. profiling tools.

Using Debug Wrappers

There are three ways to do start applications using debug wrappers - all of them rely on a common way to specify which debug wrapper to use:

  • Within your System-UI, do not use startApplication to start an app, but debugApplication:
    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 will redirect the respective IO streams (stdin, stdout and stderr) to the calling terminal.

Note: In order to use the D-Bus options, the application-manager has to be connected to either a session- or system-bus - make sure to not 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 sub-string %program%, it will be replaced with the full path to the executable of the application (or the appman-launcher-qml binary for QML applications). The same thing happens for %arguments%, which will be replaced with potential command line arguments for the application. If you don't specify %program% or %arguments%, they will simply be 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 also have the possibility to specify environment variables for the debug wrapper - just like on the command line. This command will run 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 just only set environment variables without any actual debug wrapper, e.g. 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

It is advisable to create aliases or wrapper scripts when using complex debug wrappers on the command line often.

© 2019 Luxoft Sweden AB. 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.