diff options
author | hjk <hjk121@nokiamail.com> | 2013-03-08 16:09:08 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-04-05 16:26:31 +0200 |
commit | 06d4c0b2e82019798b199cf2f70f184d8a27e456 (patch) | |
tree | 5f9c47b51fc1277c20e8f52520891af8d70227f2 /src/android/jar/src | |
parent | f5ba2b8a91b3af74470776fabdbd170383e91f57 (diff) |
Android: Implement debugging without relying on shell run-as
This uses explicit handshakes between the application and the
gdbserver start and the host side by using the gdbserver socket
and two files ("ping" file in the application dir, "pong" file
in /data/local/tmp/qt)
The sequence is as follows:
host: adb forward debugsocket :5039
host: adb shell rm pong file
host: adb shell am start
host: loop until ping file appears
app start up: launch gdbserver --multi +debug-socket
app start up: loop until debug socket appear
gdbserver: normal start up including opening debug-socket,
not yet attached to any process
app start up: touch ping file
app start up: loop until pong file appears
host: start gdb
host: gdb: set up binary, breakpoints, path etc
host: gdb: target extended-remote :5039
gdbserver: accepts connection from gdb
host: gdb: attach <application-pid>
gdbserver: attaches to the application
and stops it
app start up: stopped now (it is still waiting for
the pong anyway)
host: gdb: continue
gdbserver: resumes application
app start up: resumed (still waiting for the pong)
host: write pong file
app start up: java code continues now, the process
is already fully under control
of gdbserver. Breakpoints are set etc,
we are before main.
app start up: native code launches
Change-Id: Iaa28b8664dbebc39022d1be7ff5533c52ce39715
Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>
Reviewed-by: Daniel Teske <daniel.teske@digia.com>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Diffstat (limited to 'src/android/jar/src')
-rw-r--r-- | src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java | 122 |
1 files changed, 107 insertions, 15 deletions
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index c1fe8920f5..dedfc9d417 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -43,6 +43,7 @@ package org.qtproject.qt5.android; import java.io.File; +import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.Method; import java.util.ArrayList; @@ -368,6 +369,11 @@ public class QtActivityDelegate return true; } + public void debugLog(String msg) + { + Log.i(QtNative.QtTAG, "DEBUGGER: " + msg); + } + public boolean startApplication() { // start application @@ -414,25 +420,111 @@ public class QtActivityDelegate &&*/ extras != null && extras.containsKey("debug_ping") && extras.getString("debug_ping").equals("true")) { - String packagePath = - m_activity.getPackageManager().getApplicationInfo(m_activity.getPackageName(), - PackageManager.GET_CONFIGURATIONS).dataDir + "/"; - String debugPing = packagePath + "debug_ping"; - int i = 0; - while (true) { - ++i; - Log.i(QtNative.QtTAG, "DEBUGGER: WAITING FOR PING AT " + debugPing + ", ATTEMPT " + i); - File file = new File(debugPing); - if (file.exists()) { - file.delete(); - break; + try { + debugLog("extra parameters: " + extras); + String packageName = m_activity.getPackageName(); + String pingFile = extras.getString("ping_file"); + String pongFile = extras.getString("pong_file"); + String gdbserverSocket = extras.getString("gdbserver_socket"); + String gdbserverCommand = extras.getString("gdbserver_command"); + boolean usePing = pingFile != null; + boolean usePong = pongFile != null; + boolean useSocket = gdbserverSocket != null; + int napTime = 200; // milliseconds between file accesses + int timeOut = 30000; // ms until we give up on ping and pong + int maxAttempts = timeOut / napTime; + + if (usePing) { + debugLog("removing ping file " + pingFile); + File ping = new File(pingFile); + if (ping.exists()) { + if (!ping.delete()) + debugLog("ping file cannot be deleted"); } - Thread.sleep(1000); } - Log.i(QtNative.QtTAG, "DEBUGGER: GOT PING " + debugPing); - } + if (usePong) { + debugLog("removing pong file " + pongFile); + File pong = new File(pongFile); + if (pong.exists()) { + if (!pong.delete()) + debugLog("pong file cannot be deleted"); + } + } + + debugLog("starting " + gdbserverCommand); + m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand); + debugLog("gdbserver started"); + + if (useSocket) { + 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 socket"); + return false; + } + + debugLog("socket ok"); + } else { + debugLog("socket not used"); + } + + if (usePing) { + // Tell we are ready. + debugLog("writing ping at " + pingFile); + FileWriter writer = new FileWriter(pingFile); + writer.write("" + android.os.Process.myPid()); + writer.close(); + File file = new File(pingFile); + file.setReadable(true, false); + file.setWritable(true, false); + file.setExecutable(true, false); + debugLog("wrote ping"); + } else { + debugLog("ping not requested"); + } + + // Wait until other side is ready. + if (usePong) { + int i; + for (i = 0; i < maxAttempts; ++i) { + debugLog("waiting for pong at " + pongFile + ", attempt " + i); + File file = new File(pongFile); + if (file.exists()) { + file.delete(); + break; + } + debugLog("go to sleep"); + Thread.sleep(napTime); + } + + if (i == maxAttempts) { + debugLog("time out when waiting for pong file"); + return false; + } + debugLog("got pong " + pongFile); + } else { + debugLog("pong not requested"); + } + + } catch (IOException ioe) { + Log.e(QtNative.QtTAG,"Can't start debugger" + ioe.getMessage()); + } catch (SecurityException se) { + Log.e(QtNative.QtTAG,"Can't start debugger" + se.getMessage()); + } + } if (/*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0 &&*/ extras != null |