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:
Category | DLT Context ID | Description |
---|---|---|
am.system | SYS | General system messages |
am.installer | INST | Installer sub-system messages |
am.graphics | GRPH | OpenGL/UI related messages |
am.wayland.debug | WAYL | Wayland related messages |
am.qml | QML | General QML related messages |
am.runtime | RT | Runtime messages |
am.runtime.qml | QMRT | QML runtime messages |
am.notify | NTFY | Notification sub-system messages |
am.deployment | DPLM | Deployment hints |
am.intent | INTN | Intent sub-system messages |
am.cache | CACH | Cache sub-system messages |
general | GEN | Used 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:
Variable | Description |
---|---|
AM_STARTUP_TIMER | If 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_OUTPUT | Can 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_FACTOR | 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 1 . |
QT_MESSAGE_PATTERN | Setting 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 ofstartApplication
: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
, andstderr
) 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.