diff options
author | Mike Rennie | 2013-01-09 17:02:04 +0000 |
---|---|---|
committer | Mike Rennie | 2013-01-09 17:02:04 +0000 |
commit | d2430fb08faa4cdaa1fb4b739b5ac14ba64f8643 (patch) | |
tree | 226891a7dc7a617f0fe77aca4fa998bb61eaa6d0 | |
parent | 81269a7eaf7d63bc74cfec4dbccad48c0eabd387 (diff) | |
download | eclipse.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
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 { |