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