【问题标题】:How to debug Android/GDB/Qt problems?如何调试 Android/GDB/Qt 问题?
【发布时间】:2016-04-13 08:55:18
【问题描述】:

几个月来,我一直在使用 Qt 开发 Android 应用程序。我以前可以在 Qt Creator 中毫无问题地调试,但现在调试器无法启动。部署过程有效 - 可以从设备 GUI 启动应用程序。

样例工程搭建,可以正常调试。

我正在使用 NDK 10e,因为后来的任何事情都会让 Creator 感到困惑,这告诉我 Qt 人员没有使用最近的构建。

我有最新版本的 SDK,在 OS X 上开发。

调试器日志窗口结束于:

~"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 ******

这是 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!

关于如何调试的任何建议?无法使用调试器正在杀死我。我已经擦除并重新安装了与 Qt 相关的所有内容。不走运。

【问题讨论】:

    标签: android c++ qt debugging android-ndk


    【解决方案1】:

    我也遇到了同样的问题,就是使用的 SDK 工具对 QT 的支持不好。安装 25.2.5 工具后,就像 here 说的那样,它工作了。

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,截至今天,我发现的唯一方法是在您的 AndroidManifest.xml 中将 Target android SDK 设置为 API 23 (Android 6) 或更低

      【讨论】:

        【解决方案3】:

        我遇到了同样的问题 XD:

        1. 确保双方(AppIDE)没有被任何 防火墙。
        2. 确保您的应用在 IDE 连接到 GNU 调试服务器之前不会退出

        以下是单机版Qt调试服务器源码(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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-05-05
          • 2023-04-05
          • 1970-01-01
          • 1970-01-01
          • 2013-11-20
          相关资源
          最近更新 更多