[Development] Tracing Qt
Rutledge Shawn
Shawn.Rutledge at digia.com
Fri Aug 23 14:30:09 CEST 2013
On 23 Aug 2013, at 1:20 PM, Robin Burchell wrote:
> Thoughts, flames, cookies?
Yes I've been interested in doing something like that too, for debugging touch and other types of events. The biggest problem with events is that they get converted into different types and queued multiple times, which is both inefficient and hard to debug. My goal is to be able to trace an OS touch event all the way through to the QtQuick item which handles the QtQuick-specific form of the event. So I think this is (yet another?) high-priority thing to get done; and I don't think it's hard, we just need to agree whether it's OK to "clutter" the code with these trace lines. And to avoid performance impact we need to be sure that in non-debug builds, the code disappears completely. I think that means the trace lines should use a macro, so that the macro can be #defined to a no-op for non-debug builds. The trace lines should be one-liners so we don't have #ifdef/endif clutter around all of them, but they should generate no machine code whatsoever when Qt is compiled in non-debug mode. Otherwise it would become hopeless to use it in performance-critical code.
As an example, if you want a DEBUG macro which expands to printf, you will need a varargs version of the macro to use when you want to compile without debug support. e.g.
#define DEBUG(format, args...) ((void)0)
And varargs macros are not supported by all compilers. But a macro which takes a fixed number of args is easy to turn into a no-op.
There are alternatives. One could write a script or some other type of tool which can insert the trace lines into your source tree whenever you want to do some tracing, so that the source code clutter is there only when you want it. (This has even been done before. Probably even many times, although I only got my hands on one such tool.) But that's also more difficult and requires too much prior knowledge; e.g. to trace a particular type of event I have to know all the types that it can be converted into, before I can even start searching the code to find where those types are used. And events are distinguished by enums, not just by their C++ types. Tracing touch events should not automatically imply tracing all events, because that would be like drinking from a firehose. But whenever an enum (like QEvent::Type) is involved, there are usually switch statements in various places, so each branch of the switch might need its own trace line with a different key or set of keys that can be filtered.
Tracing certain function entry/exit points would also be enough some of the time for some use cases, but not all the time (e.g. when we are only interested in certain branches of a switch). If it were enough, then it would be possible to write something like a debugger which automatically creates a gazillion breakpoints, and each time it hits one, it logs the fact and automatically continues. Then the Qt source wouldn't require modifications, only the same debug symbols that gdb etc. already use. This sort of thing has been done before too (but I'd have to google again to find those projects again).
If the trace clutter bothers people, they could be kept in separate patches which are maintained so that they can always be applied on-demand. But then the danger is code rot in those patches. It would be less trouble if the patch tool was more intelligent, based on recognizing similar-looking code instead of a line-by-line diff. But then it's more like a script to add the traces rather than just a patch.
Either way it would tend to need autotests to keep it working.
Whatever we do might benefit from sharing some of the QDebug/QWarning related code instead of starting over from scratch. And those are not as flexible as they could be, either. At one previous commercial job we had a custom log function which underneath was QDebug with a category field added to each line, and then there was a GUI window for viewing and filtering the debugs in real-time as the software emitted them. That sort of thing could be built in to Qt, too. At some point tracing and logging could be essentially the same thing, if we design it that way.
So it's kindof a tricky problem, but I hope we can at least agree on some useful framework for the near term.
More information about the Development
mailing list