Thursday, July 21, 2011

Qt Inspector

Whilst debugging a widget layout problem a few days ago, I was looking around for a tool to view the structure of a Qt application without having to recompile it, or in other words, Firebug / Web Inspector for Qt widgets.  I found the KSpy tool in the KDE repositories which is in need of some love and there are a variety of tools to aid in runtime debugging and modification of QML but not much in the way of tools for QWidget-based interfaces.  Please let me know in the comments if I missed any.

I have put together a simple tool called Qt Inspector.

Qt Inspector starts a specified application or connects to an existing Qt application and once connected can:
  • Browse the object tree of Qt applications.
  • View properties of objects
  • Edit properties of objects
  • Locate a widget in the object tree by clicking on it in the application
  • Copy a reference to an object for use in a debugger (eg. to manipulate it by calling methods on it, examine member fields, setup conditional breakpoints)
Here is a screenshot of Qt Inspector connected to Dolphin showing the widget tree for the settings dialog. Like the Web Inspector or Firebug, this can be used to tweak styling settings, layouts and other properties without a recompile.



Usage:

Qt Inspector can either attach to an existing application or launch
a specified application and then attach to it.

From a terminal, this can be done with:

qtinspector [process ID]
qtinspector [program name] [args]

Design:

Qt Inspector operates by injecting a helper library into the target process using gdb.  This helper library sets up a local socket and listens for requests from the inspector process. The inspector and target process communicate via protocol buffer messages over this socket.

The inspector uses Qt's meta-object system to fetch the properties of an object and read/write their values, so properties need to be declared with Q_PROPERTY for them to be visible to the inspector.

Source:

The code is up on GitHub.  Please download it and give it a whirl.  Happy forking :) 

Update:  Eva Brucherseifer let me know about the Basyskom Inspector tool in Gitorious.  In addition to being able to select and inspect widgets it can also view signals and slots, application resources and take screenshots. 

13 comments:

Ruurd said...

Hmm. On openSUSE even after fixing the path to the shared object the inspector still crashes gdbhelper on dlopen-ing the so...

Elv13 said...

Hi, great tool. I installed it as soon as I saw this.

Please add a proper make install to your cmake script. Without it your application have hard time finding it's own .so

Anonymous said...

Will ApiTrace (on Zack Ruskin's blog help?

Anonymous said...

Woww, the app itself is already great, but I'm not sure I like the fact that any binary can hijack any Kde/Qt app. It's not your fault, I know, but I'm realizing that.
Just think about making dolphin icons pointing to some evil-minded website by just overriding QAction.. Is it a way to protect widgets from being modified that way ?

dhaumann said...

Can you please include that in kdesdk?

Unknown said...

Hi Ruurd,

The tool writes the output from gdb to a file called gdb.log in the directory which qtinspector. That might be helpful to find out why it isn't working.

@Elv13,

Thanks for the advice. I must admit I've always run the tool directly from the build directory.

@Anonymous,

The application has the same security restrictions as a debugger. If you can attach to a process and manipulate it with gdb then you can inspect it, otherwise this tool will not be able to connect to the application.

Vishesh Yadav said...

This is great! Thanks for sharing :-)

Ignat said...

Aha! This makes Qt look like a .NET-like framework. This was the last step. I've noticed that you can't easily debug Qt applications due to the signals and slots, and I guess that any code using the Qt Meta Object System can't be easily debugged either. Well, this is what happens when a commercial company writes the code, probably. Same as using in-house containers instead of the STL ones. I guess it's time to switch to GTK+, now that they have released a new version.

But otherwise, this is indeed an invaluabvle tool, because as stated above, you can't easily debug Qt applications using plain GDB.

Dave said...

@anonymous

This works by using something called ptrace, you can block this.

Read up on: /proc/sys/kernel/yama/ptrace_scope

A suitable setting is to only allow injecting from parent applications, this allows debugging (and Qt Inspector with a slight mod) but disallow random injecting.

A cool mod would be to write something that finds all QLineEdit and changes the echo mode. I've seen a windows 'hacking tool' which does this.

Klemens said...

Hi, I tried to build the Tool for hours with no success on Mac OSX 10.6.7. Unfortunately I have only very basic expericnes with CMake / Make.

All I get is the following error:
make[2]: *** No rule to make target `CMakeFiles/QtInspector.dir/depend'. Stop.
make[1]: *** [CMakeFiles/QtInspector.dir/all] Error 2
make: *** [all] Error 2

Hopefully you can give me some pointers. A google-search didn't help so far.

junkew said...

Under Windows VC2010 Express
Unable to find
#include "inspector.pb.h"
and not finding
#include

Should it be possible to build under windows?

Unknown said...

> Should it be possible to build under windows?

No. The cross-process communication and logic to inject a helper DLL using a debugger hasn't been ported to Windows.

KDAB have built a more sophisticated tool which does what Qt Inspector does plus more and it looks like that does have support for Windows: http://www.kdab.com/kdab-products/gammaray/

bethanybeachhouserentalsde.com said...

It won't work in actual fact, that is exactly what I suppose.