Peek and Poke

Published Monday June 22nd, 2009 | by

Remember the days when all the tools at hand looked like a Basic interpreter with 30 commands, the most usable being PEEK, POKE and PRINT? Yes, that’s been a while…

Nevertheless, a few months ago I found myself doing lots of “printf-style debugging” again. Even with some basic IDE support that nicely displays QString and QByteArray, digging into more complex structures was just no fun. One of the reasons was certainly that we humans like to think of a QHash at a “higher level” of abstraction, in a way that’s fairly different from the actual implementation – and it’s only the low level implementation a debugger usually sees.

One solution is to bridge the gap between the low level (pointers, anonymous unions, …) and the high level (a bunch of keys with associated values) externally. This is done by asking the debugger for the type of an object only, and then – instead of asking for the low level data – tell it what part of the application’s memory is a hash key and what part is the corresponding value. This information is then transfered to Qt Creator’s “Locals & Watchers” view.

Below is the result for some nested containers and two QObjects with a parent-child relationship:

Code using nested containersDisplay of nested containers

Code using QObjectDisplay QObjects

In the latter case the “more traditional” approach of displaying low-level data would produce:

Low level QObject display

The low-level display of a QHash is even less impressive. Of course, Qt Creator can easily toggle between the views, but it’s rarely needed.

For the convenience of the less Qt-centric audience similar displays have been added for a few widely used containers from the C++ Standard Library, proof coming here:

Code using C++ Standard containersDisplay of Standard containers

The display of aforementioned types (and a few more) works already with the Creator 1.1 release from April on Linux, Windows and Mac. All that’s needed is a not-too-old version of the GNU debugger. Gdb version 6.8 is just fine and widely available, on Mac Apple’s gdb will do.

As time goes on work continues, too. Qt Creator 1.2 will be able to show QAbstractItem, QAbstractItemModel, QByteArray, QDateTime, QDir, QFile, QFileInfo, QHash, QImage, QImageData, QLinkedList, QList, QLocale, QMap, QModelIndex, QMultiMap, QObject, QSet, QSharedPointer, QString, QStringList, QTextCodec, QVariant, QVector, QWeakPointer, std::list, std::map, std::set, std::string, std::vector, std::wstring as well as a few helper types (QMapData and the like). If you miss something desperately, just tell me ;-)

Last but not least, some special news for the people on the Windows side of the world: Starting with Creator 1.2 the debugger frontend will also support Microsoft’s debugger, even featuring the same friendly display of complex data.

André

Did you like this? Share it:
Bookmark and Share

Posted in Qt, QtCreator

14 comments to Peek and Poke

Ben says:

Very nice… I’m an old-school emacs & terminal window kind of guy, but you may yet tempt me…

What’d be nice would be if you could provide hooks so that users could write their own display classes for custom data types to totally do away with the need for printf-style debugging – not only for a high level view of standard types.

Tim says:

Good work. MSVC’s debugger is still unsurpassed so it’s nice to see some improvements. Btw one of the most awesome MSVC features is that you can hover over variables and it will show an expandable (!) tool-tip along the lines of your work here. Can Qt Creator do that yet?

Julien says:

What would be cool, is the ability to write one’s own visualizer, like Visual Studio’s autoexp.dat file. But maybe with a saner syntaxe :-)

Bluebird says:

You rock man !

Abdel says:

What would be nice is an easy to use plugin interface for the display of custom object. In the case of lyx for example the display of ucs4 strings (std::basic_string) would be very nice.

hoang vu says:

There is a new version of mingw yesterday with gcc 4.4.0. Will Qt Creator have support for C++ 0x features present in gcc 4 and Visual C++ 2010 (which is currently in beta phase) ?

Will Stokes says:

Wow, MinGW finally upgraded to gcc4?! Pigs just flew. Will the next release of Qt ship/support Mingw w/ gcc4.4.0?

Adam Higerd says:

MinGW gcc4.4? Satan’s putting on his thermal undies. O.o

Luiz says:

Any change of having a GDB integration on solaris? The current QtCreator code doesn’t compile on solaris. After commenting some ptrace code (and a few other bits) it compiles, but without gdb integration. I hope solaris could get some QtCreator love.

Nimrod says:

The Archer project (http://sourceware.org/gdb/wiki/ProjectArcher) has a good solution in the works. They modified GDB to allow writing extensions in Python and have written pretty printers for the C++ STL. End users can extend the code to support their own datatypes.

Sandeep says:

I am wondering about the integration of build scripts into the IDE. For example take a look at Visual Studio – it generates its msproj files that can also be built on the commandline using nant – does QT Creator have some kind of build-file symbiotic relationship? This should mean I can add/delete files in the IDE and the appropriate build files get generated.

André says:

@Ben, Julien, Abdel: Technically you can do that. The “helpers” are just a few lines of code compiled by Creator and stuffed alongside your Qt installation. You can trigger that process from the Qt 4 Settings menu, you would not have to recompile Creator itself. However, the format the helpers are supposed to produce is… erm… well… “underdocumented” right now.

@Tim: I never liked that feature, but well, it’s available in Creator now, too. Should be in the public git repo by tomorrow noon and end up in the 1.3 release.

@Bluebird: Thanks!

@Luiz: I guess that could work, but it’s nothing I will personally work on. If you have patches I could integrate them, though.

@Nimrod: “In the works” is the crucial part… I am aware of the project. The Python support is even already backported to FSF gdb cvs. There are a few reasons not to use it in Qt Creator right now, though:

1. The first one is portability: I haven’t seen an FSF gdb 7.0 running on Mac yet. Still I need to support Macs, and it works using Apple’s gdb rather well, but this one does not have the python “enhancements” (and probably will never get them). The other “interesting” platform is Windows: even assuming all is fine with gdb there I need the same functionality for the Microsoft toolchain, too. Right now we can use the same code for both. If we were to switch to Python for gdb we would have to maintain two sets of helpers (one in python for gdb, one in C++ for cdb) and to a certain degree even different code paths within Creator proper. Not nice…

2. I don’t really like the idea of the Python dependency. On Linux we can surely assume it’s installed already, but everywhere else the installers would need to take care of it.

3. It’s “not ready” yet. The gdb python “pretty-printers” have serious problems with uninitialized and/or damaged C++ objects. I understand work to fix that is going on, but from my point of view it is not ready for shipping yet.

But don’t get me wrong: I am very happy about the work the Archer people are doing. E.g. speeding up library loading will benefit everybody.

spinynorman says:

What’d be a nice custom data type display interface would be for the user to implement overloaded display functions that QtCreator would automatically check for and use if available.

e.g.

_QtCreatorDisplay(MyType *p)
{
_QtCreatorPrintLine(“%i”, p->i);
_QtCreatorPrintLine(“%s”, p->s.c_str());
_QtCreatorDisplay(&p->l); // Pass the address of a member field for Qt to (recursively) display itself – e.g. a std::list
}

_QtCreatorDisplay(MyOtherType *p)
{
}

etc

So, when QtCreator needs to display a variable at a given address whose debugger provided type matches an available _QtCreatorDisplay() overloading it would call that function to do the display. Within these display functions the user could either call _QtCreatorPrintLine to generate output, or call _QtCreatorDisplay(void *) to tell QtCreator to display a type itself. This would happen recursively so that for a class with a std::list of a custom type the user could pass the list back to QtCreator for display, and QtCreator could then invoke another _QtCreatorDisplay() function to display the list members if they were a custom type.

These display functions would just be implemented as global functions in the users project – no need to tell Qt about them. They’d be a permanent part of the project to be invoked whenever need in the QtCreator debugger.

yan says:

Hi.
QtCreator + visual is really good!!!
Debugging helper is really powerfull!!
unfortunately, this doesn’t with QVector show or on a pointer or a reference

QString s(“Hello Qt”); // Debugging helper ok
QVector v; v

Commenting closed.