Skip to content

Perfect Debugging Experience with QtCreator on Android

While I was working on a yet-to-be-announced super secret and cool Qt on Android project, I had to do a lot of debugging. This way I found that debugging Qt apps on Android using QtCreator was ok, but it had some issues, which was kinda frustrating.

  • First issue was that I could not debug on an Android 8 device.
  • Second issue was that, even if the debugger was almost ok for debugging Qt apps, debugging Qt itself was not that good.

Long story short, these problems will be fixed starting with QtCreator 4.6.1 (was too late for 4.6.0) or 4.7, and I also paved the way for using lldb if necessary, though, gdb works perfectly for me. And in the (distant) future MAYBE even being able to do java debugging from QtCreator as well!

Keep reading if you are interested in technical details.

How the debugging worked until now: it used a handshake technique:

  • The application built for debugging bundles gdbserver into the apk.
  • We start the application from QtC with some special params.
  • The app checks these params, it starts gdbserver, it creates a socket, then it waits for QtCreator to connect to this socket.
  • QtCreator uses adb to forward gdbservers and the socket port to your host.
  • QtCreator tries to connect to the socket created by your application. When it succeeds to connect to that socket it attaches host gdb to gdbserver. At this moment all the application’s .so files are loaded and gdb will search for their symbols on the host side. It sets the breakpoints.
  • At the end it signals the java application (using the previous socket) that it can continue the execution.

How it works now: it’s using the same technique that Android Studio uses:

  • The application built for debugging bundles gdbserver into the apk.
  • The application is started in debug mode (we add “-D” param to adb shell am start).
  • The default wait for debugger dialog appears which waits for a jdb connection.
  • QtCreator uses “adb shell run-as” to search for gdbserver and it starts it.
  • QtCreator uses adb to forward gdbservers and the socket port to your host. At this moment no .so files are loaded by your application.
  • QtCreator connects to gdbserver.
  • QtCreator uses jdb to attach to the java debugger and it signals the application to continue the execution.

At first glance, both ways look similar, but …. there is a big difference 🙂

  • First and foremost the application doesn’t need the handshake hack, this means that we can soon drop that code from Android Qt apps.
  • The second difference, which makes the debugging perfect, is at the point when we attach gdbserver to the application. As you can see, in the first way we attach gdbserver to the application after we load all .so file, this means that all breakpoints to static vars constructors or to JNI_Onload will not work, because these functions are already called by the linker.
  • Now, because QtCreator is in control of the gdbserver part, with some effort it can search for lldbserver instead, and start it.
  • Last but not least, because it’s using jdb to start the application, it might be possible to use it also to debug the java part of the application!

The downside of the new way is that the start up is a little bit slower, because instead of loading the symbols for all the .so files at once, it will load them one by one as they are loaded by the application, which on my Ryzen 1700X is from 2 to 5 seconds slower.

If you can’t wait for QtCreator 4.6.1/4.7 you can cherry-pick the following two patches and rebuild QtCreator yourself:

In the end I want to thank The Qt Company folks who helped me in testing these patches on all platforms and on as many devices as we had!


About KDAB

KDAB is a consulting company offering a wide variety of expert services in Qt, C++ and 3D/OpenGL and providing training courses in:

KDAB believes that it is critical for our business to contribute to the Qt framework and C++ thinking, to keep pushing these technologies forward to ensure they remain competitive.

7 thoughts on “Perfect Debugging Experience with QtCreator on Android”

  1. Thanks, debugging on android really worked 20% of the time previously in my experience !

  2. Hi BogDan, sorry for the off-topic but I know you are the master of Qt for Android and maybe can help with this. I opened this bug couple of months ago:
    https://bugreports.qt.io/browse/QTBUG-65894
    I think it is rather important but unfortunately it did not receive any attention. I hope you can take a look at it or at least give it a boost.
    Thanks for your hard work and advice on Qt for Android!

  3. Hi BogDan, thanks for the post and all the insights.
    I have messed around with gdb and gdbserver on android recently and found out that run-as apparently does not work as expected on many Samsung devices (https://issuetracker.google.com/issues/37093233#c4
    https://stackoverflow.com/questions/37413667/run-as-could-not-set-capabilities-operation-not-permitted).

    I was not able to use gdb from the command line without starting gdb from the app (like you did until now in Qt creator).
    Does this mean I will be out of luck with the newer Qt Creators too?

    1. BogDan Vatra

      run-as is a must for the new QtCreators.
      If you can’t debug apps using Android Studio you won’t be able to debug them in QtCreator as well.
      The only things you can do are:
      – to contact Samsung and ask them to fix their problem
      – or use an older QtCreator

      The benefits for the other users are way too big to go back to the old implementation…

      1. Thank you for the fast reply. I understand that the benefits outweigh this drawback.
        Samsung is already contacted (since nearly a year now), but nothing happened afaik.
        I will stay with Qt Creator 4.6.0 by now or add code to launch gdbserver in the app (like visualgdb does: https://visualgdb.com/tutorials/android/run-as/ <- I understand this is also the former qt creator way?).
        Thanks again for the insights!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

By continuing to use the site, you agree to the use of cookies. More information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close