[Development] Tracing Qt

Robin Burchell robin+qt at viroteck.net
Fri Aug 23 13:20:10 CEST 2013


(apologies in advance for the wall of text)

It's inevitable when working with Qt that sooner or later, you
probably have a desire to work on tracing Qt - or at least part of it.
Qt Creator's QML profiler is one such very prominent example of an
area where this may be useful, but there are many others: usually
sprinkled around Qt hidden behind various defines, environment
variables, and other hard-to-find places. This makes digging into a
problem somewhat hard, unless you are (or can be handheld by) a Qt
expert when you start digging.

It's also a bit of a problem in that each of these methods uses
different ways to communicate information, meaning it is difficult to
write tooling to inspect this data and visualise it. We also miss out
on tracing in a number of areas that *could* potentially be valuable,
such as touch event processing, the event loop, the sky's the limit.

Thanks to Carsten and Andre for their input in hashing the details of
this proposal out.


Let's look at unifying tracing inside Qt. Let's add code to Qt itself
to enable easy introspection of what exactly is going on.

When looking at tracing, it can be boiled down into two levels - an
area (which may be a feature being inspected, or a subsystem - for
instance, QML performance, vsync timestamps, ...) containing events,
so from this, we can gather that we need a way to categorise logging
by area, and the capability to switch logging on by area.

An area should be associated with a simple numeric identifier to avoid
expensive code when manipulating events, but there will be some form
of name => id mapping (for the environment variable below, for

Suggested area-based API:
enum TraceArea {
    TraceAreaDrawing (drawing event, frame event)
    ... other areas as required
    TraceAreaUser = 1000 // held for possible future expansion into
allowing dynamic area registration

rationale: providing system-wide defaults enables tracing of
system-wide behaviour is very useful. Being able to inspect exactly
what an entire set of Qt-based applications are doing while a user is
interacting with it would be a useful thing.

enable_trace(TraceArea area)
disable_trace(TraceArea area)
rationale: a developer may want to turn tracing of an individual area
on/off at runtime, as they start something they are particularly
interested in tracing. This has some inspiration in

Along with this user-facing API, we also need some mechanism to enable
different applications of the tracing data (for instance, the QML
profiler from Creator, Android's systrace
https://developer.android.com/tools/help/systrace.html, plain console
logging, etc). Multiple tracers should be able to handle a single
area. Tracers would live in seperate plugins.

Example tracer API:
class QTracer { virtual void logStart() = 0; virtual void logEnd() = 0; }

QTracer subclasses would register their interest in a particular event
type on construction:

struct MyCoolConsoleTracer : public QTracer {
    MyCoolConsoleTracer() : QTracer() {
        q_register_tracer_for_area(this, TraceAreaDrawing); // we are
interested in this particular event type

    virtual void logStart() {
        qDebug() << "Trace event for drawing, start: " <<
    virtual void logEnd() {
        qDebug() << "Trace event for drawing, end: " <<

The invocation of tracer subclasses is controlled by a simple RAII class:

struct QTraceEvent {
    QTraceEvent(TraceArea area); // invokes logStart on all interested tracers
    ~QTraceEvent(); // invokes logEnd on all interested tracers

Example use being something like:

void draw() {
    QTraceEvent e(TraceAreaDrawing);
    // do painting

Thoughts, flames, cookies?

(with jolla hat on)

More information about the Development mailing list