Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Rennie2013-01-09 17:02:04 +0000
committerMike Rennie2013-01-09 17:02:04 +0000
commitd2430fb08faa4cdaa1fb4b739b5ac14ba64f8643 (patch)
tree226891a7dc7a617f0fe77aca4fa998bb61eaa6d0
parent81269a7eaf7d63bc74cfec4dbccad48c0eabd387 (diff)
downloadeclipse.jdt.debug-mrennie/bug392893.tar.gz
eclipse.jdt.debug-mrennie/bug392893.tar.xz
eclipse.jdt.debug-mrennie/bug392893.zip
Bug 392893 - Debug view: allow to stop selected thread(s) - completemrennie/bug392893
feature
-rw-r--r--org.eclipse.jdt.debug.ui/plugin.properties5
-rw-r--r--org.eclipse.jdt.debug.ui/plugin.xml69
-rw-r--r--org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JDIPropertyTester.java31
-rw-r--r--org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/handlers/InterruptThreadsHandler.java16
-rw-r--r--org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/handlers/StopThreadsHandler.java69
-rw-r--r--org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ThreadReferenceImpl.java4
6 files changed, 117 insertions, 77 deletions
diff --git a/org.eclipse.jdt.debug.ui/plugin.properties b/org.eclipse.jdt.debug.ui/plugin.properties
index 0648d003b..4d14d8c35 100644
--- a/org.eclipse.jdt.debug.ui/plugin.properties
+++ b/org.eclipse.jdt.debug.ui/plugin.properties
@@ -314,4 +314,9 @@ InterruptThreadCommand.description = Interrupts the selected Java thread in the
StopThreadCommand.description = Stops the selected Java thread in the Debug view
StopThreadCommand.name = Stop Thread
StopInterruptMenu.label = Stop/Interrupt
+StopInterruptMenu.tooltip = Stop or interrupt the selected threadInterruptThreadCommand.label = Interrupt Thread
+InterruptThreadCommand.description = Interrupts the selected Java thread in the Debug view
+StopThreadCommand.description = Stops the selected Java thread in the Debug view
+StopThreadCommand.name = Stop Thread
+StopInterruptMenu.label = Stop/Interrupt
StopInterruptMenu.tooltip = Stop or interrupt the selected thread \ No newline at end of file
diff --git a/org.eclipse.jdt.debug.ui/plugin.xml b/org.eclipse.jdt.debug.ui/plugin.xml
index 0a310e670..636b54bbf 100644
--- a/org.eclipse.jdt.debug.ui/plugin.xml
+++ b/org.eclipse.jdt.debug.ui/plugin.xml
@@ -48,6 +48,33 @@
</editor>
</extension>
<extension
+ point="org.eclipse.ui.handlers">
+ <handler
+ class="org.eclipse.jdt.internal.debug.ui.handlers.StopThreadsHandler"
+ commandId="org.eclipse.jdt.debug.ui.stop.thread">
+ <activeWhen>
+ <with
+ variable="activePartId">
+ <equals
+ value="org.eclipse.debug.ui.DebugView">
+ </equals>
+ </with>
+ </activeWhen>
+ </handler>
+ <handler
+ class="org.eclipse.jdt.internal.debug.ui.handlers.InterruptThreadsHandler"
+ commandId="org.eclipse.jdt.debug.ui.interrupt.thread">
+ <activeWhen>
+ <with
+ variable="activePartId">
+ <equals
+ value="org.eclipse.debug.ui.DebugView">
+ </equals>
+ </with>
+ </activeWhen>
+ </handler>
+ </extension>
+ <extension
point="org.eclipse.ui.editorActions">
<editorContribution
targetID="org.eclipse.jdt.ui.CompilationUnitEditor"
@@ -429,7 +456,7 @@
</command>
</menuContribution>
<menuContribution
- locationURI="popup:org.eclipse.debug.ui.DebugView?endof=emptyThreadGroup">
+ locationURI="popup:org.eclipse.debug.ui.DebugView?endof=threadGroup">
<menu
id="stop_and_interrupt_submenu"
label="%StopInterruptMenu.label"
@@ -441,18 +468,6 @@
icon="$nl$/icons/full/obj16/thread_obj.gif"
label="%InterruptThreadCommand.label"
style="push">
- <visibleWhen>
- <with
- variable="selection">
- <count
- value="1">
- </count>
- <test
- property="org.eclipse.jdt.debug.ui.isJavaThread"
- value="true">
- </test>
- </with>
- </visibleWhen>
</command>
<command
commandId="org.eclipse.jdt.debug.ui.stop.thread"
@@ -461,19 +476,17 @@
label="%StopThreadCommand.name"
style="push"
tooltip="%StopThreadCommand.description">
- <visibleWhen>
- <with
- variable="selection">
- <count
- value="1">
- </count>
- <test
- property="org.eclipse.jdt.debug.ui.isJavaThreadRunning"
- value="false">
- </test>
- </with>
- </visibleWhen>
</command>
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="activeMenuSelection">
+ <test
+ property="org.eclipse.jdt.debug.ui.isJavaThreadsRunning"
+ value="true">
+ </test>
+ </with>
+ </visibleWhen>
</menu>
</menuContribution>
</extension>
@@ -2750,7 +2763,6 @@ M4 = Platform-specific fourth key
</command>
<command
categoryId="org.eclipse.debug.ui.category.run"
- defaultHandler="org.eclipse.jdt.internal.debug.ui.handlers.InterruptThreadsHandler"
description="%InterruptThreadCommand.description"
helpContextId="interrupt_thread_context_id"
id="org.eclipse.jdt.debug.ui.interrupt.thread"
@@ -2758,7 +2770,6 @@ M4 = Platform-specific fourth key
</command>
<command
categoryId="org.eclipse.debug.ui.category.run"
- defaultHandler="org.eclipse.jdt.internal.debug.ui.handlers.StopThreadsHandler"
description="%StopThreadCommand.description"
helpContextId="stop_thread_context_id"
id="org.eclipse.jdt.debug.ui.stop.thread"
@@ -3728,9 +3739,9 @@ M4 = Platform-specific fourth key
point="org.eclipse.core.expressions.propertyTesters">
<propertyTester
class="org.eclipse.jdt.internal.debug.ui.actions.JDIPropertyTester"
- id="org.eclipse.jdt.debug.ui.propertyTeszter"
+ id="org.eclipse.jdt.debug.ui.propertyTester"
namespace="org.eclipse.jdt.debug.ui"
- properties="isJavaThread,isJavaThreadRunning"
+ properties="isJavaThreadsRunning"
type="java.lang.Object">
</propertyTester>
</extension>
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JDIPropertyTester.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JDIPropertyTester.java
index 433c54f49..03e1795f4 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JDIPropertyTester.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JDIPropertyTester.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.actions;
+import java.util.Iterator;
+
import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.jdt.internal.debug.core.model.JDIThread;
import org.eclipse.jface.viewers.IStructuredSelection;
@@ -21,21 +23,30 @@ import org.eclipse.jface.viewers.IStructuredSelection;
*/
public class JDIPropertyTester extends PropertyTester {
- public static final String IS_JAVA_THREAD = "isJavaThread"; //$NON-NLS-1$
- public static final String IS_JAVA_THREAD_RUNNING = "isJavaThreadRunning"; //$NON-NLS-1$
+ public static final String IS_JAVA_THREADS_RUNNING = "isJavaThreadsRunning"; //$NON-NLS-1$
/* (non-Javadoc)
* @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object)
*/
public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
- if(IS_JAVA_THREAD.equals(property)) {
- return ((IStructuredSelection)receiver).getFirstElement() instanceof JDIThread;
- }
- if(IS_JAVA_THREAD_RUNNING.equals(property)) {
- Object o = ((IStructuredSelection) receiver).getFirstElement();
- if(o instanceof JDIThread) {
- JDIThread thread = (JDIThread) o;
- return thread.isSuspended();
+ if(IS_JAVA_THREADS_RUNNING.equals(property) && receiver instanceof IStructuredSelection) {
+ if(receiver instanceof IStructuredSelection) {
+ IStructuredSelection selection = (IStructuredSelection) receiver;
+ boolean running = true;
+ for (Iterator<?> i = selection.iterator(); i.hasNext();) {
+ Object o = i.next();
+ if(o instanceof JDIThread) {
+ JDIThread thread = (JDIThread) o;
+ running &= !thread.isSuspended();
+ if(!running) {
+ return false;
+ }
+ }
+ else {
+ return false;
+ }
+ }
+ return running;
}
}
return false;
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/handlers/InterruptThreadsHandler.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/handlers/InterruptThreadsHandler.java
index e53491511..611e7233c 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/handlers/InterruptThreadsHandler.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/handlers/InterruptThreadsHandler.java
@@ -15,7 +15,9 @@ import java.util.Iterator;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
+import org.eclipse.jdt.internal.debug.core.model.JDIStackFrame;
import org.eclipse.jdt.internal.debug.core.model.JDIThread;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jface.viewers.IStructuredSelection;
@@ -34,9 +36,19 @@ public class InterruptThreadsHandler extends AbstractHandler {
public Object execute(ExecutionEvent event) throws ExecutionException {
IStructuredSelection sel = (IStructuredSelection) HandlerUtil.getCurrentSelection(event);
if(sel != null && !sel.isEmpty()) {
- for(Iterator<JDIThread> i = sel.iterator(); i.hasNext();) {
+ for(Iterator<?> i = sel.iterator(); i.hasNext();) {
try {
- i.next().interrupt();
+ Object o = i.next();
+ if(o instanceof JDIThread) {
+ JDIThread thread = (JDIThread) o;
+ thread.interrupt();
+ thread.fireChangeEvent(DebugEvent.STATE);
+ }
+ else if(o instanceof JDIStackFrame) {
+ JDIThread thread = (JDIThread) ((JDIStackFrame)o).getThread();
+ thread.interrupt();
+ thread.fireChangeEvent(DebugEvent.STATE);
+ }
}
catch(DebugException de) {
JDIDebugUIPlugin.log(de);
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/handlers/StopThreadsHandler.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/handlers/StopThreadsHandler.java
index 5a95d2237..ce120cc2d 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/handlers/StopThreadsHandler.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/handlers/StopThreadsHandler.java
@@ -10,28 +10,24 @@
*******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.handlers;
-import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.jdi.internal.ThreadReferenceImpl;
+import org.eclipse.jdi.internal.VirtualMachineImpl;
+import org.eclipse.jdt.debug.core.IJavaObject;
+import org.eclipse.jdt.internal.debug.core.model.JDIClassObjectValue;
import org.eclipse.jdt.internal.debug.core.model.JDIThread;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.handlers.HandlerUtil;
-import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.ClassType;
-import com.sun.jdi.IncompatibleThreadStateException;
-import com.sun.jdi.InvalidTypeException;
-import com.sun.jdi.InvocationException;
-import com.sun.jdi.Method;
-import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
-import com.sun.jdi.Value;
-import com.sun.jdi.VirtualMachine;
/**
* Default handler for the Stop Threads command
@@ -49,34 +45,41 @@ public class StopThreadsHandler extends AbstractHandler {
//create the new exception class type once
for(Iterator<JDIThread> i = sel.iterator(); i.hasNext();) {
try {
- JDIThread jdt = i.next();
- VirtualMachine vm = jdt.getJavaDebugTarget().getVM();
- List<ReferenceType> rts = vm.classesByName("java.lang.Throwable"); //$NON-NLS-1$
- ClassType clazz = (ClassType) rts.get(0);
- Method constructor = clazz.concreteMethodByName("<init>", "(Ljava/lang/String;)V"); //$NON-NLS-1$ //$NON-NLS-2$
- List<Value> args = new ArrayList<Value>();
- args.add(vm.mirrorOf(jdt.getModelIdentifier()));
- ObjectReference oref = clazz.newInstance(
- jdt.getUnderlyingThread(),
- constructor,
- args,
- ClassType.INVOKE_SINGLE_THREADED);
- jdt.getUnderlyingThread().stop(oref);
+ JDIThread thread = i.next();
+ IJavaObject ex = getException(thread);
+ if(ex != null) {
+ thread.stop(ex);
+ }
}
- catch (InvalidTypeException e) {
- JDIDebugUIPlugin.log(e);
- }
- catch (ClassNotLoadedException e) {
- JDIDebugUIPlugin.log(e);
- }
- catch (IncompatibleThreadStateException e) {
- JDIDebugUIPlugin.log(e);
- }
- catch (InvocationException e) {
- JDIDebugUIPlugin.log(e);
+ catch(DebugException de) {
+ JDIDebugUIPlugin.log(de);
}
}
}
return null;
}
+
+ /**
+ * Compute the exception class to return with the stop. First try to compute <code>java.lang.ThreadDeath</code> and if
+ * that class has not been loaded use <code>java.lang.Throwable</code>.
+ * <br><br>
+ * We could try loading the type in the remote VM, but it would only work if we were trying to stop a suspended thread, or if we had
+ * a suspended thread to send the load class message on.
+ *
+ * @param thread the thread we want to stop
+ * @return the {@link IJavaObject} representing the {@link Throwable} we want to pass to the stop call
+ */
+ IJavaObject getException(JDIThread thread) {
+ ThreadReferenceImpl threadref = (ThreadReferenceImpl) thread.getUnderlyingThread();
+ VirtualMachineImpl vm = threadref.virtualMachineImpl();
+ List<ReferenceType> refs = vm.classesByName("java.lang.ThreadDeath"); //$NON-NLS-1$
+ if(refs.isEmpty()) {
+ refs = vm.classesByName("java.lang.Throwable"); //$NON-NLS-1$
+ }
+ if(!refs.isEmpty()) {
+ ClassType clazz = (ClassType) refs.get(0);
+ return new JDIClassObjectValue(thread.getJavaDebugTarget(), clazz.classObject());
+ }
+ return null;
+ }
}
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ThreadReferenceImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ThreadReferenceImpl.java
index f44c9331e..b1cb4835e 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ThreadReferenceImpl.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ThreadReferenceImpl.java
@@ -516,9 +516,7 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl implements ThreadRe
}
}
- /**
- * Stops this thread with an asynchronous exception.
- *
+ /* (non-Javadoc)
* @see com.sun.jdi.ThreadReference#stop(com.sun.jdi.ObjectReference)
*/
public void stop(ObjectReference throwable) throws InvalidTypeException {

Back to the top