André Pönitz

Qt Creator and LLDB

Published Tuesday November 12th, 2013 | by

As at least the Mac people know, we have had some support for the LLDB debugger simmering in the cauldron for a quite a while. There was some investigative work done a while ago, back then targeted at desktop Mac and based on the library interface LLDB provides. It turned out to be not working too well on Mac, and not compiling anywhere else, and with the existing GDB solution in a somewhat working state, the effort was put on hold.

Fast forward. Time changes environments, changing environments sometimes result in different answers. In times of Qt-on-iOS and with Apple’s support for GDB dwindling, it became quite clear that we will need support for LLDB as a backend in Qt Creator sooner rather than later and so the work was re-started in the 2.8 release cycle, this time using LLDB’s Python interface.

The decision to go with Python is clearly a trade-off. On the “contra” side there’s mainly the performance penalty we pay for the interpreted nature of the approach; on the “pro” side there are distribution considerations (it’s often easier to just work with an installed “system” debugger than to ship debugger binaries), and there was some hope that we could directly re-use one of the biggest assets of Qt Creator, the “dumpers” (Qt Creator speak), a.k.a. “pretty printers” (GDB speak), a.k.a. “data visualizers” (LLDB speak).

So what works with upcoming Qt Creator 3.0 and LLDB?

Right now the focus is on the “LLDB 300.2″ build that’s shipped with the Xcode 5 Command Line Tools on Mac. That’s the one intented to be used with Qt-on-iOS, and probably the most common setup for the next couple of months. Other versions are known to work to varying degrees, but they are not currently tested at all.

Setting of simple breakpoints, running, and breaking are working. Stepping, especially around inlined function code behaves sometimes quite differently from how GDB would behave, but since that part of the functionality is completely done inside the backends, there is not really much Qt Creator can (and possibly even should) do. The situation is also not really different compared to the GDB-vs-CDB situation, so I trust people with a genuine cross-platform background to consider this bearable.

Display of basic data and plain C-style structures work just fine. Also, 184 of 226 dumper tests pass, meaning that the bulk of non-trivial display is also there. The remaining FAILs are fairly distributed. There are a few missing implementations and some cases of slight variations in visual output compared to other backends. At least one item looks like broken debug information produced by Clang, and  a couple of issues are caused by type lookups in LLDB. Nothing that would count as a show stopper, though.

Also working are quite a few bits and pieces all over the place. Disassembler views (including steppings) and Registers work, as do “Evaluated Expressions”, and of course Stack view with frame switching, etc.

What doesn’t work?

Roughly speaking, “anything else”. Some of the views need some extra nudge to be populated (Modules->Update Module List, …), some aren’t handled yet at all (Snapshots, Source Files, …).

And for the future?

“Finishing it”, clearly. There’s still a lot of glue missing, even things that are trivial to fix. There is some headroom on the performance side, and it’s currently not yet feeling robust. Not unusable, but not comparable to GDB on Linux, either. Given the past experience with the other backends, this maturing will accompany us during some more minor releases.

The environment is, for a change, quite refreshing to work with. The available interfaces are rather complete, thanks to the use of SWIG. Typically, the question is not the so far customary: “How can I get hold of this piece of data at all?” Often it is: “Which of the functions is best, or fastest, or the recommended one?” (In case some LLDB developer reads this here: Big thanks, and hats off!)

All-in-all, I am pretty confident we are on the right track here, including the option to leave the Mac-only corner soonish. Qt Creator 3.0 will support both GDB and LLDB as debugger backends on Mac. Neither will be perfect, but if you want to help to improve the situation, either by filing issues in the bug tracker or even by contributing real code, go for LLDB.

7 Comments


Posted in C++, Mac OS X, Qt, QtCreator

Qt Creator 2.7.0 beta released

Published Thursday February 7th, 2013 | by

We are happy to announce a prerelease of Qt Creator 2.7. This is intended to give some early impression of improvements and new features of the final release scheduled to ship at the end of March, and also as a way to gather last minute user feedback.

All in all we are looking at more than 1300 changes by 63 developers. The changes with most user visible impact are recorded in the ChangeLog.

Let me highlight a few areas:

On the C++ support side we see better, but not yet full support for C++11. The new keywords alignof, alignas and noexcept are handled, as are ref-qualifiers in function declarations, “>>” in template parameters, some more cases of lambda captures, and a few more. The biggest addition is support for uniform initialization (a.k.a. brace initializers). In cases where the build system does not provide enough hints we now assume the code is C++11, not C++98/03, giving generally a better out-of-the-box experience. Before questions arise, yes, this is still our trusty old code model, a switch over to clang is still hampered by the performance impact this would have.

Screenshot of Qt Quick DesignerOn the QML side there was quite some work to make the Qt Quick Designer work with Qt Quick 2. Note, however, that the binary packages are based on Qt 4.8 and therefore do not contain qml2puppet, the external process that is responsible for rendering Qt Quick 2. You can build it yourself from source (qt-creator/share/qtcreator/qml/qmlpuppet/qml2puppet), or wait for the Qt 5.1 release. As the other Qt 5 packages, this will come with a Qt 5 based Qt Creator build. Qt 5.1 will also contain Qt Quick UI components, making the Qt Quick Designer more fun to use.

The “Kits” (i.e. working sets of device, compiler, debugger, and Qt version settings) introduced with Qt Creator 2.6 have proven to be a pretty flexible foundation for a wide scope of use cases, especially in the cross-development area. It is now e.g. possible to use certain custom toolchains without the need to create a specific Qt Creator plugin and also easier to create ready-made custom setups. As a result, it will be possible to provide ready-built embedded Linux images again for the commercial licensees which have been missing in 2.6. The new flexibility came with a few rough edges in the UI, but the worst have been addressed by now. This is one of the areas where feedback from Real World use would be especially valuable.

Other than that there have been smaller and bigger changes across the board. There is, for instance, experimental support for the (also experimental) QBS build system, including .qbs files for building Creator itself, Merge Tool support in the git plugins, new templates for BlackBerry applications, a more straightforward way to visualize images and vector data in external viewers when debugging etc etc. I’d like to take the opportunity and thank Orgad for becoming the most active contributor, and on a more personal note Lukas for picking up the ball in the FakeVim arena, tying up the loose ends and doing all the grunt work of bringing it from the “good enough for me” to the “works well for others” state. Thanks, guys!

What now?

The commercial license holders can download packages from the Customer Portal, open-source users from release.qt-project.org or directly build from the 2.7 branch on Gitorious. Try it, and report back using the Bug Tracker. We are also reachable on #qt-creator on FreeNode IRC and the qt-creator@qt-project.org mailing list. Please do not attempt to report bugs in the comment section of the blog post or the web forum, chances are they won’t be visible to the people who might be able to fix them.

We will go into string freeze on Thursday next week and plan to have a first Release Candidate two weeks later.

A final heads up for the users of the Madde plugin: As the functionality is now mostly available using the Generic Linux approach, the plugin has been downgraded to “not loaded by default”. This has right now the effect that the related settings vanish and need to be re-entered after re-enabling the plugin. We will look into a solution for the final.

37 Comments


Posted in QtCreator

Qt Creator 2.6.2 released

Published Thursday January 31st, 2013 | by

Qt Creator 2.6.2 has just been released. A quick count yields 55 patches on top of 2.6.1, the majority of them of the Mostly Harmless kind, fixing usability and UI issues. Some serious issues got fixed, too, most notably the code editor freeze some people encountered on certain constructs in the C++ editor (see QTCREATORBUG-8472 and QTCREATORBUG-8532). The full change log is here.

Binary packages of stand-alone Qt Creator 2.6.2 are available the download site, sources are as usual accessible from gitorious, and last but not least it is part of the Qt 5.0.1 release.

20 Comments


Posted in Qt, QtCreator, Releases | Tags: ,

Qt Creator 2.2 released

Published Friday May 6th, 2011 | by

We are happy to announce the release of Qt Creator 2.2.

Even if this release is following the previous release after not even ten weeks it contains a whole lot of new features as well as bug fixes and enhancements making an update worthwhile.

Let’s have a look at some highlights:

  • New Bazaar VCS support by Hugues Delorme.
  • Completely rewritten debugging support for the MSVC toolchain, resulting in significant speed improvements and allowing to debug 32 bit and 64 bit applications independent of the build of Qt Creator itself.
  • New configurable MIME type definitions to map editors to files as you wish (look in Environment->MIME Types).
  • New support recording and playing text editing macros by Nicolas Arnaud-Cormos.
  • New configurable snippets to the editors, already including a range of predefined C++ and QML snippets (see Preferences->Text Editor->Snippets). Snippets support placeholders.
  • New configurable access to external tools, also used, but not restricted to, access to the native Qt translation tool lupdate and lrelease.
  • New pinnable debugger tool tips.
  • New support for the CODA Symbian on-device debugging agent.
  • New Valgrind/memcheck based memory debugger integration added (Debug->Analyzer) for Linux and Mac.
  • New specialized editor for the GL shader language.

Improvements to already existing features include

  • Better QML support, such as completion for urls, file imports and attached properties.
  • Better JSlint-style warnings
  • Better locator filter for QML functions.
  • Improved Qt Quick Designer.
  • Better support for manually configured tool chains.
  • Better support for mixed QML/C++ debugging, like mixed stepping from QML into C++ plugin code.
  • Better customization of build steps through variables like the file path of the current document.
  • Proper quoting and use of native shell syntax when specifying a program’s command line arguments.

…and many more, as listed in the changes file.

Source packages, as well as binaries for Linux, Windows and Mac, are available from The Qt Developer Network. The sources are also directly available from the git repository.

As usual, please don’t hesitate to post suggestions through the usual means, i.e. the Bug tracker, the Mailing list, or the #qt-creator IRC channel on Freenode.

To give some optical impression of Qt Creator, some random screenshots follow:

Qt Creator 2.2 not yet contained in the Qt SDK 1.1, but the plan is, of course, to make it available as update.

57 Comments


Posted in C++, Qt Quick, QtCreator

Peek and Poke, Vol 4

Published Friday October 15th, 2010 | by

Qt Creator 2.1 is looming over the horizon, and therefore, the time has come to add another chapter to the Tale of Debugging.

To keep it short, I’ll try to focus on two issues: architectural changes in the 2.1 cycle and some kind of update, long overdue, on extending the debugger to display your own data types.

Architectural Changes

There have been quite a few fundamental changes to Qt Creator’s debugger plugin during the recent development cycle. They were mainly driven by the need to extend the debugger scope beyond the original C++ debugger front-end to allow mixed C++/JavaScript/QML debugging.

Incidentally, the results are beneficial also for the more traditional use cases. Previously, we could take static snapshots of a process and jump between them to compare variable contents, memory, and so on. However, the first such jump had to kill the live process, because most of the debugger plugin was a singleton (nobody wants to debug more than one process at a time, right? ;-}), and before switching the data models to one of the snapshots, the live process had to make way. Not anymore. We can now have as many engines running at the same time as we want, so the live process engine can just continue while examining a snapshot. Not to mention that switching between snapshots is faster now…

Talking about performance: While the CDB integration (that is used to access binaries compiled with the Microsoft compiler on Windows) is still far from snappy, startup times have been reduced by 15 seconds. Each, time, the, debugger, is, started. That makes it bearable at least.

In the Free gdb world (i.e. Linux, Symbian, Maemo, Windows/MinGW) we now can take advantage of gdb’s shiny new “Dwarf Index” generation. This significantly reduces warm start times. For the Qt Creator project itself (which consists of more than a half a million lines in .cpp by now, not to mention headers or generated code, pulling in more than a hundred shared objects) I now get a warm start inside the debugger in 13 seconds (and a cold start in around 40). By leaving out non-vital plugins this can go down (depending on the definition of vital) to four(!) seconds. For smaller projects, such as the Qt examples, this is barely noticeable anymore. So you now really have no reason not to use Qt Creator’s gdb integration out of fear of falling asleep while waiting for application startup.

And getting started with debugging is still as simple as it used to be: Load or create a project. Press F5.

That’s it. No magic dancing needed on your side, not launch configuration to setup, no black roosters harmed in the process. For having a quick look at a core file or a running process, you can even skip the project bit and directly start Qt Creator with the -debug <name_of_core_file> or -debug <process_id_of_running_process> command line arguments.


And now for something completely different:

(Re-)Introduction to Data Dumpers for the Qt Creator gdb front-end

The topic has been covered in the first and second post, but by now, so many details have changed that following the process outlined there will not directly lead to success.

So let’s start over.

The beast has appeared under different names in the past: Data Dumpers, Pretty Printers, Debugging Helpers. I guess none of them is really to-the-point anymore, but in my brain it’s still “Data Dumpers”. It’s all about examining data structures at a higher level. No funny d-Pointers, vector data hidden behind void *, image data as hex string (or not visible at all), and so on. I really don’t want to see any of that when debugging code using containers. Or a QObject. All I want to do then is to see the actual contents of the container or the properties of the QObject I am working with, and maybe have a way to navigate to the objects that are connected to it.

That need led to the original incarnation of the Dumpers, as introduced in the first blog. They worked, but a recurring request since then – starting with the comments to the blog post – was to make that easily extensible by users of Qt Creator.

By now, and a change of technology later, I think we are there. Gdb nowadays supports Python as a scripting language which is way more complete and especially faster than the old canned sequences of commands. It even has built-in pretty printing but, while this is nice and usable on the command line, it has some severe limitations that makes it unusable for our purpose. In a display hierarchy, it creates only one level at a time, which makes virtual data, such as the “signals” group subnode in a QObject, difficult to display, and the MI “var object” machinery impossible to use. Not to mention robustness issues in case of uninitialized objects which are rather common in C++. Luckily, all this does not matter: Having a proper scripting language is all that’s needed.

So… how to get started?

Suppose we have the following code:

QUrl url(QString("http://www.nokia.com"));

Traditionally, the debugger would show you a tree, as follows:

I think “Eeeks!” is about the most common reaction to such a display of “information”.

How did I find out the data was visible in encodedOriginal?

By trial and error. And note that I was lucky that it was a QByteArray which happens to have a char * member for the data which happens to be handled natively by gdb. If it had been a QString, it would have been a ushort * and all I would have seen would have been the numerical value ‘104’.

I’d pretty much prefer to see something like:

at the top-level, instead, with the option (but not the need) to look at the details — even if they could look a bit nicer:

So what do I do? Knowing that Qt Creator will set up its Python-based data dumpers anyway, I just need to have: (a) a dumper for QUrl, and (b) inject it into the process.

(a) is easy: We need to define a python function  qdump__QUrl which will be automatically called when an object of the type QUrl (or myns::QUrl when Qt was built in the namespace myns) is encountered:

def qdump__QUrl(d, item):
    d.putStringValue(item.value["d"].dereference()["encodedOriginal"])
    d.putNumChild(0)

The function basically writes a put QString item taken from url.d->encodedOriginal into the value column of the Locals&Watchers view and disallows further expansion.

If expansion is wanted, a full implementation of the dumper would look something like the following:

def qdump__QUrl(d, item):
    d.putStringValue(item.value["d"].dereference()["encodedOriginal"])
    d.putNumChild(1)    # Any non-0 value will do. A wart...
    if d.isExpanded(item):
        with Children(d):
            d.putFields(Item(data, item.iname))

 

(b) is easy, too: There is a Gdb Startup Script setting in the gdb options page. This points to a script that is parsed by gdb after the Python machinery is set up. Therefore, we can just write the function above into a mydumpers.py file and point the setting there. Unfortunately (or fortunately, as it speeds up things), the list of known dumpers is cached, so the cache needs to be flushed. There are several ways to do that. The simplest, but least obvious, is to add a line containing only bbsetup() at the end of mydumpers.py. (Smells like a bug, doesn’t it? I guess I’d better fix that in 2.2…)

It is also possible to implement several ways to display data of a given type, and switch between them on-the-fly, globally or on a per-object base. Qt Creator uses that by itself to allow the selection of different encodings for string-like data, such as char * or wchar_t *, or to allow the viewing of data in separate windows.

I’ll spare you the details for now and rather finish with the list of latest additions to the Dumper Zoo: New in 2.1 are QDate, QTime, QHostAddress, QRegion, boost::optional, QSharedData, QSharedDataPointer and QTextCursor. Some others like QObject, QList, C-style arrays, QSize, QSizeF, QImage/QPixmap, std::vector, QVariant(QString), qulonglong, std::size_t, std::ptrdiff_t, QScopedPointer, QStandardItem have seen some bug fixes or improvements. The most notable change here is that QObject now displays dynamic user defined properties.

31 Comments


Posted in C++, Qt, QtCreator

Peek and Poke, Vol. 3

Published Thursday April 22nd, 2010 | by

With the feature work on Qt Creator 2.0 slowing down in anticipation of the beta release there is a bit of time to update the Tale of Debugging.

Executive Summary for the people not following the thread so far: Users of recent release of the GNU Project Debugger gdb can automate certain tasks using the Python scripting language. Qt Creator takes advantage of that to populate the Locals and Expressions view. While this could be done before using the gdb/MI protocol it is more robust and way more powerful nowadays. And, surprisingly, faster.

But let us start with a look at the outside world. Work is progressing nicely, albeit, unfortunately, not uniformly. The FSF gdb has seen two official releases (7.0.1 and 7.1) since December, and both releases decided to play nice with Qt Creator on Linux and Windows/MinGW. The Symbian folks managed to get hold of a pre-7.0 based port that’s capable of handling Python, so they are on the lucky side now, too, and so is, in theory, Maemo.

The other factions have been less lucky. Of course, Apple’s gdb is still fast and robust on Mac, but as it’s 6.3 based, it does not have Python, and the Python-enabled FSF-7.x-for-Darwin port happily crashes when only looking at something linked with QtCore. And then there was some vain attempt to improve the sad gdb-on-Windows/MSVC story.

 

Anyway, back to the bright side:

Qt Creator’s Python based ‘helpers’ to inspect objects of certain Qt and Standard data types now finally caught up with their older compiled cousins – and went a bit further. By now they cover:

QAtomicInt, QBasicAtomicInt, QByteArray, QChar, QAbstractItem, QAbstractItemModel, QModelIndex, QDateTime, QDir, QFile, QFileInfo, QFlags, QHash, QList, QImage, QLinkedList, QLocale, QMap, QMultiMap, QObject, QPixmap, QPoint, QPointF, QRect, QRectF, QSet, QSharedPointer, QSize, QSizeF, QStack, QString, QStringList, QTemporaryFile, QTextCodec, QUrl, QVariant, QVector, QWeakPointer, std::deque, std::list, std::map, std::set, std::string, std::vector, std::wstring, std::basic_string, gnu_cxx::hash_set, TBuf and TLitC.

Why QImage you may ask. Uuh… well. Later ;-)

For the beginning some boring stuff, like making gdb play nicely with stuff you’ll never need. Nested anonymous struct for instance. I never noticed this was a problem with the gdb/MI based versions until someone created a bug report for Qt Creator. The problem is exposed by the following code:

        union {
            struct { int i; int b; };
            struct { float f; };
            double d;
        } a = { 42, 43 };
        a.i = 1;
        a.i = 2;
        a.i = 3;

Put a breakpoint on the a.i = 1 line and press F5. When the program stops, expand the a, #1 and #2 nodes:

Anonymous Structs 1

Everything there. You can even modify the data in that structure: Change a.i in Locals view to 0. This changes f, d but, as expected, not b:

Anonymous Structs 2

 

Bored? Perhaps less boring is that you can now use scripting on the IDE side to do some fancy stuff with watched expressions, i.e. expressions that are evaluated each time the process stops, like at a break point or after a single step.

Have you ever had a large array of structs that contain lots of data but for the time being you are really only interest in a couple of members? I.e. something like the following, only a bit bigger?

        struct S { int a; double b; } s[10];
        for (int i = 0; i != 10; ++i)
            s[i].b = s[i].a = i;

Now, what if you are only interested in the a members of items 2 through 4?

Filtering to the Rescue! Create a new entry in the Watchers view (by selecting “Add New Watcher” from the Watchers view’s context menu or by “cloning” an expression from the Locals view or the main text editor) and edit it to

        ['s[2].a', 's[3].a', 's[4].a']

You can enter a Python list of strings there, and each will be evaluated as an expression by gdb in the context of the current stack frame. The result will show up as children of the list’s own node in the Watchers view, and as we specified the a member in all cases, we get a flat list of three ints.
Exactly what we were interested in.

But that’s not all. The more daring can even use Python to create the list of expressions by using e.g.

        ['s[%d].a' % i for i in range(2, 5)]

Filtered Display

and one can even obtain the range indices from other variable values or arithmetic operations thereof etc.

 

Still bored by looking at black-on-white numbers and strings? What about watching an image being painted? With real colors ;-))?
Then try the following:

        QImage im(QSize(200, 200), QImage::Format_RGB32);
        im.fill(QColor(200, 10, 30).rgba());
        QPainter p;
        p.begin(&im);
        p.setPen(QPen(Qt::black, 5.0, Qt::SolidLine, Qt::RoundCap));
        p.drawEllipse(20, 20, 160, 160);
        p.drawArc(70, 115, 60, 30, 200 * 16, 140 * 16);
        p.setBrush(Qt::black);
        p.drawEllipse(65, 70, 15, 15);
        p.drawEllipse(120, 70, 15, 15);
        p.end();

Put a breakpoint on the first ‘drawEllipse’ line. Run and wait until the breakpoint is hit. Now go to the context menu of the im item in the Locals view and toggle between “Normal” and “Displayed” in the “Display of Type QImage” submenu.

Keep it at “Displayed”, press F10 a few more times, and watch the contents of the extra window:

QImage 2  QImage 3  QImage 4  QImage 5

 

So many possibilities ;-)

André

PS: A big “Thank you!” to everybody who was involved on making this possible by bringing Python scripting to gdb, especially to Thiago Jung Bauermann, Phil Muldoon and Tom Tromey.

20 Comments


Posted in Qt, QtCreator

Peek and Poke, Vol. 2

Published Tuesday December 15th, 2009 | by

NOTE: Some of the commands shown below have changed in more recent versions of Qt CreatorPlease check the Qt Creator documentation for details. Self-compiling gdb is rarely needed nowadays (2012).

Remember the day when you were asked to 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?

That’s been almost half a year now, and the tale is ready to get a new chapter.

The latest and greatest in the World of the GNU Project debugger (also known as gdb) is Python scripting, — and it is really awesome. I certainly don’t tend to exaggerate on the positive side, but this is close to sliced bread with chocolate and beer. Erm… well, you get the idea ;-)

The feature has been in the works for a while (the initial commit to the gdb CVS repository was in August 2008) and was officially released with gdb 7.0 in October 2009. So in theory it is now in a usable state and accessible on a broad range of platforms.

Unfortunately, outside the Ivory Tower usability is a bit hampered by the fact that gdb 7.0 likes to divide by zero every now and then, and the “broad range of platforms” excludes Mac (Apple’s gdb for Mac is based on FSF gdb 6.3, and FSF gdb does not work there), Symbian (best bet so far is based on FSF gdb 6.4), and, of course, MSVC compiled binaries on Windows (no gdb at all).

But a few Gaul villages are still standing: It does work on Linux, and after tickling the gdb sources a bit it even works well, so well in fact that the next release of Qt Creator will use gdb’s Python scripting to build up the “Locals and Watchers” view.

This also lets us nicely address one of the most prominent feature requests: To “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”, or “an easy to use plugin interface for the display of custom object”, or “a nice custom data type display interface would be for the user to implement” (see comments of Ben, Abdel, and spinynorman), or a few similar ones on qt-creator@qt-project.org

Here is how:

  1. Get a Python enabled gdb by either
    • downloading a pre-build binary from here
    • –or–

    • building one yourself:
      • get build prerequisites including Python development packages (on Ubuntu e.g. python2.6-dev)
      • get gdb sources from the archer-tromey-python branch:
           git clone git://sourceware.org/git/archer.git
           cd archer
           git checkout -b archer-tromey-python origin/archer-tromey-python
      • patch sources to work around that division by zero:
           --- a/gdb/value.c
           +++ b/gdb/value.c
           @@ -1920,7 +1920,8 @@ value_primitive_field (struct value *arg1, int offset,
                  v = allocate_value_lazy (type);
                  v->bitsize = TYPE_FIELD_BITSIZE (arg_type, fieldno);
           -      if ((bitpos % container_bitsize) + v->bitsize bitsize < = container_bitsize
                     && TYPE_LENGTH (type) bitpos = bitpos % container_bitsize;
                  else
           
      • configure and build it:
           ./configure --with-python --disable-werror
           make

        Your new gdb will emerge as gdb/gdb. It will identify itself as gdb-6.8.50.something-cvs. That is fine.

  2. Get a recent checkout of Qt Creator master branch and build it:
       git clone git://gitorious.org/qt-creator/qt-creator.git
       cd qt-creator
       qmake -r
       make
    
  3. Point Qt Creator’s gdb path (Options -> Debugger -> Gdb -> Gdb Location) to your archer gdb or set the QTC_DEBUGGER_PATH environment variable before starting Qt Creator.
  4. Start debugging as usual.

That gives you the kind of display of QStringList, std::map etc use are used to from the old C++ based debugging helpers. You might notice that it’s even a bit quicker. Nothing to be scared about, though.

But now, time for your own debugging helpers. Assuming you have the following class template in your code:

  template <typename T> class Vector
  {
      public:
         explicit Vector(int size) : m_size(size), m_data(new T[size]) {}
         ~Vector() { delete [] m_data; }
         //...
      private:
         int m_size;
         T *m_data;
  };

all you need is to

  1. write the following into some file, say vector.py:
        def qdump__Vector(d, value):
            data = value["m_data"]                          # extract the 'm_data' member from the object
            size = value["m_size"]                          # extract the 'm_size' member from the object
            d.putItemCount(size)                            # set the 'value' field to ''
            d.putNumChild(size)                             # announce 'size' children
            if d.isExpanded():                              # check whether the children should be shown, too
               with Children(d, size):                      # if so:
                   for i in d.childRange():                 #   iterate over the specified range
                       d.putSubItem(i, data.dereference())  #   show value btained from dereferencing the data pointer
                       data += 1                            #   advance the data pointer by one
    
  2. make it accessible to gdb by putting
    python execfile('/path/to/your/vector.py')

    into the Additional Startup Commands settting

  3. start debugging as usual – i.e. hit F5

Qt Creator’s default helpers are defined in share/qtcreator/dumper/qttypes.py. For a description of the two parameters ‘d’ and ‘value’ (of type ‘Dumper’ and ‘gdb.Value’ respectively), refer to the Qt Creator documentation.

Have fun!
André

9 Comments


Posted in Qt, QtCreator

With or Without Qt

Published Monday August 24th, 2009 | by

I wanted to do a certain bit of benchmarking for quite a while – years actually – but triggered by one of those friendly discussions on the ##c++ channel on FreeNode I finally figured I should sit down and actually do it. I was expecting some interesting results, but the not at the scale that we will see below.

If you ask the resident channel bot on ##c++ how to tokenize a std::string you’ll get offered the following (slightly compacted) code snippet:

  #include <sstream>
  #include <vector>
  #include <string>

  std::string str("abc:def");
  std::istringstream split(str);
  std::vector<std ::string> tokens;
  for (std::string each; std::getline(split, each, ':'); tokens.push_back(each));

Obviously, that’s the “Without Qt” version: Clean Standard C++, as straight-forward as it can get. The contender “With Qt” is:

  #include <QString>
  #include <QStringList>

  QString str("abc:def");
  QStringList tokens = str.split(':');

From the source alone we can collect a few numbers:

Property   Without Qt   With Qt   Ratio
Code to type   3 lines   1 line   3.0
  147 char   35 chars   4.2
Code usable as sub-expression   no   yes
Size of compilation unit [1]   22215 lines   7590 lines   2.9
Compile time [2]   1.64s   1.02s   1.6

To compare performance I use a benchmark that I just checked into the Qt source base, under tests/benchmark/qstringlist. It basically consists of running the above mentioned snippets on a string “unit:unit:unit:….” with 10, 100, 1000, and 10000 “unit” chunks and record callgrind’s “instruction loads per iteration” as follows:

Chunk count   Without Qt   With Qt   Ratio
10 chunks     18,455   9,827   1.9
100 chunks     134,578   71,008   1.9
1000 chunks     1,244,425   641,174   1.9
10000 chunks     13,161,115   7,053,633   1.9

In this case, bigger numbers mean more time needed to execute. Interesting, isn’t it?

After reading Thiago’s latest posts I got the impression that people like conclusions. The verbose version of a conclusion might be something along the lines of

Using Qt’s functions to split a string you need about a third of the effort to write code, and get a 47% performance boost at runtime.

Or shorter (Qt way): “Code less, create more”.

André

[1] Counted with “g++ -E -DQT_NO_STL -I$QTDIR/include/QtCore -I$QTDIR/include qt.cpp | wc” using g++ Ubuntu 4.3.3-5ubuntu4.

[2] Fastest result of “real” time, out of 20 runs each. “user” times in both scenarios smaller, with similar ratio.

19 Comments


Posted in Qt

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é

14 Comments


Posted in Qt, QtCreator