summaryrefslogtreecommitdiffstats
path: root/src/android/jar
diff options
context:
space:
mode:
authorhjk <hjk121@nokiamail.com>2013-03-08 16:09:08 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-04-05 16:26:31 +0200
commit06d4c0b2e82019798b199cf2f70f184d8a27e456 (patch)
tree5f9c47b51fc1277c20e8f52520891af8d70227f2 /src/android/jar
parentf5ba2b8a91b3af74470776fabdbd170383e91f57 (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')
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java122
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