blob: cb1369576f28c56176d1c67fd182d29c5c9f427f [file] [log] [blame]
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * Handle messages from debugger.
19 *
20 * GENERAL NOTE: we're not currently testing the message length for
21 * correctness. This is usually a bad idea, but here we can probably
22 * get away with it so long as the debugger isn't broken. We can
23 * change the "read" macros to use "dataLen" to avoid wandering into
24 * bad territory, and have a single "is dataLen correct" check at the
25 * end of each function. Not needed at this time.
26 */
27
Elliott Hughes872d4ec2011-10-21 17:07:15 -070028#include "jdwp/jdwp_handler.h"
Elliott Hughes872d4ec2011-10-21 17:07:15 -070029
30#include <stdlib.h>
31#include <string.h>
32#include <unistd.h>
33
Elliott Hughesa96836a2013-01-17 12:27:49 -080034#include <string>
35
Elliott Hughes07ed66b2012-12-12 18:34:25 -080036#include "atomic.h"
37#include "base/logging.h"
38#include "base/macros.h"
Elliott Hughese222ee02012-12-13 14:41:43 -080039#include "base/stringprintf.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080040#include "debugger.h"
41#include "jdwp/jdwp_constants.h"
42#include "jdwp/jdwp_event.h"
43#include "jdwp/jdwp_expand_buf.h"
44#include "jdwp/jdwp_priv.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080045
Elliott Hughes872d4ec2011-10-21 17:07:15 -070046namespace art {
47
48namespace JDWP {
49
Elliott Hughesa96836a2013-01-17 12:27:49 -080050static std::string DescribeField(const FieldId& field_id)
51 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
52 return StringPrintf("%#x (%s)", field_id, Dbg::GetFieldName(field_id).c_str());
53}
54
55static std::string DescribeMethod(const MethodId& method_id)
56 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
57 return StringPrintf("%#x (%s)", method_id, Dbg::GetMethodName(method_id).c_str());
58}
59
60static std::string DescribeRefTypeId(const RefTypeId& ref_type_id)
61 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
62 std::string signature("unknown");
63 Dbg::GetSignature(ref_type_id, signature);
64 return StringPrintf("%#llx (%s)", ref_type_id, signature.c_str());
Elliott Hughes872d4ec2011-10-21 17:07:15 -070065}
66
67/*
Elliott Hughes872d4ec2011-10-21 17:07:15 -070068 * Helper function: read a variable-width value from the input buffer.
69 */
Elliott Hughes4993bbc2013-01-10 15:41:25 -080070static uint64_t ReadValue(const uint8_t** pBuf, size_t width) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -070071 uint64_t value = -1;
72 switch (width) {
Elliott Hughesf7c3b662011-10-27 12:04:56 -070073 case 1: value = Read1(pBuf); break;
74 case 2: value = Read2BE(pBuf); break;
75 case 4: value = Read4BE(pBuf); break;
76 case 8: value = Read8BE(pBuf); break;
Elliott Hughes872d4ec2011-10-21 17:07:15 -070077 default: LOG(FATAL) << width; break;
78 }
79 return value;
80}
81
Elliott Hughesa96836a2013-01-17 12:27:49 -080082static int32_t ReadSigned32(const char* what, const uint8_t** pBuf) {
83 int32_t value = static_cast<int32_t>(Read4BE(pBuf));
84 VLOG(jdwp) << " " << what << " " << value;
85 return value;
86}
87
88uint32_t ReadUnsigned32(const char* what, const uint8_t** pBuf) {
89 uint32_t value = Read4BE(pBuf);
90 VLOG(jdwp) << " " << what << " " << value;
91 return value;
92}
93
94static FieldId ReadFieldId(const uint8_t** pBuf) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
95 FieldId id = Read4BE(pBuf);
96 VLOG(jdwp) << " field id " << DescribeField(id);
97 return id;
98}
99
100static MethodId ReadMethodId(const uint8_t** pBuf) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
101 MethodId id = Read4BE(pBuf);
102 VLOG(jdwp) << " method id " << DescribeMethod(id);
103 return id;
104}
105
106static ObjectId ReadObjectId(const char* specific_kind, const uint8_t** pBuf) {
107 ObjectId id = Read8BE(pBuf);
108 VLOG(jdwp) << StringPrintf(" %s id %#llx", specific_kind, id);
109 return id;
110}
111
112static ObjectId ReadArrayId(const uint8_t** pBuf) {
113 return ReadObjectId("array", pBuf);
114}
115
116ObjectId ReadObjectId(const uint8_t** pBuf) {
117 return ReadObjectId("object", pBuf);
118}
119
120static ObjectId ReadThreadId(const uint8_t** pBuf) {
121 return ReadObjectId("thread", pBuf);
122}
123
124static ObjectId ReadThreadGroupId(const uint8_t** pBuf) {
125 return ReadObjectId("thread group", pBuf);
126}
127
128static RefTypeId ReadRefTypeId(const uint8_t** pBuf) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
129 RefTypeId id = Read8BE(pBuf);
130 VLOG(jdwp) << " ref type id " << DescribeRefTypeId(id);
131 return id;
132}
133
134static FrameId ReadFrameId(const uint8_t** pBuf) {
135 FrameId id = Read8BE(pBuf);
136 VLOG(jdwp) << " frame id " << id;
137 return id;
138}
139
140static JdwpTag ReadTag(const uint8_t** pBuf) {
141 JdwpTag tag = static_cast<JdwpTag>(Read1(pBuf));
142 VLOG(jdwp) << " tag " << tag;
143 return tag;
144}
145
146static JdwpTypeTag ReadTypeTag(const uint8_t** pBuf) {
147 JdwpTypeTag tag = static_cast<JdwpTypeTag>(Read1(pBuf));
148 VLOG(jdwp) << " type tag " << tag;
149 return tag;
150}
151
152static JdwpLocation ReadLocation(const uint8_t** pBuf) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
153 JdwpLocation location;
154 memset(&location, 0, sizeof(location)); // Allows memcmp(3) later.
155 location.type_tag = ReadTypeTag(pBuf);
156 location.class_id = ReadObjectId(pBuf);
157 location.method_id = ReadMethodId(pBuf);
158 location.dex_pc = Read8BE(pBuf);
159 VLOG(jdwp) << " location " << location;
160 return location;
161}
162
163static std::string ReadUtf8String(unsigned char const** ppSrc) {
164 uint32_t length = Read4BE(ppSrc);
165 std::string s;
166 s.resize(length);
167 memcpy(&s[0], *ppSrc, length);
168 (*ppSrc) += length;
169 VLOG(jdwp) << " string \"" << s << "\"";
170 return s;
171}
172
173static JdwpModKind ReadModKind(const uint8_t** pBuf) {
174 JdwpModKind mod_kind = static_cast<JdwpModKind>(Read1(pBuf));
175 VLOG(jdwp) << " mod kind " << mod_kind;
176 return mod_kind;
177}
178
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700179/*
180 * Helper function: write a variable-width value into the output input buffer.
181 */
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800182static void WriteValue(ExpandBuf* pReply, int width, uint64_t value) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700183 switch (width) {
184 case 1: expandBufAdd1(pReply, value); break;
185 case 2: expandBufAdd2BE(pReply, value); break;
186 case 4: expandBufAdd4BE(pReply, value); break;
187 case 8: expandBufAdd8BE(pReply, value); break;
188 default: LOG(FATAL) << width; break;
189 }
190}
191
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800192static JdwpError WriteTaggedObject(ExpandBuf* reply, ObjectId object_id)
193 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
194 uint8_t tag;
195 JdwpError rc = Dbg::GetObjectTag(object_id, tag);
196 if (rc == ERR_NONE) {
197 expandBufAdd1(reply, tag);
198 expandBufAddObjectId(reply, object_id);
199 }
200 return rc;
201}
202
Elliott Hughes0cbaff52013-01-16 15:28:01 -0800203static JdwpError WriteTaggedObjectList(ExpandBuf* reply, const std::vector<ObjectId>& objects)
204 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
205 expandBufAdd4BE(reply, objects.size());
206 for (size_t i = 0; i < objects.size(); ++i) {
207 JdwpError rc = WriteTaggedObject(reply, objects[i]);
208 if (rc != ERR_NONE) {
209 return rc;
210 }
211 }
212 return ERR_NONE;
213}
214
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700215/*
216 * Common code for *_InvokeMethod requests.
217 *
Elliott Hughes74847412012-06-20 18:10:21 -0700218 * If "is_constructor" is set, this returns "object_id" rather than the
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700219 * expected-to-be-void return value of the called function.
220 */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700221static JdwpError FinishInvoke(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply,
Elliott Hughes74847412012-06-20 18:10:21 -0700222 ObjectId thread_id, ObjectId object_id,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700223 RefTypeId class_id, MethodId method_id, bool is_constructor)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700224 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700225 CHECK(!is_constructor || object_id != 0);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700226
Elliott Hughesa96836a2013-01-17 12:27:49 -0800227 int32_t arg_count = ReadSigned32("argument count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700228
Elliott Hughes74847412012-06-20 18:10:21 -0700229 VLOG(jdwp) << StringPrintf(" --> thread_id=%#llx object_id=%#llx", thread_id, object_id);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700230 VLOG(jdwp) << StringPrintf(" class_id=%#llx method_id=%x %s.%s", class_id,
231 method_id, Dbg::GetClassName(class_id).c_str(),
Elliott Hughesa96836a2013-01-17 12:27:49 -0800232 Dbg::GetMethodName(method_id).c_str());
Elliott Hughes45651fd2012-02-21 15:48:20 -0800233 VLOG(jdwp) << StringPrintf(" %d args:", arg_count);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700234
Elliott Hughes45651fd2012-02-21 15:48:20 -0800235 UniquePtr<JdwpTag[]> argTypes(arg_count > 0 ? new JdwpTag[arg_count] : NULL);
236 UniquePtr<uint64_t[]> argValues(arg_count > 0 ? new uint64_t[arg_count] : NULL);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800237 for (int32_t i = 0; i < arg_count; ++i) {
Elliott Hughes45651fd2012-02-21 15:48:20 -0800238 argTypes[i] = ReadTag(&buf);
239 size_t width = Dbg::GetTagWidth(argTypes[i]);
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800240 argValues[i] = ReadValue(&buf, width);
Elliott Hughes229feb72012-02-23 13:33:29 -0800241 VLOG(jdwp) << " " << argTypes[i] << StringPrintf("(%zd): %#llx", width, argValues[i]);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700242 }
243
Elliott Hughesf7c3b662011-10-27 12:04:56 -0700244 uint32_t options = Read4BE(&buf); /* enum InvokeOptions bit flags */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700245 VLOG(jdwp) << StringPrintf(" options=0x%04x%s%s", options,
246 (options & INVOKE_SINGLE_THREADED) ? " (SINGLE_THREADED)" : "",
247 (options & INVOKE_NONVIRTUAL) ? " (NONVIRTUAL)" : "");
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700248
Elliott Hughes45651fd2012-02-21 15:48:20 -0800249 JdwpTag resultTag;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700250 uint64_t resultValue;
251 ObjectId exceptObjId;
Elliott Hughes74847412012-06-20 18:10:21 -0700252 JdwpError err = Dbg::InvokeMethod(thread_id, object_id, class_id, method_id, arg_count, argValues.get(), argTypes.get(), options, &resultTag, &resultValue, &exceptObjId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700253 if (err != ERR_NONE) {
Elliott Hughes45651fd2012-02-21 15:48:20 -0800254 return err;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700255 }
256
257 if (err == ERR_NONE) {
Elliott Hughes45651fd2012-02-21 15:48:20 -0800258 if (is_constructor) {
259 // If we invoked a constructor (which actually returns void), return the receiver,
260 // unless we threw, in which case we return NULL.
261 resultTag = JT_OBJECT;
Elliott Hughes74847412012-06-20 18:10:21 -0700262 resultValue = (exceptObjId == 0) ? object_id : 0;
Elliott Hughes45651fd2012-02-21 15:48:20 -0800263 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700264
Elliott Hughes45651fd2012-02-21 15:48:20 -0800265 size_t width = Dbg::GetTagWidth(resultTag);
266 expandBufAdd1(pReply, resultTag);
267 if (width != 0) {
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800268 WriteValue(pReply, width, resultValue);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700269 }
270 expandBufAdd1(pReply, JT_OBJECT);
271 expandBufAddObjectId(pReply, exceptObjId);
272
Elliott Hughes229feb72012-02-23 13:33:29 -0800273 VLOG(jdwp) << " --> returned " << resultTag << StringPrintf(" %#llx (except=%#llx)", resultValue, exceptObjId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700274
275 /* show detailed debug output */
276 if (resultTag == JT_STRING && exceptObjId == 0) {
277 if (resultValue != 0) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800278 VLOG(jdwp) << " string '" << Dbg::StringToUtf8(resultValue) << "'";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700279 } else {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800280 VLOG(jdwp) << " string (null)";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700281 }
282 }
283 }
284
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700285 return err;
286}
287
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700288static JdwpError VM_Version(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700289 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes927bd292013-01-17 10:40:13 -0800290 // Text information on runtime version.
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700291 std::string version(StringPrintf("Android Runtime %s", Runtime::Current()->GetVersion()));
Elliott Hughes4740cdf2011-12-07 14:07:12 -0800292 expandBufAddUtf8String(pReply, version);
Elliott Hughes927bd292013-01-17 10:40:13 -0800293
294 // JDWP version numbers, major and minor.
295 expandBufAdd4BE(pReply, 1);
296 expandBufAdd4BE(pReply, 6);
297
298 // "java.version".
299 expandBufAddUtf8String(pReply, "1.6.0");
300
301 // "java.vm.name".
302 expandBufAddUtf8String(pReply, "Dalvik");
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700303
304 return ERR_NONE;
305}
306
307/*
308 * Given a class JNI signature (e.g. "Ljava/lang/Error;"), return the
309 * referenceTypeID. We need to send back more than one if the class has
310 * been loaded by multiple class loaders.
311 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700312static JdwpError VM_ClassesBySignature(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700313 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -0800314 std::string classDescriptor(ReadUtf8String(&buf));
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700315
Elliott Hughes6fa602d2011-12-02 17:54:25 -0800316 std::vector<RefTypeId> ids;
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800317 Dbg::FindLoadedClassBySignature(classDescriptor.c_str(), ids);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700318
Elliott Hughes6fa602d2011-12-02 17:54:25 -0800319 expandBufAdd4BE(pReply, ids.size());
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700320
Elliott Hughes6fa602d2011-12-02 17:54:25 -0800321 for (size_t i = 0; i < ids.size(); ++i) {
322 // Get class vs. interface and status flags.
Elliott Hughes436e3722012-02-17 20:01:47 -0800323 JDWP::JdwpTypeTag type_tag;
324 uint32_t class_status;
325 JDWP::JdwpError status = Dbg::GetClassInfo(ids[i], &type_tag, &class_status, NULL);
326 if (status != ERR_NONE) {
327 return status;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800328 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700329
Elliott Hughes436e3722012-02-17 20:01:47 -0800330 expandBufAdd1(pReply, type_tag);
Elliott Hughes6fa602d2011-12-02 17:54:25 -0800331 expandBufAddRefTypeId(pReply, ids[i]);
Elliott Hughes436e3722012-02-17 20:01:47 -0800332 expandBufAdd4BE(pReply, class_status);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700333 }
334
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700335 return ERR_NONE;
336}
337
338/*
339 * Handle request for the thread IDs of all running threads.
340 *
341 * We exclude ourselves from the list, because we don't allow ourselves
342 * to be suspended, and that violates some JDWP expectations.
343 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700344static JdwpError VM_AllThreads(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700345 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughescaf76542012-06-28 16:08:22 -0700346 std::vector<ObjectId> thread_ids;
Elliott Hughes026b1462012-06-28 20:43:49 -0700347 Dbg::GetThreads(0, thread_ids);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700348
Elliott Hughescaf76542012-06-28 16:08:22 -0700349 expandBufAdd4BE(pReply, thread_ids.size());
350 for (uint32_t i = 0; i < thread_ids.size(); ++i) {
351 expandBufAddObjectId(pReply, thread_ids[i]);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700352 }
353
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700354 return ERR_NONE;
355}
356
357/*
358 * List all thread groups that do not have a parent.
359 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700360static JdwpError VM_TopLevelThreadGroups(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700361 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700362 /*
363 * TODO: maintain a list of parentless thread groups in the VM.
364 *
365 * For now, just return "system". Application threads are created
366 * in "main", which is a child of "system".
367 */
368 uint32_t groups = 1;
369 expandBufAdd4BE(pReply, groups);
Elliott Hughescaf76542012-06-28 16:08:22 -0700370 ObjectId thread_group_id = Dbg::GetSystemThreadGroupId();
371 expandBufAddObjectId(pReply, thread_group_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700372
373 return ERR_NONE;
374}
375
376/*
377 * Respond with the sizes of the basic debugger types.
378 *
379 * All IDs are 8 bytes.
380 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700381static JdwpError VM_IDSizes(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700382 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700383 expandBufAdd4BE(pReply, sizeof(FieldId));
384 expandBufAdd4BE(pReply, sizeof(MethodId));
385 expandBufAdd4BE(pReply, sizeof(ObjectId));
386 expandBufAdd4BE(pReply, sizeof(RefTypeId));
387 expandBufAdd4BE(pReply, sizeof(FrameId));
388 return ERR_NONE;
389}
390
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700391static JdwpError VM_Dispose(JdwpState*, const uint8_t*, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700392 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes86964332012-02-15 19:37:42 -0800393 Dbg::Disposed();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700394 return ERR_NONE;
395}
396
397/*
398 * Suspend the execution of the application running in the VM (i.e. suspend
399 * all threads).
400 *
401 * This needs to increment the "suspend count" on all threads.
402 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700403static JdwpError VM_Suspend(JdwpState*, const uint8_t*, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700404 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
jeffhaoa77f0f62012-12-05 17:19:31 -0800405 Thread* self = Thread::Current();
406 self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSuspension);
Elliott Hughes475fc232011-10-25 15:00:35 -0700407 Dbg::SuspendVM();
jeffhaoa77f0f62012-12-05 17:19:31 -0800408 self->TransitionFromSuspendedToRunnable();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700409 return ERR_NONE;
410}
411
412/*
413 * Resume execution. Decrements the "suspend count" of all threads.
414 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700415static JdwpError VM_Resume(JdwpState*, const uint8_t*, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700416 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700417 Dbg::ResumeVM();
418 return ERR_NONE;
419}
420
421/*
422 * The debugger wants the entire VM to exit.
423 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700424static JdwpError VM_Exit(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700425 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesf7c3b662011-10-27 12:04:56 -0700426 uint32_t exitCode = Get4BE(buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700427
428 LOG(WARNING) << "Debugger is telling the VM to exit with code=" << exitCode;
429
430 Dbg::Exit(exitCode);
431 return ERR_NOT_IMPLEMENTED; // shouldn't get here
432}
433
434/*
435 * Create a new string in the VM and return its ID.
436 *
437 * (Ctrl-Shift-I in Eclipse on an array of objects causes it to create the
438 * string "java.util.Arrays".)
439 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700440static JdwpError VM_CreateString(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700441 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -0800442 std::string str(ReadUtf8String(&buf));
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700443 ObjectId stringId = Dbg::CreateString(str);
444 if (stringId == 0) {
445 return ERR_OUT_OF_MEMORY;
446 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700447 expandBufAddObjectId(pReply, stringId);
448 return ERR_NONE;
449}
450
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700451static JdwpError VM_ClassPaths(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700452 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa3ae2b72012-02-24 15:10:51 -0800453 expandBufAddUtf8String(pReply, "/");
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700454
Elliott Hughesa3ae2b72012-02-24 15:10:51 -0800455 std::vector<std::string> class_path;
456 Split(Runtime::Current()->GetClassPathString(), ':', class_path);
457 expandBufAdd4BE(pReply, class_path.size());
458 for (size_t i = 0; i < class_path.size(); ++i) {
459 expandBufAddUtf8String(pReply, class_path[i]);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700460 }
461
Elliott Hughesa3ae2b72012-02-24 15:10:51 -0800462 std::vector<std::string> boot_class_path;
463 Split(Runtime::Current()->GetBootClassPathString(), ':', boot_class_path);
464 expandBufAdd4BE(pReply, boot_class_path.size());
465 for (size_t i = 0; i < boot_class_path.size(); ++i) {
466 expandBufAddUtf8String(pReply, boot_class_path[i]);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700467 }
468
469 return ERR_NONE;
470}
471
472/*
473 * Release a list of object IDs. (Seen in jdb.)
474 *
475 * Currently does nothing.
476 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700477static JdwpError VM_DisposeObjects(JdwpState*, const uint8_t*, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700478 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700479 return ERR_NONE;
480}
481
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800482static JdwpError VM_Capabilities(JdwpState*, const uint8_t*, int, ExpandBuf* reply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700483 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800484 expandBufAdd1(reply, false); // canWatchFieldModification
485 expandBufAdd1(reply, false); // canWatchFieldAccess
Elliott Hughes9777ba22013-01-17 09:04:19 -0800486 expandBufAdd1(reply, true); // canGetBytecodes
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800487 expandBufAdd1(reply, true); // canGetSyntheticAttribute
488 expandBufAdd1(reply, true); // canGetOwnedMonitorInfo
Elliott Hughesf9501702013-01-11 11:22:27 -0800489 expandBufAdd1(reply, true); // canGetCurrentContendedMonitor
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800490 expandBufAdd1(reply, true); // canGetMonitorInfo
491 return ERR_NONE;
492}
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700493
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800494static JdwpError VM_CapabilitiesNew(JdwpState*, const uint8_t*, int, ExpandBuf* reply)
495 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
496
497 // The first few capabilities are the same as those reported by the older call.
498 VM_Capabilities(NULL, NULL, 0, reply);
499
500 expandBufAdd1(reply, false); // canRedefineClasses
501 expandBufAdd1(reply, false); // canAddMethod
502 expandBufAdd1(reply, false); // canUnrestrictedlyRedefineClasses
503 expandBufAdd1(reply, false); // canPopFrames
504 expandBufAdd1(reply, false); // canUseInstanceFilters
505 expandBufAdd1(reply, false); // canGetSourceDebugExtension
506 expandBufAdd1(reply, false); // canRequestVMDeathEvent
507 expandBufAdd1(reply, false); // canSetDefaultStratum
Elliott Hughesec0f83d2013-01-15 16:54:08 -0800508 expandBufAdd1(reply, true); // 1.6: canGetInstanceInfo
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800509 expandBufAdd1(reply, false); // 1.6: canRequestMonitorEvents
Elliott Hughes734b8c62013-01-11 15:32:45 -0800510 expandBufAdd1(reply, true); // 1.6: canGetMonitorFrameInfo
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800511 expandBufAdd1(reply, false); // 1.6: canUseSourceNameFilters
512 expandBufAdd1(reply, false); // 1.6: canGetConstantPool
513 expandBufAdd1(reply, false); // 1.6: canForceEarlyReturn
514
515 // Fill in reserved22 through reserved32; note count started at 1.
516 for (size_t i = 22; i <= 32; ++i) {
517 expandBufAdd1(reply, false);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700518 }
519 return ERR_NONE;
520}
521
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700522static JdwpError VM_AllClassesImpl(ExpandBuf* pReply, bool descriptor_and_status, bool generic)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700523 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800524 std::vector<JDWP::RefTypeId> classes;
525 Dbg::GetClassList(classes);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700526
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800527 expandBufAdd4BE(pReply, classes.size());
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700528
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800529 for (size_t i = 0; i < classes.size(); ++i) {
Elliott Hughesa2155262011-11-16 16:26:58 -0800530 static const char genericSignature[1] = "";
Elliott Hughes436e3722012-02-17 20:01:47 -0800531 JDWP::JdwpTypeTag type_tag;
Elliott Hughesa2155262011-11-16 16:26:58 -0800532 std::string descriptor;
Elliott Hughes436e3722012-02-17 20:01:47 -0800533 uint32_t class_status;
534 JDWP::JdwpError status = Dbg::GetClassInfo(classes[i], &type_tag, &class_status, &descriptor);
535 if (status != ERR_NONE) {
536 return status;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800537 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700538
Elliott Hughes436e3722012-02-17 20:01:47 -0800539 expandBufAdd1(pReply, type_tag);
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800540 expandBufAddRefTypeId(pReply, classes[i]);
Elliott Hughes86964332012-02-15 19:37:42 -0800541 if (descriptor_and_status) {
542 expandBufAddUtf8String(pReply, descriptor);
543 if (generic) {
544 expandBufAddUtf8String(pReply, genericSignature);
545 }
Elliott Hughes436e3722012-02-17 20:01:47 -0800546 expandBufAdd4BE(pReply, class_status);
Elliott Hughes1fe7afb2012-02-13 17:23:03 -0800547 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700548 }
549
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700550 return ERR_NONE;
551}
552
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700553static JdwpError VM_AllClasses(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700554 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700555 return VM_AllClassesImpl(pReply, true, false);
Elliott Hughes1fe7afb2012-02-13 17:23:03 -0800556}
557
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700558static JdwpError VM_AllClassesWithGeneric(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700559 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700560 return VM_AllClassesImpl(pReply, true, true);
Elliott Hughes1fe7afb2012-02-13 17:23:03 -0800561}
562
Elliott Hughesec0f83d2013-01-15 16:54:08 -0800563static JdwpError VM_InstanceCounts(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
564 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -0800565 int32_t class_count = ReadSigned32("class count", &buf);
Elliott Hughesec0f83d2013-01-15 16:54:08 -0800566 if (class_count < 0) {
567 return ERR_ILLEGAL_ARGUMENT;
568 }
569 std::vector<RefTypeId> class_ids;
570 for (int32_t i = 0; i < class_count; ++i) {
571 class_ids.push_back(ReadRefTypeId(&buf));
572 }
573
574 std::vector<uint64_t> counts;
575 JdwpError rc = Dbg::GetInstanceCounts(class_ids, counts);
576 if (rc != ERR_NONE) {
577 return rc;
578 }
579
580 expandBufAdd4BE(pReply, counts.size());
581 for (size_t i = 0; i < counts.size(); ++i) {
582 expandBufAdd8BE(pReply, counts[i]);
583 }
584 return ERR_NONE;
585}
586
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700587static JdwpError RT_Modifiers(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700588 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700589 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800590 return Dbg::GetModifiers(refTypeId, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700591}
592
593/*
594 * Get values from static fields in a reference type.
595 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700596static JdwpError RT_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700597 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes0cf74332012-02-23 23:14:00 -0800598 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800599 int32_t field_count = ReadSigned32("field count", &buf);
Elliott Hughes0cf74332012-02-23 23:14:00 -0800600 expandBufAdd4BE(pReply, field_count);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800601 for (int32_t i = 0; i < field_count; ++i) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700602 FieldId fieldId = ReadFieldId(&buf);
Elliott Hughes0cf74332012-02-23 23:14:00 -0800603 JdwpError status = Dbg::GetStaticFieldValue(refTypeId, fieldId, pReply);
Elliott Hughes3f4d58f2012-02-18 20:05:37 -0800604 if (status != ERR_NONE) {
605 return status;
606 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700607 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700608 return ERR_NONE;
609}
610
611/*
612 * Get the name of the source file in which a reference type was declared.
613 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700614static JdwpError RT_SourceFile(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700615 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700616 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes03181a82011-11-17 17:22:21 -0800617 std::string source_file;
Elliott Hughes436e3722012-02-17 20:01:47 -0800618 JdwpError status = Dbg::GetSourceFile(refTypeId, source_file);
619 if (status != ERR_NONE) {
620 return status;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700621 }
Elliott Hughes4740cdf2011-12-07 14:07:12 -0800622 expandBufAddUtf8String(pReply, source_file);
Elliott Hughes03181a82011-11-17 17:22:21 -0800623 return ERR_NONE;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700624}
625
626/*
627 * Return the current status of the reference type.
628 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700629static JdwpError RT_Status(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700630 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700631 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800632 JDWP::JdwpTypeTag type_tag;
633 uint32_t class_status;
634 JDWP::JdwpError status = Dbg::GetClassInfo(refTypeId, &type_tag, &class_status, NULL);
635 if (status != ERR_NONE) {
636 return status;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800637 }
Elliott Hughes436e3722012-02-17 20:01:47 -0800638 expandBufAdd4BE(pReply, class_status);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700639 return ERR_NONE;
640}
641
642/*
643 * Return interfaces implemented directly by this class.
644 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700645static JdwpError RT_Interfaces(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700646 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700647 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800648 return Dbg::OutputDeclaredInterfaces(refTypeId, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700649}
650
651/*
652 * Return the class object corresponding to this type.
653 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700654static JdwpError RT_ClassObject(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700655 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700656 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800657 ObjectId class_object_id;
658 JdwpError status = Dbg::GetClassObject(refTypeId, class_object_id);
Elliott Hughes436e3722012-02-17 20:01:47 -0800659 if (status != ERR_NONE) {
660 return status;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800661 }
Elliott Hughesa96836a2013-01-17 12:27:49 -0800662 VLOG(jdwp) << StringPrintf(" --> ObjectId %#llx", class_object_id);
663 expandBufAddObjectId(pReply, class_object_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700664 return ERR_NONE;
665}
666
667/*
668 * Returns the value of the SourceDebugExtension attribute.
669 *
670 * JDB seems interested, but DEX files don't currently support this.
671 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700672static JdwpError RT_SourceDebugExtension(JdwpState*, const uint8_t*, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700673 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700674 /* referenceTypeId in, string out */
675 return ERR_ABSENT_INFORMATION;
676}
677
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700678static JdwpError RT_Signature(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply,
679 bool with_generic)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700680 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700681 RefTypeId refTypeId = ReadRefTypeId(&buf);
682
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800683 std::string signature;
Elliott Hughes98e43f62012-02-24 12:42:35 -0800684 JdwpError status = Dbg::GetSignature(refTypeId, signature);
685 if (status != ERR_NONE) {
686 return status;
687 }
688 expandBufAddUtf8String(pReply, signature);
689 if (with_generic) {
Elliott Hughes0cf74332012-02-23 23:14:00 -0800690 expandBufAddUtf8String(pReply, "");
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700691 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700692 return ERR_NONE;
693}
694
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700695static JdwpError RT_Signature(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700696 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700697 return RT_Signature(state, buf, dataLen, pReply, false);
Elliott Hughes98e43f62012-02-24 12:42:35 -0800698}
699
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700700static JdwpError RT_SignatureWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen,
701 ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700702 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700703 return RT_Signature(state, buf, dataLen, pReply, true);
Elliott Hughes98e43f62012-02-24 12:42:35 -0800704}
705
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700706/*
707 * Return the instance of java.lang.ClassLoader that loaded the specified
708 * reference type, or null if it was loaded by the system loader.
709 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700710static JdwpError RT_ClassLoader(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700711 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700712 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800713 return Dbg::GetClassLoader(refTypeId, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700714}
715
716/*
717 * Given a referenceTypeId, return a block of stuff that describes the
718 * fields declared by a class.
719 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700720static JdwpError RT_FieldsWithGeneric(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700721 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700722 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800723 return Dbg::OutputDeclaredFields(refTypeId, true, pReply);
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800724}
725
726// Obsolete equivalent of FieldsWithGeneric, without the generic type information.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700727static JdwpError RT_Fields(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700728 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800729 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800730 return Dbg::OutputDeclaredFields(refTypeId, false, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700731}
732
733/*
734 * Given a referenceTypeID, return a block of goodies describing the
735 * methods declared by a class.
736 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700737static JdwpError RT_MethodsWithGeneric(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700738 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700739 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800740 return Dbg::OutputDeclaredMethods(refTypeId, true, pReply);
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800741}
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700742
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800743// Obsolete equivalent of MethodsWithGeneric, without the generic type information.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700744static JdwpError RT_Methods(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700745 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800746 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800747 return Dbg::OutputDeclaredMethods(refTypeId, false, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700748}
749
Elliott Hughes3b78c942013-01-15 17:35:41 -0800750static JdwpError RT_Instances(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
751 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
752 RefTypeId class_id = ReadRefTypeId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800753 int32_t max_count = ReadSigned32("max count", &buf);
Elliott Hughes3b78c942013-01-15 17:35:41 -0800754 if (max_count < 0) {
755 return ERR_ILLEGAL_ARGUMENT;
756 }
757
758 std::vector<ObjectId> instances;
759 JdwpError rc = Dbg::GetInstances(class_id, max_count, instances);
760 if (rc != ERR_NONE) {
761 return rc;
762 }
763
Elliott Hughes0cbaff52013-01-16 15:28:01 -0800764 return WriteTaggedObjectList(reply, instances);
Elliott Hughes3b78c942013-01-15 17:35:41 -0800765}
766
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700767/*
768 * Return the immediate superclass of a class.
769 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700770static JdwpError CT_Superclass(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700771 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700772 RefTypeId class_id = ReadRefTypeId(&buf);
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800773 RefTypeId superClassId;
Elliott Hughes74847412012-06-20 18:10:21 -0700774 JdwpError status = Dbg::GetSuperclass(class_id, superClassId);
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -0800775 if (status != ERR_NONE) {
776 return status;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800777 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700778 expandBufAddRefTypeId(pReply, superClassId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700779 return ERR_NONE;
780}
781
782/*
783 * Set static class values.
784 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700785static JdwpError CT_SetValues(JdwpState* , const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700786 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700787 RefTypeId class_id = ReadRefTypeId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800788 int32_t values_count = ReadSigned32("values count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700789
Elliott Hughesa96836a2013-01-17 12:27:49 -0800790 UNUSED(class_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700791
Elliott Hughesa96836a2013-01-17 12:27:49 -0800792 for (int32_t i = 0; i < values_count; ++i) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700793 FieldId fieldId = ReadFieldId(&buf);
Elliott Hughesaed4be92011-12-02 16:16:23 -0800794 JDWP::JdwpTag fieldTag = Dbg::GetStaticFieldBasicTag(fieldId);
Elliott Hughesdbb40792011-11-18 17:05:22 -0800795 size_t width = Dbg::GetTagWidth(fieldTag);
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800796 uint64_t value = ReadValue(&buf, width);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700797
Elliott Hughesa96836a2013-01-17 12:27:49 -0800798 VLOG(jdwp) << " --> field=" << fieldId << " tag=" << fieldTag << " --> " << value;
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -0800799 JdwpError status = Dbg::SetStaticFieldValue(fieldId, value, width);
800 if (status != ERR_NONE) {
801 return status;
802 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700803 }
804
805 return ERR_NONE;
806}
807
808/*
809 * Invoke a static method.
810 *
811 * Example: Eclipse sometimes uses java/lang/Class.forName(String s) on
812 * values in the "variables" display.
813 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700814static JdwpError CT_InvokeMethod(JdwpState* state, const uint8_t* buf, int dataLen,
815 ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700816 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700817 RefTypeId class_id = ReadRefTypeId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800818 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -0700819 MethodId method_id = ReadMethodId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700820
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700821 return FinishInvoke(state, buf, dataLen, pReply, thread_id, 0, class_id, method_id, false);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700822}
823
824/*
825 * Create a new object of the requested type, and invoke the specified
826 * constructor.
827 *
828 * Example: in IntelliJ, create a watch on "new String(myByteArray)" to
829 * see the contents of a byte[] as a string.
830 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700831static JdwpError CT_NewInstance(JdwpState* state, const uint8_t* buf, int dataLen,
832 ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700833 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700834 RefTypeId class_id = ReadRefTypeId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800835 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -0700836 MethodId method_id = ReadMethodId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700837
Elliott Hughes74847412012-06-20 18:10:21 -0700838 ObjectId object_id;
839 JdwpError status = Dbg::CreateObject(class_id, object_id);
Elliott Hughes436e3722012-02-17 20:01:47 -0800840 if (status != ERR_NONE) {
841 return status;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800842 }
Elliott Hughes74847412012-06-20 18:10:21 -0700843 if (object_id == 0) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700844 return ERR_OUT_OF_MEMORY;
845 }
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700846 return FinishInvoke(state, buf, dataLen, pReply, thread_id, object_id, class_id, method_id, true);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700847}
848
849/*
850 * Create a new array object of the requested type and length.
851 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700852static JdwpError AT_newInstance(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700853 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700854 RefTypeId arrayTypeId = ReadRefTypeId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800855 int32_t length = ReadSigned32("length", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700856
Elliott Hughes74847412012-06-20 18:10:21 -0700857 ObjectId object_id;
858 JdwpError status = Dbg::CreateArrayObject(arrayTypeId, length, object_id);
Elliott Hughes436e3722012-02-17 20:01:47 -0800859 if (status != ERR_NONE) {
860 return status;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800861 }
Elliott Hughes74847412012-06-20 18:10:21 -0700862 if (object_id == 0) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700863 return ERR_OUT_OF_MEMORY;
864 }
865 expandBufAdd1(pReply, JT_ARRAY);
Elliott Hughes74847412012-06-20 18:10:21 -0700866 expandBufAddObjectId(pReply, object_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700867 return ERR_NONE;
868}
869
870/*
871 * Return line number information for the method, if present.
872 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700873static JdwpError M_LineTable(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700874 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700875 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -0700876 MethodId method_id = ReadMethodId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700877
Elliott Hughes74847412012-06-20 18:10:21 -0700878 Dbg::OutputLineTable(refTypeId, method_id, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700879
880 return ERR_NONE;
881}
882
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700883static JdwpError M_VariableTable(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply,
884 bool generic)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700885 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700886 RefTypeId class_id = ReadRefTypeId(&buf);
887 MethodId method_id = ReadMethodId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700888
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -0800889 // We could return ERR_ABSENT_INFORMATION here if the DEX file was built without local variable
890 // information. That will cause Eclipse to make a best-effort attempt at displaying local
891 // variables anonymously. However, the attempt isn't very good, so we're probably better off just
892 // not showing anything.
Elliott Hughes74847412012-06-20 18:10:21 -0700893 Dbg::OutputVariableTable(class_id, method_id, generic, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700894 return ERR_NONE;
895}
896
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700897static JdwpError M_VariableTable(JdwpState* state, const uint8_t* buf, int dataLen,
898 ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700899 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700900 return M_VariableTable(state, buf, dataLen, pReply, false);
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -0800901}
902
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700903static JdwpError M_VariableTableWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen,
904 ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700905 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700906 return M_VariableTable(state, buf, dataLen, pReply, true);
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -0800907}
908
Elliott Hughes9777ba22013-01-17 09:04:19 -0800909static JdwpError M_Bytecodes(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
910 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
911 RefTypeId class_id = ReadRefTypeId(&buf);
912 MethodId method_id = ReadMethodId(&buf);
913
914 std::vector<uint8_t> bytecodes;
915 JdwpError rc = Dbg::GetBytecodes(class_id, method_id, bytecodes);
916 if (rc != ERR_NONE) {
917 return rc;
918 }
919
920 expandBufAdd4BE(reply, bytecodes.size());
921 for (size_t i = 0; i < bytecodes.size(); ++i) {
922 expandBufAdd1(reply, bytecodes[i]);
923 }
924
925 return ERR_NONE;
926}
927
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700928/*
929 * Given an object reference, return the runtime type of the object
930 * (class or array).
931 *
Elliott Hughes74847412012-06-20 18:10:21 -0700932 * This can get called on different things, e.g. thread_id gets
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700933 * passed in here.
934 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700935static JdwpError OR_ReferenceType(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700936 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700937 ObjectId object_id = ReadObjectId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -0700938 return Dbg::GetReferenceType(object_id, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700939}
940
941/*
942 * Get values from the fields of an object.
943 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700944static JdwpError OR_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700945 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700946 ObjectId object_id = ReadObjectId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800947 int32_t field_count = ReadSigned32("field count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700948
Elliott Hughes0cf74332012-02-23 23:14:00 -0800949 expandBufAdd4BE(pReply, field_count);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800950 for (int32_t i = 0; i < field_count; ++i) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700951 FieldId fieldId = ReadFieldId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -0700952 JdwpError status = Dbg::GetFieldValue(object_id, fieldId, pReply);
Elliott Hughes3f4d58f2012-02-18 20:05:37 -0800953 if (status != ERR_NONE) {
954 return status;
955 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700956 }
957
958 return ERR_NONE;
959}
960
961/*
962 * Set values in the fields of an object.
963 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700964static JdwpError OR_SetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700965 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700966 ObjectId object_id = ReadObjectId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800967 int32_t field_count = ReadSigned32("field count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700968
Elliott Hughesa96836a2013-01-17 12:27:49 -0800969 for (int32_t i = 0; i < field_count; ++i) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700970 FieldId fieldId = ReadFieldId(&buf);
971
Elliott Hughesaed4be92011-12-02 16:16:23 -0800972 JDWP::JdwpTag fieldTag = Dbg::GetFieldBasicTag(fieldId);
Elliott Hughesdbb40792011-11-18 17:05:22 -0800973 size_t width = Dbg::GetTagWidth(fieldTag);
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800974 uint64_t value = ReadValue(&buf, width);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700975
Elliott Hughes2435a572012-02-17 16:07:41 -0800976 VLOG(jdwp) << " --> fieldId=" << fieldId << " tag=" << fieldTag << "(" << width << ") value=" << value;
Elliott Hughes74847412012-06-20 18:10:21 -0700977 JdwpError status = Dbg::SetFieldValue(object_id, fieldId, value, width);
Elliott Hughes3f4d58f2012-02-18 20:05:37 -0800978 if (status != ERR_NONE) {
979 return status;
980 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700981 }
982
983 return ERR_NONE;
984}
985
Elliott Hughesf327e072013-01-09 16:01:26 -0800986static JdwpError OR_MonitorInfo(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
987 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
988 ObjectId object_id = ReadObjectId(&buf);
989 return Dbg::GetMonitorInfo(object_id, reply);
990}
991
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700992/*
993 * Invoke an instance method. The invocation must occur in the specified
994 * thread, which must have been suspended by an event.
995 *
996 * The call is synchronous. All threads in the VM are resumed, unless the
997 * SINGLE_THREADED flag is set.
998 *
999 * If you ask Eclipse to "inspect" an object (or ask JDB to "print" an
1000 * object), it will try to invoke the object's toString() function. This
1001 * feature becomes crucial when examining ArrayLists with Eclipse.
1002 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001003static JdwpError OR_InvokeMethod(JdwpState* state, const uint8_t* buf, int dataLen,
1004 ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001005 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -07001006 ObjectId object_id = ReadObjectId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -08001007 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -07001008 RefTypeId class_id = ReadRefTypeId(&buf);
1009 MethodId method_id = ReadMethodId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001010
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001011 return FinishInvoke(state, buf, dataLen, pReply, thread_id, object_id, class_id, method_id, false);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001012}
1013
1014/*
1015 * Disable garbage collection of the specified object.
1016 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001017static JdwpError OR_DisableCollection(JdwpState*, const uint8_t*, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001018 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes927bd292013-01-17 10:40:13 -08001019 // TODO: this is currently a no-op.
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001020 return ERR_NONE;
1021}
1022
1023/*
1024 * Enable garbage collection of the specified object.
1025 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001026static JdwpError OR_EnableCollection(JdwpState*, const uint8_t*, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001027 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes927bd292013-01-17 10:40:13 -08001028 // TODO: this is currently a no-op.
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001029 return ERR_NONE;
1030}
1031
1032/*
1033 * Determine whether an object has been garbage collected.
1034 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001035static JdwpError OR_IsCollected(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001036 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001037 //ObjectId object_id = ReadObjectId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001038
1039 // TODO: currently returning false; must integrate with GC
1040 expandBufAdd1(pReply, 0);
1041
1042 return ERR_NONE;
1043}
1044
Elliott Hughes0cbaff52013-01-16 15:28:01 -08001045static JdwpError OR_ReferringObjects(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
1046 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1047 ObjectId object_id = ReadObjectId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -08001048 int32_t max_count = ReadSigned32("max count", &buf);
Elliott Hughes0cbaff52013-01-16 15:28:01 -08001049 if (max_count < 0) {
1050 return ERR_ILLEGAL_ARGUMENT;
1051 }
1052
1053 std::vector<ObjectId> referring_objects;
1054 JdwpError rc = Dbg::GetReferringObjects(object_id, max_count, referring_objects);
1055 if (rc != ERR_NONE) {
1056 return rc;
1057 }
1058
1059 return WriteTaggedObjectList(reply, referring_objects);
1060}
1061
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001062/*
1063 * Return the string value in a string object.
1064 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001065static JdwpError SR_Value(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001066 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001067 ObjectId stringObject = ReadObjectId(&buf);
Elliott Hughes68fdbd02011-11-29 19:22:47 -08001068 std::string str(Dbg::StringToUtf8(stringObject));
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001069
Elliott Hughesa96836a2013-01-17 12:27:49 -08001070 VLOG(jdwp) << StringPrintf(" --> %s", PrintableString(str).c_str());
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001071
Elliott Hughes4740cdf2011-12-07 14:07:12 -08001072 expandBufAddUtf8String(pReply, str);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001073
1074 return ERR_NONE;
1075}
1076
1077/*
1078 * Return a thread's name.
1079 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001080static JdwpError TR_Name(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001081 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001082 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001083
Elliott Hughesa2e54f62011-11-17 13:01:30 -08001084 std::string name;
Elliott Hughes221229c2013-01-08 18:17:50 -08001085 JdwpError error = Dbg::GetThreadName(thread_id, name);
1086 if (error != ERR_NONE) {
1087 return error;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001088 }
Elliott Hughes74847412012-06-20 18:10:21 -07001089 VLOG(jdwp) << StringPrintf(" Name of thread %#llx is \"%s\"", thread_id, name.c_str());
Elliott Hughes4740cdf2011-12-07 14:07:12 -08001090 expandBufAddUtf8String(pReply, name);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001091
1092 return ERR_NONE;
1093}
1094
1095/*
1096 * Suspend the specified thread.
1097 *
1098 * It's supposed to remain suspended even if interpreted code wants to
1099 * resume it; only the JDI is allowed to resume it.
1100 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001101static JdwpError TR_Suspend(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001102 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001103 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001104
Elliott Hughes74847412012-06-20 18:10:21 -07001105 if (thread_id == Dbg::GetThreadSelfId()) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001106 LOG(INFO) << " Warning: ignoring request to suspend self";
1107 return ERR_THREAD_NOT_SUSPENDED;
1108 }
Elliott Hughesa96836a2013-01-17 12:27:49 -08001109
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001110 Thread* self = Thread::Current();
1111 self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
1112 JdwpError result = Dbg::SuspendThread(thread_id);
1113 self->TransitionFromSuspendedToRunnable();
1114 return result;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001115}
1116
1117/*
1118 * Resume the specified thread.
1119 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001120static JdwpError TR_Resume(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001121 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001122 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001123
Elliott Hughes74847412012-06-20 18:10:21 -07001124 if (thread_id == Dbg::GetThreadSelfId()) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001125 LOG(INFO) << " Warning: ignoring request to resume self";
1126 return ERR_NONE;
1127 }
Elliott Hughesa96836a2013-01-17 12:27:49 -08001128
Elliott Hughes74847412012-06-20 18:10:21 -07001129 Dbg::ResumeThread(thread_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001130 return ERR_NONE;
1131}
1132
1133/*
1134 * Return status of specified thread.
1135 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001136static JdwpError TR_Status(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001137 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001138 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001139
Elliott Hughes3d30d9b2011-12-07 17:35:48 -08001140 JDWP::JdwpThreadStatus threadStatus;
1141 JDWP::JdwpSuspendStatus suspendStatus;
Elliott Hughes221229c2013-01-08 18:17:50 -08001142 JdwpError error = Dbg::GetThreadStatus(thread_id, &threadStatus, &suspendStatus);
1143 if (error != ERR_NONE) {
1144 return error;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001145 }
1146
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001147 VLOG(jdwp) << " --> " << threadStatus << ", " << suspendStatus;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001148
1149 expandBufAdd4BE(pReply, threadStatus);
1150 expandBufAdd4BE(pReply, suspendStatus);
1151
1152 return ERR_NONE;
1153}
1154
1155/*
1156 * Return the thread group that the specified thread is a member of.
1157 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001158static JdwpError TR_ThreadGroup(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001159 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001160 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -07001161 return Dbg::GetThreadGroup(thread_id, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001162}
1163
1164/*
1165 * Return the current call stack of a suspended thread.
1166 *
1167 * If the thread isn't suspended, the error code isn't defined, but should
1168 * be THREAD_NOT_SUSPENDED.
1169 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001170static JdwpError TR_Frames(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001171 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001172 ObjectId thread_id = ReadThreadId(&buf);
1173 uint32_t start_frame = ReadUnsigned32("start frame", &buf);
1174 uint32_t length = ReadUnsigned32("length", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001175
Elliott Hughes221229c2013-01-08 18:17:50 -08001176 size_t actual_frame_count;
Elliott Hughesf15f4a02013-01-09 10:09:38 -08001177 JdwpError error = Dbg::GetThreadFrameCount(thread_id, actual_frame_count);
Elliott Hughes221229c2013-01-08 18:17:50 -08001178 if (error != ERR_NONE) {
1179 return error;
1180 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001181
Elliott Hughes3f4d58f2012-02-18 20:05:37 -08001182 if (actual_frame_count <= 0) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001183 return ERR_THREAD_NOT_SUSPENDED; // 0 means no managed frames (which means "in native").
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001184 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001185
Elliott Hughes3f4d58f2012-02-18 20:05:37 -08001186 if (start_frame > actual_frame_count) {
1187 return ERR_INVALID_INDEX;
1188 }
1189 if (length == static_cast<uint32_t>(-1)) {
1190 length = actual_frame_count - start_frame;
1191 }
1192 if (start_frame + length > actual_frame_count) {
1193 return ERR_INVALID_LENGTH;
1194 }
1195
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001196 return Dbg::GetThreadFrames(thread_id, start_frame, length, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001197}
1198
1199/*
1200 * Returns the #of frames on the specified thread, which must be suspended.
1201 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001202static JdwpError TR_FrameCount(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001203 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001204 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001205
Elliott Hughes221229c2013-01-08 18:17:50 -08001206 size_t frame_count;
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001207 JdwpError rc = Dbg::GetThreadFrameCount(thread_id, frame_count);
1208 if (rc != ERR_NONE) {
1209 return rc;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001210 }
Elliott Hughes3f4d58f2012-02-18 20:05:37 -08001211 expandBufAdd4BE(pReply, static_cast<uint32_t>(frame_count));
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001212
1213 return ERR_NONE;
1214}
1215
Elliott Hughes734b8c62013-01-11 15:32:45 -08001216static JdwpError TR_OwnedMonitors(const uint8_t* buf, ExpandBuf* reply, bool with_stack_depths)
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001217 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001218 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001219
1220 std::vector<ObjectId> monitors;
Elliott Hughes734b8c62013-01-11 15:32:45 -08001221 std::vector<uint32_t> stack_depths;
1222 JdwpError rc = Dbg::GetOwnedMonitors(thread_id, monitors, stack_depths);
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001223 if (rc != ERR_NONE) {
1224 return rc;
1225 }
1226
1227 expandBufAdd4BE(reply, monitors.size());
1228 for (size_t i = 0; i < monitors.size(); ++i) {
1229 rc = WriteTaggedObject(reply, monitors[i]);
1230 if (rc != ERR_NONE) {
1231 return rc;
1232 }
Elliott Hughes734b8c62013-01-11 15:32:45 -08001233 if (with_stack_depths) {
1234 expandBufAdd4BE(reply, stack_depths[i]);
1235 }
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001236 }
1237 return ERR_NONE;
1238}
1239
Elliott Hughes734b8c62013-01-11 15:32:45 -08001240static JdwpError TR_OwnedMonitors(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
1241 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1242 return TR_OwnedMonitors(buf, reply, false);
1243}
1244
1245static JdwpError TR_OwnedMonitorsStackDepthInfo(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
1246 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1247 return TR_OwnedMonitors(buf, reply, true);
1248}
1249
Elliott Hughesf9501702013-01-11 11:22:27 -08001250static JdwpError TR_CurrentContendedMonitor(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001251 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001252 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001253
Elliott Hughesf9501702013-01-11 11:22:27 -08001254 ObjectId contended_monitor;
1255 JdwpError rc = Dbg::GetContendedMonitor(thread_id, contended_monitor);
1256 if (rc != ERR_NONE) {
1257 return rc;
1258 }
1259 return WriteTaggedObject(reply, contended_monitor);
1260}
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001261
Elliott Hughesf9501702013-01-11 11:22:27 -08001262static JdwpError TR_Interrupt(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
1263 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001264 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughesf9501702013-01-11 11:22:27 -08001265 return Dbg::Interrupt(thread_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001266}
1267
1268/*
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001269 * Return the debug suspend count for the specified thread.
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001270 *
1271 * (The thread *might* still be running -- it might not have examined
1272 * its suspend count recently.)
1273 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001274static JdwpError TR_DebugSuspendCount(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001275 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001276 ObjectId thread_id = ReadThreadId(&buf);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001277 return Dbg::GetThreadDebugSuspendCount(thread_id, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001278}
1279
1280/*
1281 * Return the name of a thread group.
1282 *
1283 * The Eclipse debugger recognizes "main" and "system" as special.
1284 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001285static JdwpError TGR_Name(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001286 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001287 ObjectId thread_group_id = ReadThreadGroupId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001288
Elliott Hughescaf76542012-06-28 16:08:22 -07001289 expandBufAddUtf8String(pReply, Dbg::GetThreadGroupName(thread_group_id));
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001290
1291 return ERR_NONE;
1292}
1293
1294/*
1295 * Returns the thread group -- if any -- that contains the specified
1296 * thread group.
1297 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001298static JdwpError TGR_Parent(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001299 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001300 ObjectId thread_group_id = ReadThreadGroupId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001301
Elliott Hughescaf76542012-06-28 16:08:22 -07001302 ObjectId parentGroup = Dbg::GetThreadGroupParent(thread_group_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001303 expandBufAddObjectId(pReply, parentGroup);
1304
1305 return ERR_NONE;
1306}
1307
1308/*
1309 * Return the active threads and thread groups that are part of the
1310 * specified thread group.
1311 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001312static JdwpError TGR_Children(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001313 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001314 ObjectId thread_group_id = ReadThreadGroupId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001315
Elliott Hughescaf76542012-06-28 16:08:22 -07001316 std::vector<ObjectId> thread_ids;
1317 Dbg::GetThreads(thread_group_id, thread_ids);
1318 expandBufAdd4BE(pReply, thread_ids.size());
1319 for (uint32_t i = 0; i < thread_ids.size(); ++i) {
1320 expandBufAddObjectId(pReply, thread_ids[i]);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001321 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001322
Elliott Hughescaf76542012-06-28 16:08:22 -07001323 std::vector<ObjectId> child_thread_groups_ids;
1324 Dbg::GetChildThreadGroups(thread_group_id, child_thread_groups_ids);
1325 expandBufAdd4BE(pReply, child_thread_groups_ids.size());
1326 for (uint32_t i = 0; i < child_thread_groups_ids.size(); ++i) {
1327 expandBufAddObjectId(pReply, child_thread_groups_ids[i]);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001328 }
1329
1330 return ERR_NONE;
1331}
1332
1333/*
1334 * Return the #of components in the array.
1335 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001336static JdwpError AR_Length(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001337 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001338 ObjectId array_id = ReadArrayId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001339
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -08001340 int length;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001341 JdwpError status = Dbg::GetArrayLength(array_id, length);
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -08001342 if (status != ERR_NONE) {
1343 return status;
1344 }
Elliott Hughes2435a572012-02-17 16:07:41 -08001345 VLOG(jdwp) << " --> " << length;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001346
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -08001347 expandBufAdd4BE(pReply, length);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001348
1349 return ERR_NONE;
1350}
1351
1352/*
1353 * Return the values from an array.
1354 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001355static JdwpError AR_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001356 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001357 ObjectId array_id = ReadArrayId(&buf);
1358 uint32_t offset = ReadUnsigned32("offset", &buf);
1359 uint32_t length = ReadUnsigned32("length", &buf);
1360 return Dbg::OutputArray(array_id, offset, length, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001361}
1362
1363/*
1364 * Set values in an array.
1365 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001366static JdwpError AR_SetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001367 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001368 ObjectId array_id = ReadArrayId(&buf);
1369 uint32_t offset = ReadUnsigned32("offset", &buf);
1370 uint32_t length = ReadUnsigned32("length", &buf);
1371 return Dbg::SetArrayElements(array_id, offset, length, buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001372}
1373
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001374static JdwpError CLR_VisibleClasses(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001375 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromfd2ec542012-05-02 15:08:57 -07001376 ReadObjectId(&buf); // classLoaderObject
Elliott Hughes86964332012-02-15 19:37:42 -08001377 // TODO: we should only return classes which have the given class loader as a defining or
1378 // initiating loader. The former would be easy; the latter is hard, because we don't have
1379 // any such notion.
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001380 return VM_AllClassesImpl(pReply, false, false);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001381}
1382
1383/*
1384 * Set an event trigger.
1385 *
1386 * Reply with a requestID.
1387 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001388static JdwpError ER_Set(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001389 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001390 const uint8_t* origBuf = buf;
1391
Elliott Hughesf7c3b662011-10-27 12:04:56 -07001392 uint8_t eventKind = Read1(&buf);
Elliott Hughesf8349362012-06-18 15:00:06 -07001393 uint8_t suspend_policy = Read1(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -08001394 int32_t modifier_count = ReadSigned32("modifier count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001395
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001396 VLOG(jdwp) << " Set(kind=" << JdwpEventKind(eventKind)
Elliott Hughesf8349362012-06-18 15:00:06 -07001397 << " suspend=" << JdwpSuspendPolicy(suspend_policy)
Elliott Hughesa96836a2013-01-17 12:27:49 -08001398 << " mods=" << modifier_count << ")";
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001399
Elliott Hughesa96836a2013-01-17 12:27:49 -08001400 CHECK_LT(modifier_count, 256); /* reasonableness check */
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001401
Elliott Hughesa96836a2013-01-17 12:27:49 -08001402 JdwpEvent* pEvent = EventAlloc(modifier_count);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001403 pEvent->eventKind = static_cast<JdwpEventKind>(eventKind);
Elliott Hughesf8349362012-06-18 15:00:06 -07001404 pEvent->suspend_policy = static_cast<JdwpSuspendPolicy>(suspend_policy);
Elliott Hughesa96836a2013-01-17 12:27:49 -08001405 pEvent->modCount = modifier_count;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001406
1407 /*
1408 * Read modifiers. Ordering may be significant (see explanation of Count
1409 * mods in JDWP doc).
1410 */
Elliott Hughesa96836a2013-01-17 12:27:49 -08001411 for (int32_t i = 0; i < modifier_count; ++i) {
Elliott Hughes972a47b2012-02-21 18:16:06 -08001412 JdwpEventMod& mod = pEvent->mods[i];
Elliott Hughesa96836a2013-01-17 12:27:49 -08001413 mod.modKind = ReadModKind(&buf);
Elliott Hughes972a47b2012-02-21 18:16:06 -08001414 switch (mod.modKind) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001415 case MK_COUNT:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001416 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001417 // Report once, when "--count" reaches 0.
1418 uint32_t count = ReadUnsigned32("count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001419 if (count == 0) {
1420 return ERR_INVALID_COUNT;
1421 }
Elliott Hughes972a47b2012-02-21 18:16:06 -08001422 mod.count.count = count;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001423 }
1424 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001425 case MK_CONDITIONAL:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001426 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001427 // Conditional on expression.
1428 uint32_t exprId = ReadUnsigned32("expr id", &buf);
Elliott Hughes972a47b2012-02-21 18:16:06 -08001429 mod.conditional.exprId = exprId;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001430 }
1431 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001432 case MK_THREAD_ONLY:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001433 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001434 // Only report events in specified thread.
1435 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -07001436 mod.threadOnly.threadId = thread_id;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001437 }
1438 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001439 case MK_CLASS_ONLY:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001440 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001441 // For ClassPrepare, MethodEntry.
Elliott Hughes74847412012-06-20 18:10:21 -07001442 RefTypeId class_id = ReadRefTypeId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -07001443 mod.classOnly.refTypeId = class_id;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001444 }
1445 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001446 case MK_CLASS_MATCH:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001447 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001448 // Restrict events to matching classes.
Elliott Hughes86964332012-02-15 19:37:42 -08001449 // pattern is "java.foo.*", we want "java/foo/*".
Elliott Hughesa96836a2013-01-17 12:27:49 -08001450 std::string pattern(ReadUtf8String(&buf));
Elliott Hughes86964332012-02-15 19:37:42 -08001451 std::replace(pattern.begin(), pattern.end(), '.', '/');
Elliott Hughes972a47b2012-02-21 18:16:06 -08001452 mod.classMatch.classPattern = strdup(pattern.c_str());
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001453 }
1454 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001455 case MK_CLASS_EXCLUDE:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001456 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001457 // Restrict events to non-matching classes.
Elliott Hughes86964332012-02-15 19:37:42 -08001458 // pattern is "java.foo.*", we want "java/foo/*".
Elliott Hughesa96836a2013-01-17 12:27:49 -08001459 std::string pattern(ReadUtf8String(&buf));
Elliott Hughes86964332012-02-15 19:37:42 -08001460 std::replace(pattern.begin(), pattern.end(), '.', '/');
Elliott Hughes972a47b2012-02-21 18:16:06 -08001461 mod.classExclude.classPattern = strdup(pattern.c_str());
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001462 }
1463 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001464 case MK_LOCATION_ONLY:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001465 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001466 // Restrict certain events based on location.
1467 JdwpLocation location = ReadLocation(&buf);
1468 mod.locationOnly.loc = location;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001469 }
1470 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001471 case MK_EXCEPTION_ONLY:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001472 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001473 // Modifies EK_EXCEPTION events,
1474 RefTypeId exceptionOrNull = ReadRefTypeId(&buf); // null => all exceptions.
1475 uint8_t caught = Read1(&buf);
1476 uint8_t uncaught = Read1(&buf);
Elliott Hughes229feb72012-02-23 13:33:29 -08001477 VLOG(jdwp) << StringPrintf(" ExceptionOnly: type=%#llx(%s) caught=%d uncaught=%d",
Elliott Hughesc308a5d2012-02-16 17:12:06 -08001478 exceptionOrNull, (exceptionOrNull == 0) ? "null" : Dbg::GetClassName(exceptionOrNull).c_str(), caught, uncaught);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001479
Elliott Hughes972a47b2012-02-21 18:16:06 -08001480 mod.exceptionOnly.refTypeId = exceptionOrNull;
1481 mod.exceptionOnly.caught = caught;
1482 mod.exceptionOnly.uncaught = uncaught;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001483 }
1484 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001485 case MK_FIELD_ONLY:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001486 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001487 // For field access/modification events.
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001488 RefTypeId declaring = ReadRefTypeId(&buf);
1489 FieldId fieldId = ReadFieldId(&buf);
Elliott Hughes972a47b2012-02-21 18:16:06 -08001490 mod.fieldOnly.refTypeId = declaring;
1491 mod.fieldOnly.fieldId = fieldId;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001492 }
1493 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001494 case MK_STEP:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001495 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001496 // For use with EK_SINGLE_STEP.
1497 ObjectId thread_id = ReadThreadId(&buf);
1498 uint32_t size = Read4BE(&buf);
1499 uint32_t depth = Read4BE(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -07001500 VLOG(jdwp) << StringPrintf(" Step: thread=%#llx", thread_id)
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001501 << " size=" << JdwpStepSize(size) << " depth=" << JdwpStepDepth(depth);
1502
Elliott Hughes74847412012-06-20 18:10:21 -07001503 mod.step.threadId = thread_id;
Elliott Hughes972a47b2012-02-21 18:16:06 -08001504 mod.step.size = size;
1505 mod.step.depth = depth;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001506 }
1507 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001508 case MK_INSTANCE_ONLY:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001509 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001510 // Report events related to a specific object.
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001511 ObjectId instance = ReadObjectId(&buf);
Elliott Hughes972a47b2012-02-21 18:16:06 -08001512 mod.instanceOnly.objectId = instance;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001513 }
1514 break;
1515 default:
Elliott Hughes972a47b2012-02-21 18:16:06 -08001516 LOG(WARNING) << "GLITCH: unsupported modKind=" << mod.modKind;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001517 break;
1518 }
1519 }
1520
1521 /*
1522 * Make sure we consumed all data. It is possible that the remote side
1523 * has sent us bad stuff, but for now we blame ourselves.
1524 */
1525 if (buf != origBuf + dataLen) {
1526 LOG(WARNING) << "GLITCH: dataLen is " << dataLen << ", we have consumed " << (buf - origBuf);
1527 }
1528
1529 /*
1530 * We reply with an integer "requestID".
1531 */
Elliott Hughes376a7a02011-10-24 18:35:55 -07001532 uint32_t requestId = state->NextEventSerial();
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001533 expandBufAdd4BE(pReply, requestId);
1534
1535 pEvent->requestId = requestId;
1536
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001537 VLOG(jdwp) << StringPrintf(" --> event requestId=%#x", requestId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001538
1539 /* add it to the list */
Elliott Hughes761928d2011-11-16 18:33:03 -08001540 JdwpError err = state->RegisterEvent(pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001541 if (err != ERR_NONE) {
1542 /* registration failed, probably because event is bogus */
1543 EventFree(pEvent);
1544 LOG(WARNING) << "WARNING: event request rejected";
1545 }
1546 return err;
1547}
1548
1549/*
1550 * Clear an event. Failure to find an event with a matching ID is a no-op
1551 * and does not return an error.
1552 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001553static JdwpError ER_Clear(JdwpState* state, const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001554 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001555 uint8_t eventKind = Read1(&buf);
Elliott Hughesf7c3b662011-10-27 12:04:56 -07001556 uint32_t requestId = Read4BE(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001557
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001558 VLOG(jdwp) << StringPrintf(" Req to clear eventKind=%d requestId=%#x", eventKind, requestId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001559
Elliott Hughes761928d2011-11-16 18:33:03 -08001560 state->UnregisterEventById(requestId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001561
1562 return ERR_NONE;
1563}
1564
1565/*
1566 * Return the values of arguments and local variables.
1567 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001568static JdwpError SF_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001569 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001570 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes546b9862012-06-20 16:06:13 -07001571 FrameId frame_id = ReadFrameId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -08001572 int32_t slot_count = ReadSigned32("slot count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001573
Elliott Hughesa96836a2013-01-17 12:27:49 -08001574 expandBufAdd4BE(pReply, slot_count); /* "int values" */
1575 for (int32_t i = 0; i < slot_count; ++i) {
1576 uint32_t slot = ReadUnsigned32("slot", &buf);
Elliott Hughesaed4be92011-12-02 16:16:23 -08001577 JDWP::JdwpTag reqSigByte = ReadTag(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001578
Elliott Hughes2435a572012-02-17 16:07:41 -08001579 VLOG(jdwp) << " --> slot " << slot << " " << reqSigByte;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001580
Elliott Hughesdbb40792011-11-18 17:05:22 -08001581 size_t width = Dbg::GetTagWidth(reqSigByte);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001582 uint8_t* ptr = expandBufAddSpace(pReply, width+1);
Elliott Hughes74847412012-06-20 18:10:21 -07001583 Dbg::GetLocalValue(thread_id, frame_id, slot, reqSigByte, ptr, width);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001584 }
1585
1586 return ERR_NONE;
1587}
1588
1589/*
1590 * Set the values of arguments and local variables.
1591 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001592static JdwpError SF_SetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001593 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001594 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes546b9862012-06-20 16:06:13 -07001595 FrameId frame_id = ReadFrameId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -08001596 int32_t slot_count = ReadSigned32("slot count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001597
Elliott Hughesa96836a2013-01-17 12:27:49 -08001598 for (int32_t i = 0; i < slot_count; ++i) {
1599 uint32_t slot = ReadUnsigned32("slot", &buf);
Elliott Hughesaed4be92011-12-02 16:16:23 -08001600 JDWP::JdwpTag sigByte = ReadTag(&buf);
Elliott Hughesdbb40792011-11-18 17:05:22 -08001601 size_t width = Dbg::GetTagWidth(sigByte);
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001602 uint64_t value = ReadValue(&buf, width);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001603
Elliott Hughes2435a572012-02-17 16:07:41 -08001604 VLOG(jdwp) << " --> slot " << slot << " " << sigByte << " " << value;
Elliott Hughes74847412012-06-20 18:10:21 -07001605 Dbg::SetLocalValue(thread_id, frame_id, slot, sigByte, value, width);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001606 }
1607
1608 return ERR_NONE;
1609}
1610
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001611static JdwpError SF_ThisObject(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001612 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001613 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes546b9862012-06-20 16:06:13 -07001614 FrameId frame_id = ReadFrameId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001615
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001616 ObjectId object_id;
1617 JdwpError rc = Dbg::GetThisObject(thread_id, frame_id, &object_id);
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001618 if (rc != ERR_NONE) {
1619 return rc;
Elliott Hughes546b9862012-06-20 16:06:13 -07001620 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001621
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001622 return WriteTaggedObject(reply, object_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001623}
1624
1625/*
1626 * Return the reference type reflected by this class object.
1627 *
1628 * This appears to be required because ReferenceTypeId values are NEVER
1629 * reused, whereas ClassIds can be recycled like any other object. (Either
1630 * that, or I have no idea what this is for.)
1631 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001632static JdwpError COR_ReflectedType(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001633 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001634 RefTypeId class_object_id = ReadRefTypeId(&buf);
1635 return Dbg::GetReflectedType(class_object_id, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001636}
1637
1638/*
1639 * Handle a DDM packet with a single chunk in it.
1640 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001641static JdwpError DDM_Chunk(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001642 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001643 uint8_t* replyBuf = NULL;
1644 int replyLen = -1;
1645
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001646 VLOG(jdwp) << StringPrintf(" Handling DDM packet (%.4s)", buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001647
Elliott Hughesa21039c2012-06-21 12:09:25 -07001648 state->NotifyDdmsActive();
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001649
1650 /*
1651 * If they want to send something back, we copy it into the buffer.
1652 * A no-copy approach would be nicer.
1653 *
1654 * TODO: consider altering the JDWP stuff to hold the packet header
1655 * in a separate buffer. That would allow us to writev() DDM traffic
1656 * instead of copying it into the expanding buffer. The reduction in
1657 * heap requirements is probably more valuable than the efficiency.
1658 */
1659 if (Dbg::DdmHandlePacket(buf, dataLen, &replyBuf, &replyLen)) {
1660 CHECK(replyLen > 0 && replyLen < 1*1024*1024);
1661 memcpy(expandBufAddSpace(pReply, replyLen), replyBuf, replyLen);
1662 free(replyBuf);
1663 }
1664 return ERR_NONE;
1665}
1666
1667/*
1668 * Handler map decl.
1669 */
1670typedef JdwpError (*JdwpRequestHandler)(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* reply);
1671
1672struct JdwpHandlerMap {
1673 uint8_t cmdSet;
1674 uint8_t cmd;
1675 JdwpRequestHandler func;
1676 const char* descr;
1677};
1678
1679/*
1680 * Map commands to functions.
1681 *
1682 * Command sets 0-63 are incoming requests, 64-127 are outbound requests,
1683 * and 128-256 are vendor-defined.
1684 */
1685static const JdwpHandlerMap gHandlerMap[] = {
1686 /* VirtualMachine command set (1) */
Elliott Hughesf327e072013-01-09 16:01:26 -08001687 { 1, 1, VM_Version, "VirtualMachine.Version" },
1688 { 1, 2, VM_ClassesBySignature, "VirtualMachine.ClassesBySignature" },
1689 { 1, 3, VM_AllClasses, "VirtualMachine.AllClasses" },
1690 { 1, 4, VM_AllThreads, "VirtualMachine.AllThreads" },
1691 { 1, 5, VM_TopLevelThreadGroups, "VirtualMachine.TopLevelThreadGroups" },
1692 { 1, 6, VM_Dispose, "VirtualMachine.Dispose" },
1693 { 1, 7, VM_IDSizes, "VirtualMachine.IDSizes" },
1694 { 1, 8, VM_Suspend, "VirtualMachine.Suspend" },
1695 { 1, 9, VM_Resume, "VirtualMachine.Resume" },
1696 { 1, 10, VM_Exit, "VirtualMachine.Exit" },
1697 { 1, 11, VM_CreateString, "VirtualMachine.CreateString" },
1698 { 1, 12, VM_Capabilities, "VirtualMachine.Capabilities" },
1699 { 1, 13, VM_ClassPaths, "VirtualMachine.ClassPaths" },
1700 { 1, 14, VM_DisposeObjects, "VirtualMachine.DisposeObjects" },
1701 { 1, 15, NULL, "VirtualMachine.HoldEvents" },
1702 { 1, 16, NULL, "VirtualMachine.ReleaseEvents" },
1703 { 1, 17, VM_CapabilitiesNew, "VirtualMachine.CapabilitiesNew" },
1704 { 1, 18, NULL, "VirtualMachine.RedefineClasses" },
1705 { 1, 19, NULL, "VirtualMachine.SetDefaultStratum" },
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001706 { 1, 20, VM_AllClassesWithGeneric, "VirtualMachine.AllClassesWithGeneric" },
Elliott Hughesec0f83d2013-01-15 16:54:08 -08001707 { 1, 21, VM_InstanceCounts, "VirtualMachine.InstanceCounts" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001708
1709 /* ReferenceType command set (2) */
Elliott Hughesf327e072013-01-09 16:01:26 -08001710 { 2, 1, RT_Signature, "ReferenceType.Signature" },
1711 { 2, 2, RT_ClassLoader, "ReferenceType.ClassLoader" },
1712 { 2, 3, RT_Modifiers, "ReferenceType.Modifiers" },
1713 { 2, 4, RT_Fields, "ReferenceType.Fields" },
1714 { 2, 5, RT_Methods, "ReferenceType.Methods" },
1715 { 2, 6, RT_GetValues, "ReferenceType.GetValues" },
1716 { 2, 7, RT_SourceFile, "ReferenceType.SourceFile" },
1717 { 2, 8, NULL, "ReferenceType.NestedTypes" },
1718 { 2, 9, RT_Status, "ReferenceType.Status" },
1719 { 2, 10, RT_Interfaces, "ReferenceType.Interfaces" },
1720 { 2, 11, RT_ClassObject, "ReferenceType.ClassObject" },
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001721 { 2, 12, RT_SourceDebugExtension, "ReferenceType.SourceDebugExtension" },
1722 { 2, 13, RT_SignatureWithGeneric, "ReferenceType.SignatureWithGeneric" },
Elliott Hughesf327e072013-01-09 16:01:26 -08001723 { 2, 14, RT_FieldsWithGeneric, "ReferenceType.FieldsWithGeneric" },
1724 { 2, 15, RT_MethodsWithGeneric, "ReferenceType.MethodsWithGeneric" },
Elliott Hughes3b78c942013-01-15 17:35:41 -08001725 { 2, 16, RT_Instances, "ReferenceType.Instances" },
Elliott Hughesf327e072013-01-09 16:01:26 -08001726 { 2, 17, NULL, "ReferenceType.ClassFileVersion" },
1727 { 2, 18, NULL, "ReferenceType.ConstantPool" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001728
1729 /* ClassType command set (3) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001730 { 3, 1, CT_Superclass, "ClassType.Superclass" },
1731 { 3, 2, CT_SetValues, "ClassType.SetValues" },
1732 { 3, 3, CT_InvokeMethod, "ClassType.InvokeMethod" },
1733 { 3, 4, CT_NewInstance, "ClassType.NewInstance" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001734
1735 /* ArrayType command set (4) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001736 { 4, 1, AT_newInstance, "ArrayType.NewInstance" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001737
1738 /* InterfaceType command set (5) */
1739
1740 /* Method command set (6) */
Elliott Hughesf327e072013-01-09 16:01:26 -08001741 { 6, 1, M_LineTable, "Method.LineTable" },
1742 { 6, 2, M_VariableTable, "Method.VariableTable" },
Elliott Hughes9777ba22013-01-17 09:04:19 -08001743 { 6, 3, M_Bytecodes, "Method.Bytecodes" },
Elliott Hughesf327e072013-01-09 16:01:26 -08001744 { 6, 4, NULL, "Method.IsObsolete" },
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001745 { 6, 5, M_VariableTableWithGeneric, "Method.VariableTableWithGeneric" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001746
1747 /* Field command set (8) */
1748
1749 /* ObjectReference command set (9) */
Elliott Hughesf327e072013-01-09 16:01:26 -08001750 { 9, 1, OR_ReferenceType, "ObjectReference.ReferenceType" },
1751 { 9, 2, OR_GetValues, "ObjectReference.GetValues" },
1752 { 9, 3, OR_SetValues, "ObjectReference.SetValues" },
1753 { 9, 4, NULL, "ObjectReference.UNUSED" },
1754 { 9, 5, OR_MonitorInfo, "ObjectReference.MonitorInfo" },
1755 { 9, 6, OR_InvokeMethod, "ObjectReference.InvokeMethod" },
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001756 { 9, 7, OR_DisableCollection, "ObjectReference.DisableCollection" },
Elliott Hughesf327e072013-01-09 16:01:26 -08001757 { 9, 8, OR_EnableCollection, "ObjectReference.EnableCollection" },
1758 { 9, 9, OR_IsCollected, "ObjectReference.IsCollected" },
Elliott Hughes0cbaff52013-01-16 15:28:01 -08001759 { 9, 10, OR_ReferringObjects, "ObjectReference.ReferringObjects" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001760
1761 /* StringReference command set (10) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001762 { 10, 1, SR_Value, "StringReference.Value" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001763
1764 /* ThreadReference command set (11) */
Elliott Hughes734b8c62013-01-11 15:32:45 -08001765 { 11, 1, TR_Name, "ThreadReference.Name" },
1766 { 11, 2, TR_Suspend, "ThreadReference.Suspend" },
1767 { 11, 3, TR_Resume, "ThreadReference.Resume" },
1768 { 11, 4, TR_Status, "ThreadReference.Status" },
1769 { 11, 5, TR_ThreadGroup, "ThreadReference.ThreadGroup" },
1770 { 11, 6, TR_Frames, "ThreadReference.Frames" },
1771 { 11, 7, TR_FrameCount, "ThreadReference.FrameCount" },
1772 { 11, 8, TR_OwnedMonitors, "ThreadReference.OwnedMonitors" },
1773 { 11, 9, TR_CurrentContendedMonitor, "ThreadReference.CurrentContendedMonitor" },
1774 { 11, 10, NULL, "ThreadReference.Stop" },
1775 { 11, 11, TR_Interrupt, "ThreadReference.Interrupt" },
1776 { 11, 12, TR_DebugSuspendCount, "ThreadReference.SuspendCount" },
1777 { 11, 13, TR_OwnedMonitorsStackDepthInfo, "ThreadReference.OwnedMonitorsStackDepthInfo" },
1778 { 11, 14, NULL, "ThreadReference.ForceEarlyReturn" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001779
1780 /* ThreadGroupReference command set (12) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001781 { 12, 1, TGR_Name, "ThreadGroupReference.Name" },
1782 { 12, 2, TGR_Parent, "ThreadGroupReference.Parent" },
1783 { 12, 3, TGR_Children, "ThreadGroupReference.Children" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001784
1785 /* ArrayReference command set (13) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001786 { 13, 1, AR_Length, "ArrayReference.Length" },
1787 { 13, 2, AR_GetValues, "ArrayReference.GetValues" },
1788 { 13, 3, AR_SetValues, "ArrayReference.SetValues" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001789
1790 /* ClassLoaderReference command set (14) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001791 { 14, 1, CLR_VisibleClasses, "ClassLoaderReference.VisibleClasses" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001792
1793 /* EventRequest command set (15) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001794 { 15, 1, ER_Set, "EventRequest.Set" },
1795 { 15, 2, ER_Clear, "EventRequest.Clear" },
Elliott Hughesf327e072013-01-09 16:01:26 -08001796 { 15, 3, NULL, "EventRequest.ClearAllBreakpoints" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001797
1798 /* StackFrame command set (16) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001799 { 16, 1, SF_GetValues, "StackFrame.GetValues" },
1800 { 16, 2, SF_SetValues, "StackFrame.SetValues" },
1801 { 16, 3, SF_ThisObject, "StackFrame.ThisObject" },
Elliott Hughesf327e072013-01-09 16:01:26 -08001802 { 16, 4, NULL, "StackFrame.PopFrames" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001803
1804 /* ClassObjectReference command set (17) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001805 { 17, 1, COR_ReflectedType, "ClassObjectReference.ReflectedType" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001806
1807 /* Event command set (64) */
Elliott Hughesf327e072013-01-09 16:01:26 -08001808 { 64, 100, NULL, "Event.Composite" }, // sent from VM to debugger, never received by VM
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001809
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001810 { 199, 1, DDM_Chunk, "DDM.Chunk" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001811};
1812
Elliott Hughesa3c24aa2011-12-07 15:34:09 -08001813static const char* GetCommandName(size_t cmdSet, size_t cmd) {
Elliott Hughes74847412012-06-20 18:10:21 -07001814 for (size_t i = 0; i < arraysize(gHandlerMap); ++i) {
Elliott Hughesa3c24aa2011-12-07 15:34:09 -08001815 if (gHandlerMap[i].cmdSet == cmdSet && gHandlerMap[i].cmd == cmd) {
1816 return gHandlerMap[i].descr;
1817 }
1818 }
1819 return "?UNKNOWN?";
1820}
1821
1822static std::string DescribeCommand(const JdwpReqHeader* pHeader, int dataLen) {
1823 std::string result;
1824 result += "REQ: ";
1825 result += GetCommandName(pHeader->cmdSet, pHeader->cmd);
1826 result += StringPrintf(" (dataLen=%d id=0x%06x)", dataLen, pHeader->id);
1827 return result;
1828}
1829
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001830/*
1831 * Process a request from the debugger.
1832 *
1833 * On entry, the JDWP thread is in VMWAIT.
1834 */
Elliott Hughes376a7a02011-10-24 18:35:55 -07001835void JdwpState::ProcessRequest(const JdwpReqHeader* pHeader, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001836 JdwpError result = ERR_NONE;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001837
1838 if (pHeader->cmdSet != kJDWPDdmCmdSet) {
1839 /*
1840 * Activity from a debugger, not merely ddms. Mark us as having an
1841 * active debugger session, and zero out the last-activity timestamp
1842 * so waitForDebugger() doesn't return if we stall for a bit here.
1843 */
Elliott Hughesa2155262011-11-16 16:26:58 -08001844 Dbg::GoActive();
Ian Rogers9adbff52013-01-23 18:19:03 -08001845 QuasiAtomic::Write64(&last_activity_time_ms_, 0);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001846 }
1847
1848 /*
1849 * If a debugger event has fired in another thread, wait until the
1850 * initiating thread has suspended itself before processing messages
1851 * from the debugger. Otherwise we (the JDWP thread) could be told to
1852 * resume the thread before it has suspended.
1853 *
1854 * We call with an argument of zero to wait for the current event
1855 * thread to finish, and then clear the block. Depending on the thread
1856 * suspend policy, this may allow events in other threads to fire,
1857 * but those events have no bearing on what the debugger has sent us
1858 * in the current request.
1859 *
1860 * Note that we MUST clear the event token before waking the event
1861 * thread up, or risk waiting for the thread to suspend after we've
1862 * told it to resume.
1863 */
Elliott Hughes376a7a02011-10-24 18:35:55 -07001864 SetWaitForEventThread(0);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001865
1866 /*
1867 * Tell the VM that we're running and shouldn't be interrupted by GC.
1868 * Do this after anything that can stall indefinitely.
1869 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001870 Thread* self = Thread::Current();
1871 ThreadState old_state = self->TransitionFromSuspendedToRunnable();
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001872
1873 expandBufAddSpace(pReply, kJDWPHeaderLen);
1874
Elliott Hughesa3c24aa2011-12-07 15:34:09 -08001875 size_t i;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001876 for (i = 0; i < arraysize(gHandlerMap); ++i) {
Elliott Hughesa3c24aa2011-12-07 15:34:09 -08001877 if (gHandlerMap[i].cmdSet == pHeader->cmdSet && gHandlerMap[i].cmd == pHeader->cmd && gHandlerMap[i].func != NULL) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001878 VLOG(jdwp) << DescribeCommand(pHeader, dataLen);
Elliott Hughes376a7a02011-10-24 18:35:55 -07001879 result = (*gHandlerMap[i].func)(this, buf, dataLen, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001880 break;
1881 }
1882 }
1883 if (i == arraysize(gHandlerMap)) {
Elliott Hughesbfbf0e22012-03-29 18:09:19 -07001884 LOG(ERROR) << "Command not implemented: " << DescribeCommand(pHeader, dataLen);
1885 LOG(ERROR) << HexDump(buf, dataLen);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001886 result = ERR_NOT_IMPLEMENTED;
1887 }
1888
1889 /*
1890 * Set up the reply header.
1891 *
1892 * If we encountered an error, only send the header back.
1893 */
1894 uint8_t* replyBuf = expandBufGetBuffer(pReply);
Elliott Hughesf7c3b662011-10-27 12:04:56 -07001895 Set4BE(replyBuf + 4, pHeader->id);
1896 Set1(replyBuf + 8, kJDWPFlagReply);
1897 Set2BE(replyBuf + 9, result);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001898 if (result == ERR_NONE) {
Elliott Hughesf7c3b662011-10-27 12:04:56 -07001899 Set4BE(replyBuf + 0, expandBufGetLength(pReply));
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001900 } else {
Elliott Hughesf7c3b662011-10-27 12:04:56 -07001901 Set4BE(replyBuf + 0, kJDWPHeaderLen);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001902 }
1903
Elliott Hughesa3c24aa2011-12-07 15:34:09 -08001904 size_t respLen = expandBufGetLength(pReply) - kJDWPHeaderLen;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001905 if (false) {
1906 LOG(INFO) << "reply: dataLen=" << respLen << " err=" << result << (result != ERR_NONE ? " **FAILED**" : "");
Elliott Hughesbfbf0e22012-03-29 18:09:19 -07001907 LOG(INFO) << HexDump(expandBufGetBuffer(pReply) + kJDWPHeaderLen, respLen);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001908 }
1909
1910 /*
1911 * Update last-activity timestamp. We really only need this during
1912 * the initial setup. Only update if this is a non-DDMS packet.
1913 */
1914 if (pHeader->cmdSet != kJDWPDdmCmdSet) {
Ian Rogers9adbff52013-01-23 18:19:03 -08001915 QuasiAtomic::Write64(&last_activity_time_ms_, MilliTime());
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001916 }
1917
1918 /* tell the VM that GC is okay again */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001919 self->TransitionFromRunnableToSuspended(old_state);
1920
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001921}
1922
1923} // namespace JDWP
1924
1925} // namespace art