aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/launch/GdbServerTask.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/launch/GdbServerTask.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/launch/GdbServerTask.java118
1 files changed, 118 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/launch/GdbServerTask.java b/eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/launch/GdbServerTask.java
new file mode 100644
index 000000000..23486ee6f
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/launch/GdbServerTask.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ndk.internal.launch;
+
+import com.android.ddmlib.IDevice;
+import com.android.ddmlib.IShellOutputReceiver;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * The {@link GdbServerTask} launches gdbserver on the given device and attaches it to
+ * provided pid.
+ */
+public class GdbServerTask implements Runnable {
+ private IDevice mDevice;
+ private String mRunAs;
+ private String mSocket;
+ private int mPid;
+ private CountDownLatch mAttachLatch;
+
+ private GdbServerOutputReceiver mOutputReceiver;
+ private Exception mLaunchException;
+
+ private AtomicBoolean mCancelled = new AtomicBoolean(false);
+ private AtomicBoolean mHasCompleted = new AtomicBoolean(false);
+
+ /**
+ * Construct a gdbserver task.
+ * @param device device to run gdbserver on
+ * @param runAsPackage name of the package in which gdbserver resides
+ * @param socketName name of the local socket on which the server will listen
+ * @param pid pid of task to attach to
+ * @param attachLatch latch to notify when gdbserver gets attached to the task
+ */
+ public GdbServerTask(IDevice device, String runAsPackage, String socketName, int pid,
+ CountDownLatch attachLatch) {
+ mDevice = device;
+ mRunAs = runAsPackage;
+ mSocket = socketName;
+ mPid = pid;
+ mAttachLatch = attachLatch;
+
+ mOutputReceiver = new GdbServerOutputReceiver();
+ }
+
+ /**
+ * Runs gdbserver on the device and connects to the given task. If gdbserver manages to
+ * successfully attach itself to the process, then it counts down on its attach latch.
+ */
+ @Override
+ public void run() {
+ // Launch gdbserver on the device.
+ String command = String.format("run-as %s lib/gdbserver +%s --attach %d",
+ mRunAs, mSocket, mPid);
+ try {
+ mDevice.executeShellCommand(command, mOutputReceiver, 0);
+ } catch (Exception e) {
+ mLaunchException = e;
+ }
+ }
+
+ /** Returns any exceptions that might have occurred while launching gdbserver. */
+ public Exception getLaunchException() {
+ return mLaunchException;
+ }
+
+ /** Cancel gdbserver if it is running. */
+ public void setCancelled() {
+ mCancelled.set(true);
+ }
+
+ public String getShellOutput() {
+ return mOutputReceiver.getOutput();
+ }
+
+ private class GdbServerOutputReceiver implements IShellOutputReceiver {
+ private StringBuffer mOutput = new StringBuffer(100);
+
+ @Override
+ public synchronized void addOutput(byte[] data, int offset, int length) {
+ mOutput.append(new String(data, offset, length));
+
+ // notify other threads that gdbserver has attached to the task
+ if (mOutput.toString().contains("Attached")) {
+ mAttachLatch.countDown();
+ }
+ }
+
+ @Override
+ public void flush() {
+ mHasCompleted.set(true);
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return mCancelled.get();
+ }
+
+ public synchronized String getOutput() {
+ return mOutput.toString();
+ }
+ }
+}