1

I've been developing an Android app with Qt for months now. I used to be able to debug with no problems in Qt Creator, but now the debugger fails to start. The deploy process works -- the app can be started from the device GUI.

Sample projects build and can be debugged normally.

I'm using NDK 10e because anything later confuses Creator, which tells me that the Qt people aren't using a recent build.

I have the latest version of the SDK, developing on OS X.

The Debugger Log window ends with this:

~"Loaded symbols for /Users/tjdaniel/projects/qt/5.6.0/plugins/sensors/libqtsensors_android.so\n"
~"Reading symbols from /Users/tjdaniel/projects/build/localization/android/Debug/liblocalization.so..."
sReading /Users/tjdaniel/projects/build/localization/android/Debug/liblocalization.so......

dHANDLE GDB ERROR: The gdb process was ended forcefully
dGDB PROCESS FINISHED, status 1, exit code 11
dNOTE: ENGINE ILL ******

And here is the output of adb logcat:

W/linker  (12790): libqtforandroid.so: unused DT entry: type 0x1d arg 0x8d9a
W/linker  (12790): Unsupported flags DT_FLAGS_1=0x81
I/Qt      (12790): qt start
W/linker  (12790): libqandroidbearer.so: unused DT entry: type 0x1d arg 0x174f
W/linker  (12790): Unsupported flags DT_FLAGS_1=0x81
W/linker  (12790): libqtmedia_android.so: unused DT entry: type 0x1d arg 0x51da
W/linker  (12790): Unsupported flags DT_FLAGS_1=0x81
W/linker  (12790): libqtsensors_android.so: unused DT entry: type 0x1d arg 0x1076
W/linker  (12790): Unsupported flags DT_FLAGS_1=0x81
I/Qt      (12790): Sensors start
W/linker  (12790): liblocalization.so: unused DT entry: type 0x1d arg 0x29f5f4
D/        (12790): (null):0 ((null)): QML debugging is enabled. Only use this in a safe environment.
I/Qt JAVA (12790): DEBUGGER: extra parameters: Bundle[{debug_ping=true, gdbserver_socket=/data/data/org.qtproject.example.localization/debug-socket, qml_debug=true, gdbserver_command=/data/data/org.qtproject.example.localization/lib/libgdbserver.so --multi +/data/data/org.qtproject.example.localization/debug-socket, qmljsdebugger=port:56956,block,services:DebugMessages,QmlDebugger,V8Debugger,QmlInspector, ping_socket=org.qtproject.example.localization.ping_pong_socket}]
I/Qt JAVA (12790): DEBUGGER: removing gdb socket /data/data/org.qtproject.example.localization/debug-socket
I/Qt JAVA (12790): DEBUGGER: starting /data/data/org.qtproject.example.localization/lib/libgdbserver.so --multi +/data/data/org.qtproject.example.localization/debug-socket
I/Qt JAVA (12790): DEBUGGER: gdbserver started
I/Qt JAVA (12790): DEBUGGER: waiting for socket at /data/data/org.qtproject.example.localization/debug-socket, attempt 0
I/Qt JAVA (12790): DEBUGGER: waiting for socket at /data/data/org.qtproject.example.localization/debug-socket, attempt 1
I/Qt JAVA (12790): DEBUGGER: socket ok
I/Qt JAVA (12790): DEBUGGER: Waiting for debug socket connect
I/Qt JAVA (12790): DEBUGGER: go to sleep
I/Qt JAVA (12790): DEBUGGER: Waiting for debug socket connect
I/Qt JAVA (12790): DEBUGGER: go to sleep
I/Qt JAVA (12790): DEBUGGER: Waiting for debug socket connect
I/Qt JAVA (12790): DEBUGGER: go to sleep
I/Qt JAVA (12790): DEBUGGER: Waiting for debug socket connect
I/Qt JAVA (12790): DEBUGGER: go to sleep
I/Qt JAVA (12790): DEBUGGER: Debug socket accepted
I/Qt JAVA (12790): DEBUGGER: Waiting for debug socket connect
I/Qt JAVA (12790): DEBUGGER: go to sleep
I/Qt JAVA (12790): DEBUGGER: Waiting for debug socket connect
I/Qt JAVA (12790): DEBUGGER: go to sleep
I/Qt JAVA (12790): DEBUGGER: Waiting for debug socket connect
I/Qt JAVA (12790): DEBUGGER: go to sleep
I/Qt JAVA (12790): DEBUGGER: Waiting for debug socket connect
I/Qt JAVA (12790): DEBUGGER: go to sleep
I/Qt JAVA (12790): DEBUGGER: Waiting for debug socket connect
I/Qt JAVA (12790): DEBUGGER: go to sleep
I/Qt JAVA (12790): DEBUGGER: Waiting for debug socket connect
I/Qt JAVA (12790): DEBUGGER: go to sleep
I/Qt JAVA (12790): DEBUGGER: Waiting for debug socket connect
I/Qt JAVA (12790): DEBUGGER: go to sleep
I/Qt JAVA (12790): DEBUGGER: Waiting for debug socket connect
I/Qt JAVA (12790): DEBUGGER: go to sleep
I/ConfigService( 1968): onDestroy
W/ActivityManager(  845): Launch timeout has expired, giving up wake lock!

Any advice on how to debug this?? Not being able to use the debugger is killing me. I've wiped and reinstalled everything related to Qt.. no luck.

Tyler Daniel
  • 656
  • 6
  • 15

3 Answers3

0

I had the same problem and it was than the SDK tools used was not good support by QT. After install the 25.2.5 tools, like says here it worked.

mabg
  • 1,894
  • 21
  • 28
0

I had the same issue, and as of today, the only way I found was to set the Target android SDK to API 23 (Android 6) or less in your AndroidManifest.xml

xalioth
  • 1
  • 2
0

I had the same issue XD:

  1. Ensure both sides (this App and IDE) are NOT blocked by any firewall.
  2. Ensure your app will not exit until IDE gets connected to GNU debug server

Below is stand-alone version of Qt debug server source (xd/DebugServer.java):

package xd;

//beaware: before call to "xd.DebugServer.start();" Gdb Server:
//  Ensure all native libraries you want debug break in are loaded
//  just add to class that calls "start" static initalizer sample:
//      static { System.loadLibrary("tun2http"); } //this may load "libs/armeabi-v7a/libtun2http.so"
//  Ensure both sides (this App and IDE) are NOT blocked by any firewall
//
//you can ignore signals using below (but may need to change SIG33):
//handle SIG33 nostop noprint noignore pass

import android.util.Log;
import android.content.pm.PackageManager;
import android.content.pm.ApplicationInfo;
import android.net.LocalServerSocket;

import java.io.File;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.DataOutputStream;

public class DebugServer {
    public static final String TAG = "XD_GDB"; // string used for Log.x (the colon helps cut out false positives)
    private static Process m_debuggerProcess = null; // debugger process

    private static void debugLog(String msg) {
        Log.i(TAG, msg);
    }

    //do not use this or IDE will fail to connect to debug server
    public static String flushLog() {
        try {
            String command = "logcat -d";

            Process process = Runtime.getRuntime().exec(command);
            BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(process.getInputStream()));
            StringBuilder log=new StringBuilder();
            String line = "";
            while ((line = bufferedReader.readLine()) != null) {
                log.append(line + System.lineSeparator());
            }
            //process.waitFor();
            bufferedReader.close();
            return log.toString();
        } catch (IOException e) {
             // Handle Exception
        }
        return "";
    }

    private static class DebugWaitRunnable implements Runnable {

        public DebugWaitRunnable(String pingPongSocket) throws  IOException {
            socket = new LocalServerSocket(pingPongSocket);
        }

        public boolean wasFailure;
        private LocalServerSocket socket;

        public void run() {
            final int napTime = 200; // milliseconds between file accesses
            final int timeOut = 5000; // ms until we give up on ping and pong
            final int maxAttempts = timeOut / napTime;

            try {
                android.net.LocalSocket connectionFromClient = socket.accept();
                debugLog("Debug socket accepted");
                BufferedReader inFromClient =
                        new BufferedReader(new InputStreamReader(connectionFromClient.getInputStream()));
                DataOutputStream outToClient = new DataOutputStream(connectionFromClient.getOutputStream());
                outToClient.writeBytes("" + android.os.Process.myPid());

                for (int i = 0; i < maxAttempts; i++) {
                    String clientData = inFromClient.readLine();
                    debugLog("Incoming socket " + clientData);
                    if (!clientData.isEmpty())
                        break;

                    if (connectionFromClient.isClosed()) {
                        wasFailure = true;
                        break;
                    }
                    Thread.sleep(napTime);
                }
            } catch (IOException ioEx) {
                ioEx.printStackTrace();
                wasFailure = true;
                Log.e(TAG,"Can't start debugger" + ioEx.getMessage());
            } catch (InterruptedException interruptEx) {
                wasFailure = true;
                Log.e(TAG,"Can't start debugger" + interruptEx.getMessage());
            }
        }

        public void shutdown() throws IOException
        {
            wasFailure = true;
            try {
                socket.close();
            } catch (IOException ignored) { }
        }
    };

//beaware: before call to "start" Gdb Server:
//  Ensure all native libraries you want debug break in are loaded
//  just add to class that calls "xd.DebugServer.start();" static initalizer sample:
//      static { System.loadLibrary("tun2http"); } //this may load "libs/armeabi-v7a/libtun2http.so"
//  Ensure both sides (this App and IDE) are NOT blocked by any firewall
    public static boolean start(android.app.Activity activity) {
    try {
        //System.loadLibrary("gnustl_shared");

        final int napTime = 200; // milliseconds between file accesses
        final int timeOut = 30000; // ms until we give up on ping and pong
        final int maxAttempts = timeOut / napTime;

        PackageManager pm = activity.getPackageManager();
        ApplicationInfo appInfo = pm.getApplicationInfo(
            activity.getPackageName(), android.content.pm.PackageManager.GET_CONFIGURATIONS
        );

        final String packagePath = appInfo.dataDir + "/";
        //using constant '"/data/data/"' instate of 'appInfo.dataDir+"/"' since that does not work old code was "extras.getString("gdbserver_socket");"
        final String gdbserverSocket = "/data/data/" + appInfo.packageName + "/debug-socket";
        final String gdbserverCommand = packagePath + "lib/libgdbserver.so --multi +" + gdbserverSocket;

        debugLog("removing gdb socket " + gdbserverSocket);
        new File(gdbserverSocket).delete();

        debugLog("starting " + gdbserverCommand);
        m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand);
        debugLog("gdbserver started");

        int i;
        for (i = 0; i < maxAttempts; ++i) {
            debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i);
            File file = new File(gdbserverSocket);
            if (file.exists()) {
                file.setReadable(true, false);
                file.setWritable(true, false);
                file.setExecutable(true, false);
                break;
            }
            Thread.sleep(napTime);
        }

        if (i == maxAttempts) {
            debugLog("time out when waiting for debug socket");
            return false;
        }

        debugLog("socket ok");

        final String pingSocket = appInfo.packageName + ".ping_pong_socket";
        debugLog("pingSocket: " + pingSocket);
        DebugWaitRunnable runnable = new DebugWaitRunnable(pingSocket);
        Thread waitThread = new Thread(runnable);
        waitThread.start();

        debugLog("Waiting for debug socket connect");
        for (i = 0; i < maxAttempts && waitThread.isAlive(); ++i) {
            if(i % 10 == 0)
                debugLog("Waiting attempt: " + i);
            Thread.sleep(napTime);
        }

        if (i == maxAttempts) {
            debugLog("time out when waiting for ping socket");
            runnable.shutdown();
            return false;
        }

        if (runnable.wasFailure) {
            debugLog("Could not connect to debug client");
            return false;
        } else {
            debugLog("Got pid acknowledgment");
        }

        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
    }

    public static void stop(android.app.Activity activity) {
        if (m_debuggerProcess != null)
            m_debuggerProcess.destroy();
        System.exit(0);// FIXME remove it or find a better way
    }
} //class GdbServer
Top-Master
  • 7,611
  • 5
  • 39
  • 71