1 /* ThreadReferenceCommandSet.java -- class to implement the ThreadReference 2 Command Set Copyright (C) 2005, 2007 Free Software Foundation 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 terms of your choice, provided that you also meet, for each linked 32 independent module, the terms and conditions of the license of that 33 module. An independent module is a module which is not derived from 34 or based on this library. If you modify this library, you may extend 35 this exception to your version of the library, but you are not 36 obligated to do so. If you do not wish to do so, delete this 37 exception statement from your version. */ 38 39 40 package gnu.classpath.jdwp.processor; 41 42 import gnu.classpath.jdwp.JdwpConstants; 43 import gnu.classpath.jdwp.VMFrame; 44 import gnu.classpath.jdwp.VMVirtualMachine; 45 import gnu.classpath.jdwp.exception.JdwpException; 46 import gnu.classpath.jdwp.exception.JdwpInternalErrorException; 47 import gnu.classpath.jdwp.exception.NotImplementedException; 48 import gnu.classpath.jdwp.id.ObjectId; 49 import gnu.classpath.jdwp.id.ThreadId; 50 import gnu.classpath.jdwp.util.JdwpString; 51 import gnu.classpath.jdwp.util.Location; 52 53 import java.io.DataOutputStream; 54 import java.io.IOException; 55 import java.nio.ByteBuffer; 56 import java.util.ArrayList; 57 58 /** 59 * A class representing the ThreadReference Command Set. 60 * 61 * @author Aaron Luchko <aluchko@redhat.com> 62 */ 63 public class ThreadReferenceCommandSet 64 extends CommandSet 65 { runCommand(ByteBuffer bb, DataOutputStream os, byte command)66 public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) 67 throws JdwpException 68 { 69 try 70 { 71 switch (command) 72 { 73 case JdwpConstants.CommandSet.ThreadReference.NAME: 74 executeName(bb, os); 75 break; 76 case JdwpConstants.CommandSet.ThreadReference.SUSPEND: 77 executeSuspend(bb, os); 78 break; 79 case JdwpConstants.CommandSet.ThreadReference.RESUME: 80 executeResume(bb, os); 81 break; 82 case JdwpConstants.CommandSet.ThreadReference.STATUS: 83 executeStatus(bb, os); 84 break; 85 case JdwpConstants.CommandSet.ThreadReference.THREAD_GROUP: 86 executeThreadGroup(bb, os); 87 break; 88 case JdwpConstants.CommandSet.ThreadReference.FRAMES: 89 executeFrames(bb, os); 90 break; 91 case JdwpConstants.CommandSet.ThreadReference.FRAME_COUNT: 92 executeFrameCount(bb, os); 93 break; 94 case JdwpConstants.CommandSet.ThreadReference.OWNED_MONITORS: 95 executeOwnedMonitors(bb, os); 96 break; 97 case JdwpConstants.CommandSet.ThreadReference.CURRENT_CONTENDED_MONITOR: 98 executeCurrentContendedMonitor(bb, os); 99 break; 100 case JdwpConstants.CommandSet.ThreadReference.STOP: 101 executeStop(bb, os); 102 break; 103 case JdwpConstants.CommandSet.ThreadReference.INTERRUPT: 104 executeInterrupt(bb, os); 105 break; 106 case JdwpConstants.CommandSet.ThreadReference.SUSPEND_COUNT: 107 executeSuspendCount(bb, os); 108 break; 109 default: 110 throw new NotImplementedException("Command " + command + 111 " not found in Thread Reference Command Set."); 112 } 113 } 114 catch (IOException ex) 115 { 116 // The DataOutputStream we're using isn't talking to a socket at all 117 // So if we throw an IOException we're in serious trouble 118 throw new JdwpInternalErrorException(ex); 119 } 120 121 return false; 122 } 123 executeName(ByteBuffer bb, DataOutputStream os)124 private void executeName(ByteBuffer bb, DataOutputStream os) 125 throws JdwpException, IOException 126 { 127 ThreadId tid = (ThreadId) idMan.readObjectId(bb); 128 Thread thread = tid.getThread(); 129 JdwpString.writeString(os, thread.getName()); 130 } 131 executeSuspend(ByteBuffer bb, DataOutputStream os)132 private void executeSuspend(ByteBuffer bb, DataOutputStream os) 133 throws JdwpException, IOException 134 { 135 ThreadId tid = (ThreadId) idMan.readObjectId(bb); 136 Thread thread = tid.getThread(); 137 VMVirtualMachine.suspendThread(thread); 138 } 139 executeResume(ByteBuffer bb, DataOutputStream os)140 private void executeResume(ByteBuffer bb, DataOutputStream os) 141 throws JdwpException, IOException 142 { 143 ThreadId tid = (ThreadId) idMan.readObjectId(bb); 144 Thread thread = tid.getThread(); 145 VMVirtualMachine.resumeThread(thread); 146 } 147 executeStatus(ByteBuffer bb, DataOutputStream os)148 private void executeStatus(ByteBuffer bb, DataOutputStream os) 149 throws JdwpException, IOException 150 { 151 ThreadId tid = (ThreadId) idMan.readObjectId(bb); 152 Thread thread = tid.getThread(); 153 int threadStatus = VMVirtualMachine.getThreadStatus(thread); 154 // There's only one possible SuspendStatus... 155 int suspendStatus = JdwpConstants.SuspendStatus.SUSPENDED; 156 157 os.writeInt(threadStatus); 158 os.writeInt(suspendStatus); 159 } 160 executeThreadGroup(ByteBuffer bb, DataOutputStream os)161 private void executeThreadGroup(ByteBuffer bb, DataOutputStream os) 162 throws JdwpException, IOException 163 { 164 ThreadId tid = (ThreadId) idMan.readObjectId(bb); 165 Thread thread = tid.getThread(); 166 ThreadGroup group = thread.getThreadGroup(); 167 ObjectId groupId = idMan.getObjectId(group); 168 groupId.write(os); 169 } 170 executeFrames(ByteBuffer bb, DataOutputStream os)171 private void executeFrames(ByteBuffer bb, DataOutputStream os) 172 throws JdwpException, IOException 173 { 174 ThreadId tid = (ThreadId) idMan.readObjectId(bb); 175 Thread thread = tid.getThread(); 176 int startFrame = bb.getInt(); 177 int length = bb.getInt(); 178 179 ArrayList frames = VMVirtualMachine.getFrames(thread, startFrame, length); 180 os.writeInt(frames.size()); 181 for (int i = 0; i < frames.size(); i++) 182 { 183 VMFrame frame = (VMFrame) frames.get(i); 184 os.writeLong(frame.getId()); 185 Location loc = frame.getLocation(); 186 loc.write(os); 187 } 188 } 189 executeFrameCount(ByteBuffer bb, DataOutputStream os)190 private void executeFrameCount(ByteBuffer bb, DataOutputStream os) 191 throws JdwpException, IOException 192 { 193 ThreadId tid = (ThreadId) idMan.readObjectId(bb); 194 Thread thread = tid.getThread(); 195 196 int frameCount = VMVirtualMachine.getFrameCount(thread); 197 os.writeInt(frameCount); 198 } 199 executeOwnedMonitors(ByteBuffer bb, DataOutputStream os)200 private void executeOwnedMonitors(ByteBuffer bb, DataOutputStream os) 201 throws JdwpException, IOException 202 { 203 if (!VMVirtualMachine.canGetOwnedMonitorInfo) 204 { 205 String msg = "getting owned monitors is not supported"; 206 throw new NotImplementedException(msg); 207 } 208 209 ThreadId tid = (ThreadId) idMan.readObjectId(bb); 210 Thread thread = tid.getThread(); 211 Object[] monitors = VMVirtualMachine.getOwnedMonitors(thread); 212 213 os.write(monitors.length); 214 for (int i = 0; i < monitors.length; ++i) 215 { 216 ObjectId id = idMan.getObjectId(monitors[i]); 217 id.writeTagged(os); 218 } 219 } 220 executeCurrentContendedMonitor(ByteBuffer bb, DataOutputStream os)221 private void executeCurrentContendedMonitor(ByteBuffer bb, 222 DataOutputStream os) 223 throws JdwpException, IOException 224 { 225 if (!VMVirtualMachine.canGetCurrentContendedMonitor) 226 { 227 String msg = "getting current contended monitor is not supported"; 228 throw new NotImplementedException(msg); 229 } 230 231 ThreadId tid = (ThreadId) idMan.readObjectId(bb); 232 Thread thread = tid.getThread(); 233 234 Object monitor = VMVirtualMachine.getCurrentContendedMonitor(thread); 235 ObjectId id = idMan.getObjectId(monitor); 236 id.writeTagged(os); 237 } 238 executeStop(ByteBuffer bb, DataOutputStream os)239 private void executeStop(ByteBuffer bb, DataOutputStream os) 240 throws JdwpException, IOException 241 { 242 ThreadId tid = (ThreadId) idMan.readObjectId(bb); 243 Thread thread = tid.getThread(); 244 ObjectId exception = idMan.readObjectId(bb); 245 Throwable throwable = (Throwable) exception.getObject(); 246 thread.stop (throwable); 247 } 248 executeInterrupt(ByteBuffer bb, DataOutputStream os)249 private void executeInterrupt(ByteBuffer bb, DataOutputStream os) 250 throws JdwpException, IOException 251 { 252 ThreadId tid = (ThreadId) idMan.readObjectId(bb); 253 Thread thread = tid.getThread(); 254 thread.interrupt(); 255 } 256 executeSuspendCount(ByteBuffer bb, DataOutputStream os)257 private void executeSuspendCount(ByteBuffer bb, DataOutputStream os) 258 throws JdwpException, IOException 259 { 260 ThreadId tid = (ThreadId) idMan.readObjectId(bb); 261 Thread thread = tid.getThread(); 262 int suspendCount = VMVirtualMachine.getSuspendCount(thread); 263 os.writeInt(suspendCount); 264 } 265 } 266