blob: aa5a8a05d7bdd6243864fd33ec34abe48096e2b0 [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"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080045#include "runtime.h"
46#include "thread.h"
47#include "UniquePtr.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080048
Elliott Hughes872d4ec2011-10-21 17:07:15 -070049namespace art {
50
51namespace JDWP {
52
Elliott Hughesa96836a2013-01-17 12:27:49 -080053static std::string DescribeField(const FieldId& field_id)
54 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
55 return StringPrintf("%#x (%s)", field_id, Dbg::GetFieldName(field_id).c_str());
56}
57
58static std::string DescribeMethod(const MethodId& method_id)
59 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
60 return StringPrintf("%#x (%s)", method_id, Dbg::GetMethodName(method_id).c_str());
61}
62
63static std::string DescribeRefTypeId(const RefTypeId& ref_type_id)
64 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
65 std::string signature("unknown");
66 Dbg::GetSignature(ref_type_id, signature);
67 return StringPrintf("%#llx (%s)", ref_type_id, signature.c_str());
Elliott Hughes872d4ec2011-10-21 17:07:15 -070068}
69
70/*
Elliott Hughes872d4ec2011-10-21 17:07:15 -070071 * Helper function: read a variable-width value from the input buffer.
72 */
Elliott Hughes4993bbc2013-01-10 15:41:25 -080073static uint64_t ReadValue(const uint8_t** pBuf, size_t width) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -070074 uint64_t value = -1;
75 switch (width) {
Elliott Hughesf7c3b662011-10-27 12:04:56 -070076 case 1: value = Read1(pBuf); break;
77 case 2: value = Read2BE(pBuf); break;
78 case 4: value = Read4BE(pBuf); break;
79 case 8: value = Read8BE(pBuf); break;
Elliott Hughes872d4ec2011-10-21 17:07:15 -070080 default: LOG(FATAL) << width; break;
81 }
82 return value;
83}
84
Elliott Hughesa96836a2013-01-17 12:27:49 -080085static int32_t ReadSigned32(const char* what, const uint8_t** pBuf) {
86 int32_t value = static_cast<int32_t>(Read4BE(pBuf));
87 VLOG(jdwp) << " " << what << " " << value;
88 return value;
89}
90
91uint32_t ReadUnsigned32(const char* what, const uint8_t** pBuf) {
92 uint32_t value = Read4BE(pBuf);
93 VLOG(jdwp) << " " << what << " " << value;
94 return value;
95}
96
97static FieldId ReadFieldId(const uint8_t** pBuf) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
98 FieldId id = Read4BE(pBuf);
99 VLOG(jdwp) << " field id " << DescribeField(id);
100 return id;
101}
102
103static MethodId ReadMethodId(const uint8_t** pBuf) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
104 MethodId id = Read4BE(pBuf);
105 VLOG(jdwp) << " method id " << DescribeMethod(id);
106 return id;
107}
108
109static ObjectId ReadObjectId(const char* specific_kind, const uint8_t** pBuf) {
110 ObjectId id = Read8BE(pBuf);
111 VLOG(jdwp) << StringPrintf(" %s id %#llx", specific_kind, id);
112 return id;
113}
114
115static ObjectId ReadArrayId(const uint8_t** pBuf) {
116 return ReadObjectId("array", pBuf);
117}
118
119ObjectId ReadObjectId(const uint8_t** pBuf) {
120 return ReadObjectId("object", pBuf);
121}
122
123static ObjectId ReadThreadId(const uint8_t** pBuf) {
124 return ReadObjectId("thread", pBuf);
125}
126
127static ObjectId ReadThreadGroupId(const uint8_t** pBuf) {
128 return ReadObjectId("thread group", pBuf);
129}
130
131static RefTypeId ReadRefTypeId(const uint8_t** pBuf) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
132 RefTypeId id = Read8BE(pBuf);
133 VLOG(jdwp) << " ref type id " << DescribeRefTypeId(id);
134 return id;
135}
136
137static FrameId ReadFrameId(const uint8_t** pBuf) {
138 FrameId id = Read8BE(pBuf);
139 VLOG(jdwp) << " frame id " << id;
140 return id;
141}
142
143static JdwpTag ReadTag(const uint8_t** pBuf) {
144 JdwpTag tag = static_cast<JdwpTag>(Read1(pBuf));
145 VLOG(jdwp) << " tag " << tag;
146 return tag;
147}
148
149static JdwpTypeTag ReadTypeTag(const uint8_t** pBuf) {
150 JdwpTypeTag tag = static_cast<JdwpTypeTag>(Read1(pBuf));
151 VLOG(jdwp) << " type tag " << tag;
152 return tag;
153}
154
155static JdwpLocation ReadLocation(const uint8_t** pBuf) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
156 JdwpLocation location;
157 memset(&location, 0, sizeof(location)); // Allows memcmp(3) later.
158 location.type_tag = ReadTypeTag(pBuf);
159 location.class_id = ReadObjectId(pBuf);
160 location.method_id = ReadMethodId(pBuf);
161 location.dex_pc = Read8BE(pBuf);
162 VLOG(jdwp) << " location " << location;
163 return location;
164}
165
166static std::string ReadUtf8String(unsigned char const** ppSrc) {
167 uint32_t length = Read4BE(ppSrc);
168 std::string s;
169 s.resize(length);
170 memcpy(&s[0], *ppSrc, length);
171 (*ppSrc) += length;
172 VLOG(jdwp) << " string \"" << s << "\"";
173 return s;
174}
175
176static JdwpModKind ReadModKind(const uint8_t** pBuf) {
177 JdwpModKind mod_kind = static_cast<JdwpModKind>(Read1(pBuf));
178 VLOG(jdwp) << " mod kind " << mod_kind;
179 return mod_kind;
180}
181
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700182/*
183 * Helper function: write a variable-width value into the output input buffer.
184 */
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800185static void WriteValue(ExpandBuf* pReply, int width, uint64_t value) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700186 switch (width) {
187 case 1: expandBufAdd1(pReply, value); break;
188 case 2: expandBufAdd2BE(pReply, value); break;
189 case 4: expandBufAdd4BE(pReply, value); break;
190 case 8: expandBufAdd8BE(pReply, value); break;
191 default: LOG(FATAL) << width; break;
192 }
193}
194
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800195static JdwpError WriteTaggedObject(ExpandBuf* reply, ObjectId object_id)
196 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
197 uint8_t tag;
198 JdwpError rc = Dbg::GetObjectTag(object_id, tag);
199 if (rc == ERR_NONE) {
200 expandBufAdd1(reply, tag);
201 expandBufAddObjectId(reply, object_id);
202 }
203 return rc;
204}
205
Elliott Hughes0cbaff52013-01-16 15:28:01 -0800206static JdwpError WriteTaggedObjectList(ExpandBuf* reply, const std::vector<ObjectId>& objects)
207 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
208 expandBufAdd4BE(reply, objects.size());
209 for (size_t i = 0; i < objects.size(); ++i) {
210 JdwpError rc = WriteTaggedObject(reply, objects[i]);
211 if (rc != ERR_NONE) {
212 return rc;
213 }
214 }
215 return ERR_NONE;
216}
217
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700218/*
219 * Common code for *_InvokeMethod requests.
220 *
Elliott Hughes74847412012-06-20 18:10:21 -0700221 * If "is_constructor" is set, this returns "object_id" rather than the
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700222 * expected-to-be-void return value of the called function.
223 */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700224static JdwpError FinishInvoke(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply,
Elliott Hughes74847412012-06-20 18:10:21 -0700225 ObjectId thread_id, ObjectId object_id,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700226 RefTypeId class_id, MethodId method_id, bool is_constructor)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700227 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700228 CHECK(!is_constructor || object_id != 0);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700229
Elliott Hughesa96836a2013-01-17 12:27:49 -0800230 int32_t arg_count = ReadSigned32("argument count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700231
Elliott Hughes74847412012-06-20 18:10:21 -0700232 VLOG(jdwp) << StringPrintf(" --> thread_id=%#llx object_id=%#llx", thread_id, object_id);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700233 VLOG(jdwp) << StringPrintf(" class_id=%#llx method_id=%x %s.%s", class_id,
234 method_id, Dbg::GetClassName(class_id).c_str(),
Elliott Hughesa96836a2013-01-17 12:27:49 -0800235 Dbg::GetMethodName(method_id).c_str());
Elliott Hughes45651fd2012-02-21 15:48:20 -0800236 VLOG(jdwp) << StringPrintf(" %d args:", arg_count);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700237
Elliott Hughes45651fd2012-02-21 15:48:20 -0800238 UniquePtr<JdwpTag[]> argTypes(arg_count > 0 ? new JdwpTag[arg_count] : NULL);
239 UniquePtr<uint64_t[]> argValues(arg_count > 0 ? new uint64_t[arg_count] : NULL);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800240 for (int32_t i = 0; i < arg_count; ++i) {
Elliott Hughes45651fd2012-02-21 15:48:20 -0800241 argTypes[i] = ReadTag(&buf);
242 size_t width = Dbg::GetTagWidth(argTypes[i]);
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800243 argValues[i] = ReadValue(&buf, width);
Elliott Hughes229feb72012-02-23 13:33:29 -0800244 VLOG(jdwp) << " " << argTypes[i] << StringPrintf("(%zd): %#llx", width, argValues[i]);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700245 }
246
Elliott Hughesf7c3b662011-10-27 12:04:56 -0700247 uint32_t options = Read4BE(&buf); /* enum InvokeOptions bit flags */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700248 VLOG(jdwp) << StringPrintf(" options=0x%04x%s%s", options,
249 (options & INVOKE_SINGLE_THREADED) ? " (SINGLE_THREADED)" : "",
250 (options & INVOKE_NONVIRTUAL) ? " (NONVIRTUAL)" : "");
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700251
Elliott Hughes45651fd2012-02-21 15:48:20 -0800252 JdwpTag resultTag;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700253 uint64_t resultValue;
254 ObjectId exceptObjId;
Elliott Hughes74847412012-06-20 18:10:21 -0700255 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 -0700256 if (err != ERR_NONE) {
Elliott Hughes45651fd2012-02-21 15:48:20 -0800257 return err;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700258 }
259
260 if (err == ERR_NONE) {
Elliott Hughes45651fd2012-02-21 15:48:20 -0800261 if (is_constructor) {
262 // If we invoked a constructor (which actually returns void), return the receiver,
263 // unless we threw, in which case we return NULL.
264 resultTag = JT_OBJECT;
Elliott Hughes74847412012-06-20 18:10:21 -0700265 resultValue = (exceptObjId == 0) ? object_id : 0;
Elliott Hughes45651fd2012-02-21 15:48:20 -0800266 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700267
Elliott Hughes45651fd2012-02-21 15:48:20 -0800268 size_t width = Dbg::GetTagWidth(resultTag);
269 expandBufAdd1(pReply, resultTag);
270 if (width != 0) {
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800271 WriteValue(pReply, width, resultValue);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700272 }
273 expandBufAdd1(pReply, JT_OBJECT);
274 expandBufAddObjectId(pReply, exceptObjId);
275
Elliott Hughes229feb72012-02-23 13:33:29 -0800276 VLOG(jdwp) << " --> returned " << resultTag << StringPrintf(" %#llx (except=%#llx)", resultValue, exceptObjId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700277
278 /* show detailed debug output */
279 if (resultTag == JT_STRING && exceptObjId == 0) {
280 if (resultValue != 0) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800281 VLOG(jdwp) << " string '" << Dbg::StringToUtf8(resultValue) << "'";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700282 } else {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800283 VLOG(jdwp) << " string (null)";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700284 }
285 }
286 }
287
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700288 return err;
289}
290
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700291static JdwpError VM_Version(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700292 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes927bd292013-01-17 10:40:13 -0800293 // Text information on runtime version.
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700294 std::string version(StringPrintf("Android Runtime %s", Runtime::Current()->GetVersion()));
Elliott Hughes4740cdf2011-12-07 14:07:12 -0800295 expandBufAddUtf8String(pReply, version);
Elliott Hughes927bd292013-01-17 10:40:13 -0800296
297 // JDWP version numbers, major and minor.
298 expandBufAdd4BE(pReply, 1);
299 expandBufAdd4BE(pReply, 6);
300
301 // "java.version".
302 expandBufAddUtf8String(pReply, "1.6.0");
303
304 // "java.vm.name".
305 expandBufAddUtf8String(pReply, "Dalvik");
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700306
307 return ERR_NONE;
308}
309
310/*
311 * Given a class JNI signature (e.g. "Ljava/lang/Error;"), return the
312 * referenceTypeID. We need to send back more than one if the class has
313 * been loaded by multiple class loaders.
314 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700315static JdwpError VM_ClassesBySignature(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700316 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -0800317 std::string classDescriptor(ReadUtf8String(&buf));
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700318
Elliott Hughes6fa602d2011-12-02 17:54:25 -0800319 std::vector<RefTypeId> ids;
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800320 Dbg::FindLoadedClassBySignature(classDescriptor.c_str(), ids);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700321
Elliott Hughes6fa602d2011-12-02 17:54:25 -0800322 expandBufAdd4BE(pReply, ids.size());
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700323
Elliott Hughes6fa602d2011-12-02 17:54:25 -0800324 for (size_t i = 0; i < ids.size(); ++i) {
325 // Get class vs. interface and status flags.
Elliott Hughes436e3722012-02-17 20:01:47 -0800326 JDWP::JdwpTypeTag type_tag;
327 uint32_t class_status;
328 JDWP::JdwpError status = Dbg::GetClassInfo(ids[i], &type_tag, &class_status, NULL);
329 if (status != ERR_NONE) {
330 return status;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800331 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700332
Elliott Hughes436e3722012-02-17 20:01:47 -0800333 expandBufAdd1(pReply, type_tag);
Elliott Hughes6fa602d2011-12-02 17:54:25 -0800334 expandBufAddRefTypeId(pReply, ids[i]);
Elliott Hughes436e3722012-02-17 20:01:47 -0800335 expandBufAdd4BE(pReply, class_status);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700336 }
337
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700338 return ERR_NONE;
339}
340
341/*
342 * Handle request for the thread IDs of all running threads.
343 *
344 * We exclude ourselves from the list, because we don't allow ourselves
345 * to be suspended, and that violates some JDWP expectations.
346 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700347static JdwpError VM_AllThreads(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700348 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughescaf76542012-06-28 16:08:22 -0700349 std::vector<ObjectId> thread_ids;
Elliott Hughes026b1462012-06-28 20:43:49 -0700350 Dbg::GetThreads(0, thread_ids);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700351
Elliott Hughescaf76542012-06-28 16:08:22 -0700352 expandBufAdd4BE(pReply, thread_ids.size());
353 for (uint32_t i = 0; i < thread_ids.size(); ++i) {
354 expandBufAddObjectId(pReply, thread_ids[i]);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700355 }
356
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700357 return ERR_NONE;
358}
359
360/*
361 * List all thread groups that do not have a parent.
362 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700363static JdwpError VM_TopLevelThreadGroups(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700364 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700365 /*
366 * TODO: maintain a list of parentless thread groups in the VM.
367 *
368 * For now, just return "system". Application threads are created
369 * in "main", which is a child of "system".
370 */
371 uint32_t groups = 1;
372 expandBufAdd4BE(pReply, groups);
Elliott Hughescaf76542012-06-28 16:08:22 -0700373 ObjectId thread_group_id = Dbg::GetSystemThreadGroupId();
374 expandBufAddObjectId(pReply, thread_group_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700375
376 return ERR_NONE;
377}
378
379/*
380 * Respond with the sizes of the basic debugger types.
381 *
382 * All IDs are 8 bytes.
383 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700384static JdwpError VM_IDSizes(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700385 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700386 expandBufAdd4BE(pReply, sizeof(FieldId));
387 expandBufAdd4BE(pReply, sizeof(MethodId));
388 expandBufAdd4BE(pReply, sizeof(ObjectId));
389 expandBufAdd4BE(pReply, sizeof(RefTypeId));
390 expandBufAdd4BE(pReply, sizeof(FrameId));
391 return ERR_NONE;
392}
393
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700394static JdwpError VM_Dispose(JdwpState*, const uint8_t*, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700395 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes86964332012-02-15 19:37:42 -0800396 Dbg::Disposed();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700397 return ERR_NONE;
398}
399
400/*
401 * Suspend the execution of the application running in the VM (i.e. suspend
402 * all threads).
403 *
404 * This needs to increment the "suspend count" on all threads.
405 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700406static JdwpError VM_Suspend(JdwpState*, const uint8_t*, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700407 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
jeffhaoa77f0f62012-12-05 17:19:31 -0800408 Thread* self = Thread::Current();
409 self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSuspension);
Elliott Hughes475fc232011-10-25 15:00:35 -0700410 Dbg::SuspendVM();
jeffhaoa77f0f62012-12-05 17:19:31 -0800411 self->TransitionFromSuspendedToRunnable();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700412 return ERR_NONE;
413}
414
415/*
416 * Resume execution. Decrements the "suspend count" of all threads.
417 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700418static JdwpError VM_Resume(JdwpState*, const uint8_t*, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700419 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700420 Dbg::ResumeVM();
421 return ERR_NONE;
422}
423
424/*
425 * The debugger wants the entire VM to exit.
426 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700427static JdwpError VM_Exit(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700428 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesf7c3b662011-10-27 12:04:56 -0700429 uint32_t exitCode = Get4BE(buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700430
431 LOG(WARNING) << "Debugger is telling the VM to exit with code=" << exitCode;
432
433 Dbg::Exit(exitCode);
434 return ERR_NOT_IMPLEMENTED; // shouldn't get here
435}
436
437/*
438 * Create a new string in the VM and return its ID.
439 *
440 * (Ctrl-Shift-I in Eclipse on an array of objects causes it to create the
441 * string "java.util.Arrays".)
442 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700443static JdwpError VM_CreateString(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700444 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -0800445 std::string str(ReadUtf8String(&buf));
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700446 ObjectId stringId = Dbg::CreateString(str);
447 if (stringId == 0) {
448 return ERR_OUT_OF_MEMORY;
449 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700450 expandBufAddObjectId(pReply, stringId);
451 return ERR_NONE;
452}
453
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700454static JdwpError VM_ClassPaths(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700455 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa3ae2b72012-02-24 15:10:51 -0800456 expandBufAddUtf8String(pReply, "/");
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700457
Elliott Hughesa3ae2b72012-02-24 15:10:51 -0800458 std::vector<std::string> class_path;
459 Split(Runtime::Current()->GetClassPathString(), ':', class_path);
460 expandBufAdd4BE(pReply, class_path.size());
461 for (size_t i = 0; i < class_path.size(); ++i) {
462 expandBufAddUtf8String(pReply, class_path[i]);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700463 }
464
Elliott Hughesa3ae2b72012-02-24 15:10:51 -0800465 std::vector<std::string> boot_class_path;
466 Split(Runtime::Current()->GetBootClassPathString(), ':', boot_class_path);
467 expandBufAdd4BE(pReply, boot_class_path.size());
468 for (size_t i = 0; i < boot_class_path.size(); ++i) {
469 expandBufAddUtf8String(pReply, boot_class_path[i]);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700470 }
471
472 return ERR_NONE;
473}
474
475/*
476 * Release a list of object IDs. (Seen in jdb.)
477 *
478 * Currently does nothing.
479 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700480static JdwpError VM_DisposeObjects(JdwpState*, const uint8_t*, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700481 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700482 return ERR_NONE;
483}
484
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800485static JdwpError VM_Capabilities(JdwpState*, const uint8_t*, int, ExpandBuf* reply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700486 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800487 expandBufAdd1(reply, false); // canWatchFieldModification
488 expandBufAdd1(reply, false); // canWatchFieldAccess
Elliott Hughes9777ba22013-01-17 09:04:19 -0800489 expandBufAdd1(reply, true); // canGetBytecodes
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800490 expandBufAdd1(reply, true); // canGetSyntheticAttribute
491 expandBufAdd1(reply, true); // canGetOwnedMonitorInfo
Elliott Hughesf9501702013-01-11 11:22:27 -0800492 expandBufAdd1(reply, true); // canGetCurrentContendedMonitor
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800493 expandBufAdd1(reply, true); // canGetMonitorInfo
494 return ERR_NONE;
495}
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700496
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800497static JdwpError VM_CapabilitiesNew(JdwpState*, const uint8_t*, int, ExpandBuf* reply)
498 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
499
500 // The first few capabilities are the same as those reported by the older call.
501 VM_Capabilities(NULL, NULL, 0, reply);
502
503 expandBufAdd1(reply, false); // canRedefineClasses
504 expandBufAdd1(reply, false); // canAddMethod
505 expandBufAdd1(reply, false); // canUnrestrictedlyRedefineClasses
506 expandBufAdd1(reply, false); // canPopFrames
507 expandBufAdd1(reply, false); // canUseInstanceFilters
508 expandBufAdd1(reply, false); // canGetSourceDebugExtension
509 expandBufAdd1(reply, false); // canRequestVMDeathEvent
510 expandBufAdd1(reply, false); // canSetDefaultStratum
Elliott Hughesec0f83d2013-01-15 16:54:08 -0800511 expandBufAdd1(reply, true); // 1.6: canGetInstanceInfo
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800512 expandBufAdd1(reply, false); // 1.6: canRequestMonitorEvents
Elliott Hughes734b8c62013-01-11 15:32:45 -0800513 expandBufAdd1(reply, true); // 1.6: canGetMonitorFrameInfo
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800514 expandBufAdd1(reply, false); // 1.6: canUseSourceNameFilters
515 expandBufAdd1(reply, false); // 1.6: canGetConstantPool
516 expandBufAdd1(reply, false); // 1.6: canForceEarlyReturn
517
518 // Fill in reserved22 through reserved32; note count started at 1.
519 for (size_t i = 22; i <= 32; ++i) {
520 expandBufAdd1(reply, false);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700521 }
522 return ERR_NONE;
523}
524
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700525static JdwpError VM_AllClassesImpl(ExpandBuf* pReply, bool descriptor_and_status, bool generic)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700526 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800527 std::vector<JDWP::RefTypeId> classes;
528 Dbg::GetClassList(classes);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700529
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800530 expandBufAdd4BE(pReply, classes.size());
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700531
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800532 for (size_t i = 0; i < classes.size(); ++i) {
Elliott Hughesa2155262011-11-16 16:26:58 -0800533 static const char genericSignature[1] = "";
Elliott Hughes436e3722012-02-17 20:01:47 -0800534 JDWP::JdwpTypeTag type_tag;
Elliott Hughesa2155262011-11-16 16:26:58 -0800535 std::string descriptor;
Elliott Hughes436e3722012-02-17 20:01:47 -0800536 uint32_t class_status;
537 JDWP::JdwpError status = Dbg::GetClassInfo(classes[i], &type_tag, &class_status, &descriptor);
538 if (status != ERR_NONE) {
539 return status;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800540 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700541
Elliott Hughes436e3722012-02-17 20:01:47 -0800542 expandBufAdd1(pReply, type_tag);
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800543 expandBufAddRefTypeId(pReply, classes[i]);
Elliott Hughes86964332012-02-15 19:37:42 -0800544 if (descriptor_and_status) {
545 expandBufAddUtf8String(pReply, descriptor);
546 if (generic) {
547 expandBufAddUtf8String(pReply, genericSignature);
548 }
Elliott Hughes436e3722012-02-17 20:01:47 -0800549 expandBufAdd4BE(pReply, class_status);
Elliott Hughes1fe7afb2012-02-13 17:23:03 -0800550 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700551 }
552
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700553 return ERR_NONE;
554}
555
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700556static JdwpError VM_AllClasses(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700557 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700558 return VM_AllClassesImpl(pReply, true, false);
Elliott Hughes1fe7afb2012-02-13 17:23:03 -0800559}
560
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700561static JdwpError VM_AllClassesWithGeneric(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700562 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700563 return VM_AllClassesImpl(pReply, true, true);
Elliott Hughes1fe7afb2012-02-13 17:23:03 -0800564}
565
Elliott Hughesec0f83d2013-01-15 16:54:08 -0800566static JdwpError VM_InstanceCounts(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
567 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -0800568 int32_t class_count = ReadSigned32("class count", &buf);
Elliott Hughesec0f83d2013-01-15 16:54:08 -0800569 if (class_count < 0) {
570 return ERR_ILLEGAL_ARGUMENT;
571 }
572 std::vector<RefTypeId> class_ids;
573 for (int32_t i = 0; i < class_count; ++i) {
574 class_ids.push_back(ReadRefTypeId(&buf));
575 }
576
577 std::vector<uint64_t> counts;
578 JdwpError rc = Dbg::GetInstanceCounts(class_ids, counts);
579 if (rc != ERR_NONE) {
580 return rc;
581 }
582
583 expandBufAdd4BE(pReply, counts.size());
584 for (size_t i = 0; i < counts.size(); ++i) {
585 expandBufAdd8BE(pReply, counts[i]);
586 }
587 return ERR_NONE;
588}
589
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700590static JdwpError RT_Modifiers(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700591 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700592 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800593 return Dbg::GetModifiers(refTypeId, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700594}
595
596/*
597 * Get values from static fields in a reference type.
598 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700599static JdwpError RT_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700600 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes0cf74332012-02-23 23:14:00 -0800601 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800602 int32_t field_count = ReadSigned32("field count", &buf);
Elliott Hughes0cf74332012-02-23 23:14:00 -0800603 expandBufAdd4BE(pReply, field_count);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800604 for (int32_t i = 0; i < field_count; ++i) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700605 FieldId fieldId = ReadFieldId(&buf);
Elliott Hughes0cf74332012-02-23 23:14:00 -0800606 JdwpError status = Dbg::GetStaticFieldValue(refTypeId, fieldId, pReply);
Elliott Hughes3f4d58f2012-02-18 20:05:37 -0800607 if (status != ERR_NONE) {
608 return status;
609 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700610 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700611 return ERR_NONE;
612}
613
614/*
615 * Get the name of the source file in which a reference type was declared.
616 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700617static JdwpError RT_SourceFile(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700618 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700619 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes03181a82011-11-17 17:22:21 -0800620 std::string source_file;
Elliott Hughes436e3722012-02-17 20:01:47 -0800621 JdwpError status = Dbg::GetSourceFile(refTypeId, source_file);
622 if (status != ERR_NONE) {
623 return status;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700624 }
Elliott Hughes4740cdf2011-12-07 14:07:12 -0800625 expandBufAddUtf8String(pReply, source_file);
Elliott Hughes03181a82011-11-17 17:22:21 -0800626 return ERR_NONE;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700627}
628
629/*
630 * Return the current status of the reference type.
631 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700632static JdwpError RT_Status(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700633 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700634 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800635 JDWP::JdwpTypeTag type_tag;
636 uint32_t class_status;
637 JDWP::JdwpError status = Dbg::GetClassInfo(refTypeId, &type_tag, &class_status, NULL);
638 if (status != ERR_NONE) {
639 return status;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800640 }
Elliott Hughes436e3722012-02-17 20:01:47 -0800641 expandBufAdd4BE(pReply, class_status);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700642 return ERR_NONE;
643}
644
645/*
646 * Return interfaces implemented directly by this class.
647 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700648static JdwpError RT_Interfaces(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700649 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700650 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800651 return Dbg::OutputDeclaredInterfaces(refTypeId, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700652}
653
654/*
655 * Return the class object corresponding to this type.
656 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700657static JdwpError RT_ClassObject(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700658 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700659 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800660 ObjectId class_object_id;
661 JdwpError status = Dbg::GetClassObject(refTypeId, class_object_id);
Elliott Hughes436e3722012-02-17 20:01:47 -0800662 if (status != ERR_NONE) {
663 return status;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800664 }
Elliott Hughesa96836a2013-01-17 12:27:49 -0800665 VLOG(jdwp) << StringPrintf(" --> ObjectId %#llx", class_object_id);
666 expandBufAddObjectId(pReply, class_object_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700667 return ERR_NONE;
668}
669
670/*
671 * Returns the value of the SourceDebugExtension attribute.
672 *
673 * JDB seems interested, but DEX files don't currently support this.
674 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700675static JdwpError RT_SourceDebugExtension(JdwpState*, const uint8_t*, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700676 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700677 /* referenceTypeId in, string out */
678 return ERR_ABSENT_INFORMATION;
679}
680
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700681static JdwpError RT_Signature(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply,
682 bool with_generic)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700683 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700684 RefTypeId refTypeId = ReadRefTypeId(&buf);
685
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800686 std::string signature;
Elliott Hughes98e43f62012-02-24 12:42:35 -0800687 JdwpError status = Dbg::GetSignature(refTypeId, signature);
688 if (status != ERR_NONE) {
689 return status;
690 }
691 expandBufAddUtf8String(pReply, signature);
692 if (with_generic) {
Elliott Hughes0cf74332012-02-23 23:14:00 -0800693 expandBufAddUtf8String(pReply, "");
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700694 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700695 return ERR_NONE;
696}
697
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700698static JdwpError RT_Signature(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700699 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700700 return RT_Signature(state, buf, dataLen, pReply, false);
Elliott Hughes98e43f62012-02-24 12:42:35 -0800701}
702
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700703static JdwpError RT_SignatureWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen,
704 ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700705 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700706 return RT_Signature(state, buf, dataLen, pReply, true);
Elliott Hughes98e43f62012-02-24 12:42:35 -0800707}
708
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700709/*
710 * Return the instance of java.lang.ClassLoader that loaded the specified
711 * reference type, or null if it was loaded by the system loader.
712 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700713static JdwpError RT_ClassLoader(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700714 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700715 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800716 return Dbg::GetClassLoader(refTypeId, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700717}
718
719/*
720 * Given a referenceTypeId, return a block of stuff that describes the
721 * fields declared by a class.
722 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700723static JdwpError RT_FieldsWithGeneric(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700724 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700725 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800726 return Dbg::OutputDeclaredFields(refTypeId, true, pReply);
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800727}
728
729// Obsolete equivalent of FieldsWithGeneric, without the generic type information.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700730static JdwpError RT_Fields(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700731 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800732 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800733 return Dbg::OutputDeclaredFields(refTypeId, false, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700734}
735
736/*
737 * Given a referenceTypeID, return a block of goodies describing the
738 * methods declared by a class.
739 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700740static JdwpError RT_MethodsWithGeneric(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700741 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700742 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800743 return Dbg::OutputDeclaredMethods(refTypeId, true, pReply);
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800744}
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700745
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800746// Obsolete equivalent of MethodsWithGeneric, without the generic type information.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700747static JdwpError RT_Methods(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700748 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800749 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes436e3722012-02-17 20:01:47 -0800750 return Dbg::OutputDeclaredMethods(refTypeId, false, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700751}
752
Elliott Hughes3b78c942013-01-15 17:35:41 -0800753static JdwpError RT_Instances(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
754 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
755 RefTypeId class_id = ReadRefTypeId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800756 int32_t max_count = ReadSigned32("max count", &buf);
Elliott Hughes3b78c942013-01-15 17:35:41 -0800757 if (max_count < 0) {
758 return ERR_ILLEGAL_ARGUMENT;
759 }
760
761 std::vector<ObjectId> instances;
762 JdwpError rc = Dbg::GetInstances(class_id, max_count, instances);
763 if (rc != ERR_NONE) {
764 return rc;
765 }
766
Elliott Hughes0cbaff52013-01-16 15:28:01 -0800767 return WriteTaggedObjectList(reply, instances);
Elliott Hughes3b78c942013-01-15 17:35:41 -0800768}
769
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700770/*
771 * Return the immediate superclass of a class.
772 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700773static JdwpError CT_Superclass(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700774 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700775 RefTypeId class_id = ReadRefTypeId(&buf);
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800776 RefTypeId superClassId;
Elliott Hughes74847412012-06-20 18:10:21 -0700777 JdwpError status = Dbg::GetSuperclass(class_id, superClassId);
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -0800778 if (status != ERR_NONE) {
779 return status;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800780 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700781 expandBufAddRefTypeId(pReply, superClassId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700782 return ERR_NONE;
783}
784
785/*
786 * Set static class values.
787 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700788static JdwpError CT_SetValues(JdwpState* , const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700789 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700790 RefTypeId class_id = ReadRefTypeId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800791 int32_t values_count = ReadSigned32("values count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700792
Elliott Hughesa96836a2013-01-17 12:27:49 -0800793 UNUSED(class_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700794
Elliott Hughesa96836a2013-01-17 12:27:49 -0800795 for (int32_t i = 0; i < values_count; ++i) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700796 FieldId fieldId = ReadFieldId(&buf);
Elliott Hughesaed4be92011-12-02 16:16:23 -0800797 JDWP::JdwpTag fieldTag = Dbg::GetStaticFieldBasicTag(fieldId);
Elliott Hughesdbb40792011-11-18 17:05:22 -0800798 size_t width = Dbg::GetTagWidth(fieldTag);
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800799 uint64_t value = ReadValue(&buf, width);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700800
Elliott Hughesa96836a2013-01-17 12:27:49 -0800801 VLOG(jdwp) << " --> field=" << fieldId << " tag=" << fieldTag << " --> " << value;
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -0800802 JdwpError status = Dbg::SetStaticFieldValue(fieldId, value, width);
803 if (status != ERR_NONE) {
804 return status;
805 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700806 }
807
808 return ERR_NONE;
809}
810
811/*
812 * Invoke a static method.
813 *
814 * Example: Eclipse sometimes uses java/lang/Class.forName(String s) on
815 * values in the "variables" display.
816 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700817static JdwpError CT_InvokeMethod(JdwpState* state, const uint8_t* buf, int dataLen,
818 ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700819 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700820 RefTypeId class_id = ReadRefTypeId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800821 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -0700822 MethodId method_id = ReadMethodId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700823
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700824 return FinishInvoke(state, buf, dataLen, pReply, thread_id, 0, class_id, method_id, false);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700825}
826
827/*
828 * Create a new object of the requested type, and invoke the specified
829 * constructor.
830 *
831 * Example: in IntelliJ, create a watch on "new String(myByteArray)" to
832 * see the contents of a byte[] as a string.
833 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700834static JdwpError CT_NewInstance(JdwpState* state, const uint8_t* buf, int dataLen,
835 ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700836 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700837 RefTypeId class_id = ReadRefTypeId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800838 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -0700839 MethodId method_id = ReadMethodId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700840
Elliott Hughes74847412012-06-20 18:10:21 -0700841 ObjectId object_id;
842 JdwpError status = Dbg::CreateObject(class_id, object_id);
Elliott Hughes436e3722012-02-17 20:01:47 -0800843 if (status != ERR_NONE) {
844 return status;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800845 }
Elliott Hughes74847412012-06-20 18:10:21 -0700846 if (object_id == 0) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700847 return ERR_OUT_OF_MEMORY;
848 }
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700849 return FinishInvoke(state, buf, dataLen, pReply, thread_id, object_id, class_id, method_id, true);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700850}
851
852/*
853 * Create a new array object of the requested type and length.
854 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700855static JdwpError AT_newInstance(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700856 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700857 RefTypeId arrayTypeId = ReadRefTypeId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800858 int32_t length = ReadSigned32("length", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700859
Elliott Hughes74847412012-06-20 18:10:21 -0700860 ObjectId object_id;
861 JdwpError status = Dbg::CreateArrayObject(arrayTypeId, length, object_id);
Elliott Hughes436e3722012-02-17 20:01:47 -0800862 if (status != ERR_NONE) {
863 return status;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800864 }
Elliott Hughes74847412012-06-20 18:10:21 -0700865 if (object_id == 0) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700866 return ERR_OUT_OF_MEMORY;
867 }
868 expandBufAdd1(pReply, JT_ARRAY);
Elliott Hughes74847412012-06-20 18:10:21 -0700869 expandBufAddObjectId(pReply, object_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700870 return ERR_NONE;
871}
872
873/*
874 * Return line number information for the method, if present.
875 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700876static JdwpError M_LineTable(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700877 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700878 RefTypeId refTypeId = ReadRefTypeId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -0700879 MethodId method_id = ReadMethodId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700880
Elliott Hughes74847412012-06-20 18:10:21 -0700881 Dbg::OutputLineTable(refTypeId, method_id, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700882
883 return ERR_NONE;
884}
885
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700886static JdwpError M_VariableTable(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply,
887 bool generic)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700888 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700889 RefTypeId class_id = ReadRefTypeId(&buf);
890 MethodId method_id = ReadMethodId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700891
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -0800892 // We could return ERR_ABSENT_INFORMATION here if the DEX file was built without local variable
893 // information. That will cause Eclipse to make a best-effort attempt at displaying local
894 // variables anonymously. However, the attempt isn't very good, so we're probably better off just
895 // not showing anything.
Elliott Hughes74847412012-06-20 18:10:21 -0700896 Dbg::OutputVariableTable(class_id, method_id, generic, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700897 return ERR_NONE;
898}
899
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700900static JdwpError M_VariableTable(JdwpState* state, const uint8_t* buf, int dataLen,
901 ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700902 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700903 return M_VariableTable(state, buf, dataLen, pReply, false);
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -0800904}
905
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700906static JdwpError M_VariableTableWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen,
907 ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700908 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700909 return M_VariableTable(state, buf, dataLen, pReply, true);
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -0800910}
911
Elliott Hughes9777ba22013-01-17 09:04:19 -0800912static JdwpError M_Bytecodes(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
913 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
914 RefTypeId class_id = ReadRefTypeId(&buf);
915 MethodId method_id = ReadMethodId(&buf);
916
917 std::vector<uint8_t> bytecodes;
918 JdwpError rc = Dbg::GetBytecodes(class_id, method_id, bytecodes);
919 if (rc != ERR_NONE) {
920 return rc;
921 }
922
923 expandBufAdd4BE(reply, bytecodes.size());
924 for (size_t i = 0; i < bytecodes.size(); ++i) {
925 expandBufAdd1(reply, bytecodes[i]);
926 }
927
928 return ERR_NONE;
929}
930
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700931/*
932 * Given an object reference, return the runtime type of the object
933 * (class or array).
934 *
Elliott Hughes74847412012-06-20 18:10:21 -0700935 * This can get called on different things, e.g. thread_id gets
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700936 * passed in here.
937 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700938static JdwpError OR_ReferenceType(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700939 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700940 ObjectId object_id = ReadObjectId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -0700941 return Dbg::GetReferenceType(object_id, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700942}
943
944/*
945 * Get values from the fields of an object.
946 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700947static JdwpError OR_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700948 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700949 ObjectId object_id = ReadObjectId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800950 int32_t field_count = ReadSigned32("field count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700951
Elliott Hughes0cf74332012-02-23 23:14:00 -0800952 expandBufAdd4BE(pReply, field_count);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800953 for (int32_t i = 0; i < field_count; ++i) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700954 FieldId fieldId = ReadFieldId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -0700955 JdwpError status = Dbg::GetFieldValue(object_id, fieldId, pReply);
Elliott Hughes3f4d58f2012-02-18 20:05:37 -0800956 if (status != ERR_NONE) {
957 return status;
958 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700959 }
960
961 return ERR_NONE;
962}
963
964/*
965 * Set values in the fields of an object.
966 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700967static JdwpError OR_SetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700968 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -0700969 ObjectId object_id = ReadObjectId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -0800970 int32_t field_count = ReadSigned32("field count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700971
Elliott Hughesa96836a2013-01-17 12:27:49 -0800972 for (int32_t i = 0; i < field_count; ++i) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700973 FieldId fieldId = ReadFieldId(&buf);
974
Elliott Hughesaed4be92011-12-02 16:16:23 -0800975 JDWP::JdwpTag fieldTag = Dbg::GetFieldBasicTag(fieldId);
Elliott Hughesdbb40792011-11-18 17:05:22 -0800976 size_t width = Dbg::GetTagWidth(fieldTag);
Elliott Hughes4993bbc2013-01-10 15:41:25 -0800977 uint64_t value = ReadValue(&buf, width);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700978
Elliott Hughes2435a572012-02-17 16:07:41 -0800979 VLOG(jdwp) << " --> fieldId=" << fieldId << " tag=" << fieldTag << "(" << width << ") value=" << value;
Elliott Hughes74847412012-06-20 18:10:21 -0700980 JdwpError status = Dbg::SetFieldValue(object_id, fieldId, value, width);
Elliott Hughes3f4d58f2012-02-18 20:05:37 -0800981 if (status != ERR_NONE) {
982 return status;
983 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700984 }
985
986 return ERR_NONE;
987}
988
Elliott Hughesf327e072013-01-09 16:01:26 -0800989static JdwpError OR_MonitorInfo(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
990 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
991 ObjectId object_id = ReadObjectId(&buf);
992 return Dbg::GetMonitorInfo(object_id, reply);
993}
994
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700995/*
996 * Invoke an instance method. The invocation must occur in the specified
997 * thread, which must have been suspended by an event.
998 *
999 * The call is synchronous. All threads in the VM are resumed, unless the
1000 * SINGLE_THREADED flag is set.
1001 *
1002 * If you ask Eclipse to "inspect" an object (or ask JDB to "print" an
1003 * object), it will try to invoke the object's toString() function. This
1004 * feature becomes crucial when examining ArrayLists with Eclipse.
1005 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001006static JdwpError OR_InvokeMethod(JdwpState* state, const uint8_t* buf, int dataLen,
1007 ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001008 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes74847412012-06-20 18:10:21 -07001009 ObjectId object_id = ReadObjectId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -08001010 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -07001011 RefTypeId class_id = ReadRefTypeId(&buf);
1012 MethodId method_id = ReadMethodId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001013
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001014 return FinishInvoke(state, buf, dataLen, pReply, thread_id, object_id, class_id, method_id, false);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001015}
1016
1017/*
1018 * Disable garbage collection of the specified object.
1019 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001020static JdwpError OR_DisableCollection(JdwpState*, const uint8_t*, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001021 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes927bd292013-01-17 10:40:13 -08001022 // TODO: this is currently a no-op.
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001023 return ERR_NONE;
1024}
1025
1026/*
1027 * Enable garbage collection of the specified object.
1028 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001029static JdwpError OR_EnableCollection(JdwpState*, const uint8_t*, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001030 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes927bd292013-01-17 10:40:13 -08001031 // TODO: this is currently a no-op.
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001032 return ERR_NONE;
1033}
1034
1035/*
1036 * Determine whether an object has been garbage collected.
1037 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001038static JdwpError OR_IsCollected(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001039 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001040 //ObjectId object_id = ReadObjectId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001041
1042 // TODO: currently returning false; must integrate with GC
1043 expandBufAdd1(pReply, 0);
1044
1045 return ERR_NONE;
1046}
1047
Elliott Hughes0cbaff52013-01-16 15:28:01 -08001048static JdwpError OR_ReferringObjects(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
1049 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1050 ObjectId object_id = ReadObjectId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -08001051 int32_t max_count = ReadSigned32("max count", &buf);
Elliott Hughes0cbaff52013-01-16 15:28:01 -08001052 if (max_count < 0) {
1053 return ERR_ILLEGAL_ARGUMENT;
1054 }
1055
1056 std::vector<ObjectId> referring_objects;
1057 JdwpError rc = Dbg::GetReferringObjects(object_id, max_count, referring_objects);
1058 if (rc != ERR_NONE) {
1059 return rc;
1060 }
1061
1062 return WriteTaggedObjectList(reply, referring_objects);
1063}
1064
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001065/*
1066 * Return the string value in a string object.
1067 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001068static JdwpError SR_Value(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001069 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001070 ObjectId stringObject = ReadObjectId(&buf);
Elliott Hughes68fdbd02011-11-29 19:22:47 -08001071 std::string str(Dbg::StringToUtf8(stringObject));
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001072
Elliott Hughesa96836a2013-01-17 12:27:49 -08001073 VLOG(jdwp) << StringPrintf(" --> %s", PrintableString(str).c_str());
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001074
Elliott Hughes4740cdf2011-12-07 14:07:12 -08001075 expandBufAddUtf8String(pReply, str);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001076
1077 return ERR_NONE;
1078}
1079
1080/*
1081 * Return a thread's name.
1082 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001083static JdwpError TR_Name(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001084 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001085 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001086
Elliott Hughesa2e54f62011-11-17 13:01:30 -08001087 std::string name;
Elliott Hughes221229c2013-01-08 18:17:50 -08001088 JdwpError error = Dbg::GetThreadName(thread_id, name);
1089 if (error != ERR_NONE) {
1090 return error;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001091 }
Elliott Hughes74847412012-06-20 18:10:21 -07001092 VLOG(jdwp) << StringPrintf(" Name of thread %#llx is \"%s\"", thread_id, name.c_str());
Elliott Hughes4740cdf2011-12-07 14:07:12 -08001093 expandBufAddUtf8String(pReply, name);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001094
1095 return ERR_NONE;
1096}
1097
1098/*
1099 * Suspend the specified thread.
1100 *
1101 * It's supposed to remain suspended even if interpreted code wants to
1102 * resume it; only the JDI is allowed to resume it.
1103 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001104static JdwpError TR_Suspend(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001105 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001106 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001107
Elliott Hughes74847412012-06-20 18:10:21 -07001108 if (thread_id == Dbg::GetThreadSelfId()) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001109 LOG(INFO) << " Warning: ignoring request to suspend self";
1110 return ERR_THREAD_NOT_SUSPENDED;
1111 }
Elliott Hughesa96836a2013-01-17 12:27:49 -08001112
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001113 Thread* self = Thread::Current();
1114 self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
1115 JdwpError result = Dbg::SuspendThread(thread_id);
1116 self->TransitionFromSuspendedToRunnable();
1117 return result;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001118}
1119
1120/*
1121 * Resume the specified thread.
1122 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001123static JdwpError TR_Resume(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001124 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001125 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001126
Elliott Hughes74847412012-06-20 18:10:21 -07001127 if (thread_id == Dbg::GetThreadSelfId()) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001128 LOG(INFO) << " Warning: ignoring request to resume self";
1129 return ERR_NONE;
1130 }
Elliott Hughesa96836a2013-01-17 12:27:49 -08001131
Elliott Hughes74847412012-06-20 18:10:21 -07001132 Dbg::ResumeThread(thread_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001133 return ERR_NONE;
1134}
1135
1136/*
1137 * Return status of specified thread.
1138 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001139static JdwpError TR_Status(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001140 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001141 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001142
Elliott Hughes3d30d9b2011-12-07 17:35:48 -08001143 JDWP::JdwpThreadStatus threadStatus;
1144 JDWP::JdwpSuspendStatus suspendStatus;
Elliott Hughes221229c2013-01-08 18:17:50 -08001145 JdwpError error = Dbg::GetThreadStatus(thread_id, &threadStatus, &suspendStatus);
1146 if (error != ERR_NONE) {
1147 return error;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001148 }
1149
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001150 VLOG(jdwp) << " --> " << threadStatus << ", " << suspendStatus;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001151
1152 expandBufAdd4BE(pReply, threadStatus);
1153 expandBufAdd4BE(pReply, suspendStatus);
1154
1155 return ERR_NONE;
1156}
1157
1158/*
1159 * Return the thread group that the specified thread is a member of.
1160 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001161static JdwpError TR_ThreadGroup(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001162 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001163 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -07001164 return Dbg::GetThreadGroup(thread_id, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001165}
1166
1167/*
1168 * Return the current call stack of a suspended thread.
1169 *
1170 * If the thread isn't suspended, the error code isn't defined, but should
1171 * be THREAD_NOT_SUSPENDED.
1172 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001173static JdwpError TR_Frames(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001174 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001175 ObjectId thread_id = ReadThreadId(&buf);
1176 uint32_t start_frame = ReadUnsigned32("start frame", &buf);
1177 uint32_t length = ReadUnsigned32("length", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001178
Elliott Hughes221229c2013-01-08 18:17:50 -08001179 size_t actual_frame_count;
Elliott Hughesf15f4a02013-01-09 10:09:38 -08001180 JdwpError error = Dbg::GetThreadFrameCount(thread_id, actual_frame_count);
Elliott Hughes221229c2013-01-08 18:17:50 -08001181 if (error != ERR_NONE) {
1182 return error;
1183 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001184
Elliott Hughes3f4d58f2012-02-18 20:05:37 -08001185 if (actual_frame_count <= 0) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001186 return ERR_THREAD_NOT_SUSPENDED; // 0 means no managed frames (which means "in native").
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001187 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001188
Elliott Hughes3f4d58f2012-02-18 20:05:37 -08001189 if (start_frame > actual_frame_count) {
1190 return ERR_INVALID_INDEX;
1191 }
1192 if (length == static_cast<uint32_t>(-1)) {
1193 length = actual_frame_count - start_frame;
1194 }
1195 if (start_frame + length > actual_frame_count) {
1196 return ERR_INVALID_LENGTH;
1197 }
1198
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001199 return Dbg::GetThreadFrames(thread_id, start_frame, length, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001200}
1201
1202/*
1203 * Returns the #of frames on the specified thread, which must be suspended.
1204 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001205static JdwpError TR_FrameCount(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001206 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001207 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001208
Elliott Hughes221229c2013-01-08 18:17:50 -08001209 size_t frame_count;
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001210 JdwpError rc = Dbg::GetThreadFrameCount(thread_id, frame_count);
1211 if (rc != ERR_NONE) {
1212 return rc;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001213 }
Elliott Hughes3f4d58f2012-02-18 20:05:37 -08001214 expandBufAdd4BE(pReply, static_cast<uint32_t>(frame_count));
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001215
1216 return ERR_NONE;
1217}
1218
Elliott Hughes734b8c62013-01-11 15:32:45 -08001219static JdwpError TR_OwnedMonitors(const uint8_t* buf, ExpandBuf* reply, bool with_stack_depths)
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001220 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001221 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001222
1223 std::vector<ObjectId> monitors;
Elliott Hughes734b8c62013-01-11 15:32:45 -08001224 std::vector<uint32_t> stack_depths;
1225 JdwpError rc = Dbg::GetOwnedMonitors(thread_id, monitors, stack_depths);
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001226 if (rc != ERR_NONE) {
1227 return rc;
1228 }
1229
1230 expandBufAdd4BE(reply, monitors.size());
1231 for (size_t i = 0; i < monitors.size(); ++i) {
1232 rc = WriteTaggedObject(reply, monitors[i]);
1233 if (rc != ERR_NONE) {
1234 return rc;
1235 }
Elliott Hughes734b8c62013-01-11 15:32:45 -08001236 if (with_stack_depths) {
1237 expandBufAdd4BE(reply, stack_depths[i]);
1238 }
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001239 }
1240 return ERR_NONE;
1241}
1242
Elliott Hughes734b8c62013-01-11 15:32:45 -08001243static JdwpError TR_OwnedMonitors(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
1244 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1245 return TR_OwnedMonitors(buf, reply, false);
1246}
1247
1248static JdwpError TR_OwnedMonitorsStackDepthInfo(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
1249 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1250 return TR_OwnedMonitors(buf, reply, true);
1251}
1252
Elliott Hughesf9501702013-01-11 11:22:27 -08001253static JdwpError TR_CurrentContendedMonitor(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001254 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001255 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001256
Elliott Hughesf9501702013-01-11 11:22:27 -08001257 ObjectId contended_monitor;
1258 JdwpError rc = Dbg::GetContendedMonitor(thread_id, contended_monitor);
1259 if (rc != ERR_NONE) {
1260 return rc;
1261 }
1262 return WriteTaggedObject(reply, contended_monitor);
1263}
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001264
Elliott Hughesf9501702013-01-11 11:22:27 -08001265static JdwpError TR_Interrupt(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
1266 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001267 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughesf9501702013-01-11 11:22:27 -08001268 return Dbg::Interrupt(thread_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001269}
1270
1271/*
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001272 * Return the debug suspend count for the specified thread.
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001273 *
1274 * (The thread *might* still be running -- it might not have examined
1275 * its suspend count recently.)
1276 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001277static JdwpError TR_DebugSuspendCount(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001278 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001279 ObjectId thread_id = ReadThreadId(&buf);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001280 return Dbg::GetThreadDebugSuspendCount(thread_id, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001281}
1282
1283/*
1284 * Return the name of a thread group.
1285 *
1286 * The Eclipse debugger recognizes "main" and "system" as special.
1287 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001288static JdwpError TGR_Name(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001289 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001290 ObjectId thread_group_id = ReadThreadGroupId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001291
Elliott Hughescaf76542012-06-28 16:08:22 -07001292 expandBufAddUtf8String(pReply, Dbg::GetThreadGroupName(thread_group_id));
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001293
1294 return ERR_NONE;
1295}
1296
1297/*
1298 * Returns the thread group -- if any -- that contains the specified
1299 * thread group.
1300 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001301static JdwpError TGR_Parent(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001302 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001303 ObjectId thread_group_id = ReadThreadGroupId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001304
Elliott Hughescaf76542012-06-28 16:08:22 -07001305 ObjectId parentGroup = Dbg::GetThreadGroupParent(thread_group_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001306 expandBufAddObjectId(pReply, parentGroup);
1307
1308 return ERR_NONE;
1309}
1310
1311/*
1312 * Return the active threads and thread groups that are part of the
1313 * specified thread group.
1314 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001315static JdwpError TGR_Children(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001316 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001317 ObjectId thread_group_id = ReadThreadGroupId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001318
Elliott Hughescaf76542012-06-28 16:08:22 -07001319 std::vector<ObjectId> thread_ids;
1320 Dbg::GetThreads(thread_group_id, thread_ids);
1321 expandBufAdd4BE(pReply, thread_ids.size());
1322 for (uint32_t i = 0; i < thread_ids.size(); ++i) {
1323 expandBufAddObjectId(pReply, thread_ids[i]);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001324 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001325
Elliott Hughescaf76542012-06-28 16:08:22 -07001326 std::vector<ObjectId> child_thread_groups_ids;
1327 Dbg::GetChildThreadGroups(thread_group_id, child_thread_groups_ids);
1328 expandBufAdd4BE(pReply, child_thread_groups_ids.size());
1329 for (uint32_t i = 0; i < child_thread_groups_ids.size(); ++i) {
1330 expandBufAddObjectId(pReply, child_thread_groups_ids[i]);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001331 }
1332
1333 return ERR_NONE;
1334}
1335
1336/*
1337 * Return the #of components in the array.
1338 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001339static JdwpError AR_Length(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001340 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001341 ObjectId array_id = ReadArrayId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001342
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -08001343 int length;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001344 JdwpError status = Dbg::GetArrayLength(array_id, length);
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -08001345 if (status != ERR_NONE) {
1346 return status;
1347 }
Elliott Hughes2435a572012-02-17 16:07:41 -08001348 VLOG(jdwp) << " --> " << length;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001349
Elliott Hughes3d1ca6d2012-02-13 15:43:19 -08001350 expandBufAdd4BE(pReply, length);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001351
1352 return ERR_NONE;
1353}
1354
1355/*
1356 * Return the values from an array.
1357 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001358static JdwpError AR_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001359 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001360 ObjectId array_id = ReadArrayId(&buf);
1361 uint32_t offset = ReadUnsigned32("offset", &buf);
1362 uint32_t length = ReadUnsigned32("length", &buf);
1363 return Dbg::OutputArray(array_id, offset, length, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001364}
1365
1366/*
1367 * Set values in an array.
1368 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001369static JdwpError AR_SetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001370 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001371 ObjectId array_id = ReadArrayId(&buf);
1372 uint32_t offset = ReadUnsigned32("offset", &buf);
1373 uint32_t length = ReadUnsigned32("length", &buf);
1374 return Dbg::SetArrayElements(array_id, offset, length, buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001375}
1376
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001377static JdwpError CLR_VisibleClasses(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001378 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromfd2ec542012-05-02 15:08:57 -07001379 ReadObjectId(&buf); // classLoaderObject
Elliott Hughes86964332012-02-15 19:37:42 -08001380 // TODO: we should only return classes which have the given class loader as a defining or
1381 // initiating loader. The former would be easy; the latter is hard, because we don't have
1382 // any such notion.
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001383 return VM_AllClassesImpl(pReply, false, false);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001384}
1385
1386/*
1387 * Set an event trigger.
1388 *
1389 * Reply with a requestID.
1390 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001391static JdwpError ER_Set(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001392 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001393 const uint8_t* origBuf = buf;
1394
Elliott Hughesf7c3b662011-10-27 12:04:56 -07001395 uint8_t eventKind = Read1(&buf);
Elliott Hughesf8349362012-06-18 15:00:06 -07001396 uint8_t suspend_policy = Read1(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -08001397 int32_t modifier_count = ReadSigned32("modifier count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001398
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001399 VLOG(jdwp) << " Set(kind=" << JdwpEventKind(eventKind)
Elliott Hughesf8349362012-06-18 15:00:06 -07001400 << " suspend=" << JdwpSuspendPolicy(suspend_policy)
Elliott Hughesa96836a2013-01-17 12:27:49 -08001401 << " mods=" << modifier_count << ")";
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001402
Elliott Hughesa96836a2013-01-17 12:27:49 -08001403 CHECK_LT(modifier_count, 256); /* reasonableness check */
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001404
Elliott Hughesa96836a2013-01-17 12:27:49 -08001405 JdwpEvent* pEvent = EventAlloc(modifier_count);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001406 pEvent->eventKind = static_cast<JdwpEventKind>(eventKind);
Elliott Hughesf8349362012-06-18 15:00:06 -07001407 pEvent->suspend_policy = static_cast<JdwpSuspendPolicy>(suspend_policy);
Elliott Hughesa96836a2013-01-17 12:27:49 -08001408 pEvent->modCount = modifier_count;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001409
1410 /*
1411 * Read modifiers. Ordering may be significant (see explanation of Count
1412 * mods in JDWP doc).
1413 */
Elliott Hughesa96836a2013-01-17 12:27:49 -08001414 for (int32_t i = 0; i < modifier_count; ++i) {
Elliott Hughes972a47b2012-02-21 18:16:06 -08001415 JdwpEventMod& mod = pEvent->mods[i];
Elliott Hughesa96836a2013-01-17 12:27:49 -08001416 mod.modKind = ReadModKind(&buf);
Elliott Hughes972a47b2012-02-21 18:16:06 -08001417 switch (mod.modKind) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001418 case MK_COUNT:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001419 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001420 // Report once, when "--count" reaches 0.
1421 uint32_t count = ReadUnsigned32("count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001422 if (count == 0) {
1423 return ERR_INVALID_COUNT;
1424 }
Elliott Hughes972a47b2012-02-21 18:16:06 -08001425 mod.count.count = count;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001426 }
1427 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001428 case MK_CONDITIONAL:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001429 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001430 // Conditional on expression.
1431 uint32_t exprId = ReadUnsigned32("expr id", &buf);
Elliott Hughes972a47b2012-02-21 18:16:06 -08001432 mod.conditional.exprId = exprId;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001433 }
1434 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001435 case MK_THREAD_ONLY:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001436 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001437 // Only report events in specified thread.
1438 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -07001439 mod.threadOnly.threadId = thread_id;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001440 }
1441 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001442 case MK_CLASS_ONLY:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001443 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001444 // For ClassPrepare, MethodEntry.
Elliott Hughes74847412012-06-20 18:10:21 -07001445 RefTypeId class_id = ReadRefTypeId(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -07001446 mod.classOnly.refTypeId = class_id;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001447 }
1448 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001449 case MK_CLASS_MATCH:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001450 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001451 // Restrict events to matching classes.
Elliott Hughes86964332012-02-15 19:37:42 -08001452 // pattern is "java.foo.*", we want "java/foo/*".
Elliott Hughesa96836a2013-01-17 12:27:49 -08001453 std::string pattern(ReadUtf8String(&buf));
Elliott Hughes86964332012-02-15 19:37:42 -08001454 std::replace(pattern.begin(), pattern.end(), '.', '/');
Elliott Hughes972a47b2012-02-21 18:16:06 -08001455 mod.classMatch.classPattern = strdup(pattern.c_str());
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001456 }
1457 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001458 case MK_CLASS_EXCLUDE:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001459 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001460 // Restrict events to non-matching classes.
Elliott Hughes86964332012-02-15 19:37:42 -08001461 // pattern is "java.foo.*", we want "java/foo/*".
Elliott Hughesa96836a2013-01-17 12:27:49 -08001462 std::string pattern(ReadUtf8String(&buf));
Elliott Hughes86964332012-02-15 19:37:42 -08001463 std::replace(pattern.begin(), pattern.end(), '.', '/');
Elliott Hughes972a47b2012-02-21 18:16:06 -08001464 mod.classExclude.classPattern = strdup(pattern.c_str());
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001465 }
1466 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001467 case MK_LOCATION_ONLY:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001468 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001469 // Restrict certain events based on location.
1470 JdwpLocation location = ReadLocation(&buf);
1471 mod.locationOnly.loc = location;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001472 }
1473 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001474 case MK_EXCEPTION_ONLY:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001475 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001476 // Modifies EK_EXCEPTION events,
1477 RefTypeId exceptionOrNull = ReadRefTypeId(&buf); // null => all exceptions.
1478 uint8_t caught = Read1(&buf);
1479 uint8_t uncaught = Read1(&buf);
Elliott Hughes229feb72012-02-23 13:33:29 -08001480 VLOG(jdwp) << StringPrintf(" ExceptionOnly: type=%#llx(%s) caught=%d uncaught=%d",
Elliott Hughesc308a5d2012-02-16 17:12:06 -08001481 exceptionOrNull, (exceptionOrNull == 0) ? "null" : Dbg::GetClassName(exceptionOrNull).c_str(), caught, uncaught);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001482
Elliott Hughes972a47b2012-02-21 18:16:06 -08001483 mod.exceptionOnly.refTypeId = exceptionOrNull;
1484 mod.exceptionOnly.caught = caught;
1485 mod.exceptionOnly.uncaught = uncaught;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001486 }
1487 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001488 case MK_FIELD_ONLY:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001489 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001490 // For field access/modification events.
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001491 RefTypeId declaring = ReadRefTypeId(&buf);
1492 FieldId fieldId = ReadFieldId(&buf);
Elliott Hughes972a47b2012-02-21 18:16:06 -08001493 mod.fieldOnly.refTypeId = declaring;
1494 mod.fieldOnly.fieldId = fieldId;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001495 }
1496 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001497 case MK_STEP:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001498 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001499 // For use with EK_SINGLE_STEP.
1500 ObjectId thread_id = ReadThreadId(&buf);
1501 uint32_t size = Read4BE(&buf);
1502 uint32_t depth = Read4BE(&buf);
Elliott Hughes74847412012-06-20 18:10:21 -07001503 VLOG(jdwp) << StringPrintf(" Step: thread=%#llx", thread_id)
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001504 << " size=" << JdwpStepSize(size) << " depth=" << JdwpStepDepth(depth);
1505
Elliott Hughes74847412012-06-20 18:10:21 -07001506 mod.step.threadId = thread_id;
Elliott Hughes972a47b2012-02-21 18:16:06 -08001507 mod.step.size = size;
1508 mod.step.depth = depth;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001509 }
1510 break;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001511 case MK_INSTANCE_ONLY:
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001512 {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001513 // Report events related to a specific object.
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001514 ObjectId instance = ReadObjectId(&buf);
Elliott Hughes972a47b2012-02-21 18:16:06 -08001515 mod.instanceOnly.objectId = instance;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001516 }
1517 break;
1518 default:
Elliott Hughes972a47b2012-02-21 18:16:06 -08001519 LOG(WARNING) << "GLITCH: unsupported modKind=" << mod.modKind;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001520 break;
1521 }
1522 }
1523
1524 /*
1525 * Make sure we consumed all data. It is possible that the remote side
1526 * has sent us bad stuff, but for now we blame ourselves.
1527 */
1528 if (buf != origBuf + dataLen) {
1529 LOG(WARNING) << "GLITCH: dataLen is " << dataLen << ", we have consumed " << (buf - origBuf);
1530 }
1531
1532 /*
1533 * We reply with an integer "requestID".
1534 */
Elliott Hughes376a7a02011-10-24 18:35:55 -07001535 uint32_t requestId = state->NextEventSerial();
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001536 expandBufAdd4BE(pReply, requestId);
1537
1538 pEvent->requestId = requestId;
1539
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001540 VLOG(jdwp) << StringPrintf(" --> event requestId=%#x", requestId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001541
1542 /* add it to the list */
Elliott Hughes761928d2011-11-16 18:33:03 -08001543 JdwpError err = state->RegisterEvent(pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001544 if (err != ERR_NONE) {
1545 /* registration failed, probably because event is bogus */
1546 EventFree(pEvent);
1547 LOG(WARNING) << "WARNING: event request rejected";
1548 }
1549 return err;
1550}
1551
1552/*
1553 * Clear an event. Failure to find an event with a matching ID is a no-op
1554 * and does not return an error.
1555 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001556static JdwpError ER_Clear(JdwpState* state, const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001557 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001558 uint8_t eventKind = Read1(&buf);
Elliott Hughesf7c3b662011-10-27 12:04:56 -07001559 uint32_t requestId = Read4BE(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001560
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001561 VLOG(jdwp) << StringPrintf(" Req to clear eventKind=%d requestId=%#x", eventKind, requestId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001562
Elliott Hughes761928d2011-11-16 18:33:03 -08001563 state->UnregisterEventById(requestId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001564
1565 return ERR_NONE;
1566}
1567
1568/*
1569 * Return the values of arguments and local variables.
1570 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001571static JdwpError SF_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001572 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001573 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes546b9862012-06-20 16:06:13 -07001574 FrameId frame_id = ReadFrameId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -08001575 int32_t slot_count = ReadSigned32("slot count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001576
Elliott Hughesa96836a2013-01-17 12:27:49 -08001577 expandBufAdd4BE(pReply, slot_count); /* "int values" */
1578 for (int32_t i = 0; i < slot_count; ++i) {
1579 uint32_t slot = ReadUnsigned32("slot", &buf);
Elliott Hughesaed4be92011-12-02 16:16:23 -08001580 JDWP::JdwpTag reqSigByte = ReadTag(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001581
Elliott Hughes2435a572012-02-17 16:07:41 -08001582 VLOG(jdwp) << " --> slot " << slot << " " << reqSigByte;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001583
Elliott Hughesdbb40792011-11-18 17:05:22 -08001584 size_t width = Dbg::GetTagWidth(reqSigByte);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001585 uint8_t* ptr = expandBufAddSpace(pReply, width+1);
Elliott Hughes74847412012-06-20 18:10:21 -07001586 Dbg::GetLocalValue(thread_id, frame_id, slot, reqSigByte, ptr, width);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001587 }
1588
1589 return ERR_NONE;
1590}
1591
1592/*
1593 * Set the values of arguments and local variables.
1594 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001595static JdwpError SF_SetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001596 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001597 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes546b9862012-06-20 16:06:13 -07001598 FrameId frame_id = ReadFrameId(&buf);
Elliott Hughesa96836a2013-01-17 12:27:49 -08001599 int32_t slot_count = ReadSigned32("slot count", &buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001600
Elliott Hughesa96836a2013-01-17 12:27:49 -08001601 for (int32_t i = 0; i < slot_count; ++i) {
1602 uint32_t slot = ReadUnsigned32("slot", &buf);
Elliott Hughesaed4be92011-12-02 16:16:23 -08001603 JDWP::JdwpTag sigByte = ReadTag(&buf);
Elliott Hughesdbb40792011-11-18 17:05:22 -08001604 size_t width = Dbg::GetTagWidth(sigByte);
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001605 uint64_t value = ReadValue(&buf, width);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001606
Elliott Hughes2435a572012-02-17 16:07:41 -08001607 VLOG(jdwp) << " --> slot " << slot << " " << sigByte << " " << value;
Elliott Hughes74847412012-06-20 18:10:21 -07001608 Dbg::SetLocalValue(thread_id, frame_id, slot, sigByte, value, width);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001609 }
1610
1611 return ERR_NONE;
1612}
1613
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001614static JdwpError SF_ThisObject(JdwpState*, const uint8_t* buf, int, ExpandBuf* reply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001615 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001616 ObjectId thread_id = ReadThreadId(&buf);
Elliott Hughes546b9862012-06-20 16:06:13 -07001617 FrameId frame_id = ReadFrameId(&buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001618
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001619 ObjectId object_id;
1620 JdwpError rc = Dbg::GetThisObject(thread_id, frame_id, &object_id);
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001621 if (rc != ERR_NONE) {
1622 return rc;
Elliott Hughes546b9862012-06-20 16:06:13 -07001623 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001624
Elliott Hughes4993bbc2013-01-10 15:41:25 -08001625 return WriteTaggedObject(reply, object_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001626}
1627
1628/*
1629 * Return the reference type reflected by this class object.
1630 *
1631 * This appears to be required because ReferenceTypeId values are NEVER
1632 * reused, whereas ClassIds can be recycled like any other object. (Either
1633 * that, or I have no idea what this is for.)
1634 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001635static JdwpError COR_ReflectedType(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001636 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa96836a2013-01-17 12:27:49 -08001637 RefTypeId class_object_id = ReadRefTypeId(&buf);
1638 return Dbg::GetReflectedType(class_object_id, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001639}
1640
1641/*
1642 * Handle a DDM packet with a single chunk in it.
1643 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001644static JdwpError DDM_Chunk(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001645 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001646 uint8_t* replyBuf = NULL;
1647 int replyLen = -1;
1648
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001649 VLOG(jdwp) << StringPrintf(" Handling DDM packet (%.4s)", buf);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001650
Elliott Hughesa21039c2012-06-21 12:09:25 -07001651 state->NotifyDdmsActive();
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001652
1653 /*
1654 * If they want to send something back, we copy it into the buffer.
1655 * A no-copy approach would be nicer.
1656 *
1657 * TODO: consider altering the JDWP stuff to hold the packet header
1658 * in a separate buffer. That would allow us to writev() DDM traffic
1659 * instead of copying it into the expanding buffer. The reduction in
1660 * heap requirements is probably more valuable than the efficiency.
1661 */
1662 if (Dbg::DdmHandlePacket(buf, dataLen, &replyBuf, &replyLen)) {
1663 CHECK(replyLen > 0 && replyLen < 1*1024*1024);
1664 memcpy(expandBufAddSpace(pReply, replyLen), replyBuf, replyLen);
1665 free(replyBuf);
1666 }
1667 return ERR_NONE;
1668}
1669
1670/*
1671 * Handler map decl.
1672 */
1673typedef JdwpError (*JdwpRequestHandler)(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* reply);
1674
1675struct JdwpHandlerMap {
1676 uint8_t cmdSet;
1677 uint8_t cmd;
1678 JdwpRequestHandler func;
1679 const char* descr;
1680};
1681
1682/*
1683 * Map commands to functions.
1684 *
1685 * Command sets 0-63 are incoming requests, 64-127 are outbound requests,
1686 * and 128-256 are vendor-defined.
1687 */
1688static const JdwpHandlerMap gHandlerMap[] = {
1689 /* VirtualMachine command set (1) */
Elliott Hughesf327e072013-01-09 16:01:26 -08001690 { 1, 1, VM_Version, "VirtualMachine.Version" },
1691 { 1, 2, VM_ClassesBySignature, "VirtualMachine.ClassesBySignature" },
1692 { 1, 3, VM_AllClasses, "VirtualMachine.AllClasses" },
1693 { 1, 4, VM_AllThreads, "VirtualMachine.AllThreads" },
1694 { 1, 5, VM_TopLevelThreadGroups, "VirtualMachine.TopLevelThreadGroups" },
1695 { 1, 6, VM_Dispose, "VirtualMachine.Dispose" },
1696 { 1, 7, VM_IDSizes, "VirtualMachine.IDSizes" },
1697 { 1, 8, VM_Suspend, "VirtualMachine.Suspend" },
1698 { 1, 9, VM_Resume, "VirtualMachine.Resume" },
1699 { 1, 10, VM_Exit, "VirtualMachine.Exit" },
1700 { 1, 11, VM_CreateString, "VirtualMachine.CreateString" },
1701 { 1, 12, VM_Capabilities, "VirtualMachine.Capabilities" },
1702 { 1, 13, VM_ClassPaths, "VirtualMachine.ClassPaths" },
1703 { 1, 14, VM_DisposeObjects, "VirtualMachine.DisposeObjects" },
1704 { 1, 15, NULL, "VirtualMachine.HoldEvents" },
1705 { 1, 16, NULL, "VirtualMachine.ReleaseEvents" },
1706 { 1, 17, VM_CapabilitiesNew, "VirtualMachine.CapabilitiesNew" },
1707 { 1, 18, NULL, "VirtualMachine.RedefineClasses" },
1708 { 1, 19, NULL, "VirtualMachine.SetDefaultStratum" },
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001709 { 1, 20, VM_AllClassesWithGeneric, "VirtualMachine.AllClassesWithGeneric" },
Elliott Hughesec0f83d2013-01-15 16:54:08 -08001710 { 1, 21, VM_InstanceCounts, "VirtualMachine.InstanceCounts" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001711
1712 /* ReferenceType command set (2) */
Elliott Hughesf327e072013-01-09 16:01:26 -08001713 { 2, 1, RT_Signature, "ReferenceType.Signature" },
1714 { 2, 2, RT_ClassLoader, "ReferenceType.ClassLoader" },
1715 { 2, 3, RT_Modifiers, "ReferenceType.Modifiers" },
1716 { 2, 4, RT_Fields, "ReferenceType.Fields" },
1717 { 2, 5, RT_Methods, "ReferenceType.Methods" },
1718 { 2, 6, RT_GetValues, "ReferenceType.GetValues" },
1719 { 2, 7, RT_SourceFile, "ReferenceType.SourceFile" },
1720 { 2, 8, NULL, "ReferenceType.NestedTypes" },
1721 { 2, 9, RT_Status, "ReferenceType.Status" },
1722 { 2, 10, RT_Interfaces, "ReferenceType.Interfaces" },
1723 { 2, 11, RT_ClassObject, "ReferenceType.ClassObject" },
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001724 { 2, 12, RT_SourceDebugExtension, "ReferenceType.SourceDebugExtension" },
1725 { 2, 13, RT_SignatureWithGeneric, "ReferenceType.SignatureWithGeneric" },
Elliott Hughesf327e072013-01-09 16:01:26 -08001726 { 2, 14, RT_FieldsWithGeneric, "ReferenceType.FieldsWithGeneric" },
1727 { 2, 15, RT_MethodsWithGeneric, "ReferenceType.MethodsWithGeneric" },
Elliott Hughes3b78c942013-01-15 17:35:41 -08001728 { 2, 16, RT_Instances, "ReferenceType.Instances" },
Elliott Hughesf327e072013-01-09 16:01:26 -08001729 { 2, 17, NULL, "ReferenceType.ClassFileVersion" },
1730 { 2, 18, NULL, "ReferenceType.ConstantPool" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001731
1732 /* ClassType command set (3) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001733 { 3, 1, CT_Superclass, "ClassType.Superclass" },
1734 { 3, 2, CT_SetValues, "ClassType.SetValues" },
1735 { 3, 3, CT_InvokeMethod, "ClassType.InvokeMethod" },
1736 { 3, 4, CT_NewInstance, "ClassType.NewInstance" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001737
1738 /* ArrayType command set (4) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001739 { 4, 1, AT_newInstance, "ArrayType.NewInstance" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001740
1741 /* InterfaceType command set (5) */
1742
1743 /* Method command set (6) */
Elliott Hughesf327e072013-01-09 16:01:26 -08001744 { 6, 1, M_LineTable, "Method.LineTable" },
1745 { 6, 2, M_VariableTable, "Method.VariableTable" },
Elliott Hughes9777ba22013-01-17 09:04:19 -08001746 { 6, 3, M_Bytecodes, "Method.Bytecodes" },
Elliott Hughesf327e072013-01-09 16:01:26 -08001747 { 6, 4, NULL, "Method.IsObsolete" },
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001748 { 6, 5, M_VariableTableWithGeneric, "Method.VariableTableWithGeneric" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001749
1750 /* Field command set (8) */
1751
1752 /* ObjectReference command set (9) */
Elliott Hughesf327e072013-01-09 16:01:26 -08001753 { 9, 1, OR_ReferenceType, "ObjectReference.ReferenceType" },
1754 { 9, 2, OR_GetValues, "ObjectReference.GetValues" },
1755 { 9, 3, OR_SetValues, "ObjectReference.SetValues" },
1756 { 9, 4, NULL, "ObjectReference.UNUSED" },
1757 { 9, 5, OR_MonitorInfo, "ObjectReference.MonitorInfo" },
1758 { 9, 6, OR_InvokeMethod, "ObjectReference.InvokeMethod" },
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001759 { 9, 7, OR_DisableCollection, "ObjectReference.DisableCollection" },
Elliott Hughesf327e072013-01-09 16:01:26 -08001760 { 9, 8, OR_EnableCollection, "ObjectReference.EnableCollection" },
1761 { 9, 9, OR_IsCollected, "ObjectReference.IsCollected" },
Elliott Hughes0cbaff52013-01-16 15:28:01 -08001762 { 9, 10, OR_ReferringObjects, "ObjectReference.ReferringObjects" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001763
1764 /* StringReference command set (10) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001765 { 10, 1, SR_Value, "StringReference.Value" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001766
1767 /* ThreadReference command set (11) */
Elliott Hughes734b8c62013-01-11 15:32:45 -08001768 { 11, 1, TR_Name, "ThreadReference.Name" },
1769 { 11, 2, TR_Suspend, "ThreadReference.Suspend" },
1770 { 11, 3, TR_Resume, "ThreadReference.Resume" },
1771 { 11, 4, TR_Status, "ThreadReference.Status" },
1772 { 11, 5, TR_ThreadGroup, "ThreadReference.ThreadGroup" },
1773 { 11, 6, TR_Frames, "ThreadReference.Frames" },
1774 { 11, 7, TR_FrameCount, "ThreadReference.FrameCount" },
1775 { 11, 8, TR_OwnedMonitors, "ThreadReference.OwnedMonitors" },
1776 { 11, 9, TR_CurrentContendedMonitor, "ThreadReference.CurrentContendedMonitor" },
1777 { 11, 10, NULL, "ThreadReference.Stop" },
1778 { 11, 11, TR_Interrupt, "ThreadReference.Interrupt" },
1779 { 11, 12, TR_DebugSuspendCount, "ThreadReference.SuspendCount" },
1780 { 11, 13, TR_OwnedMonitorsStackDepthInfo, "ThreadReference.OwnedMonitorsStackDepthInfo" },
1781 { 11, 14, NULL, "ThreadReference.ForceEarlyReturn" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001782
1783 /* ThreadGroupReference command set (12) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001784 { 12, 1, TGR_Name, "ThreadGroupReference.Name" },
1785 { 12, 2, TGR_Parent, "ThreadGroupReference.Parent" },
1786 { 12, 3, TGR_Children, "ThreadGroupReference.Children" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001787
1788 /* ArrayReference command set (13) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001789 { 13, 1, AR_Length, "ArrayReference.Length" },
1790 { 13, 2, AR_GetValues, "ArrayReference.GetValues" },
1791 { 13, 3, AR_SetValues, "ArrayReference.SetValues" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001792
1793 /* ClassLoaderReference command set (14) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001794 { 14, 1, CLR_VisibleClasses, "ClassLoaderReference.VisibleClasses" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001795
1796 /* EventRequest command set (15) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001797 { 15, 1, ER_Set, "EventRequest.Set" },
1798 { 15, 2, ER_Clear, "EventRequest.Clear" },
Elliott Hughesf327e072013-01-09 16:01:26 -08001799 { 15, 3, NULL, "EventRequest.ClearAllBreakpoints" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001800
1801 /* StackFrame command set (16) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001802 { 16, 1, SF_GetValues, "StackFrame.GetValues" },
1803 { 16, 2, SF_SetValues, "StackFrame.SetValues" },
1804 { 16, 3, SF_ThisObject, "StackFrame.ThisObject" },
Elliott Hughesf327e072013-01-09 16:01:26 -08001805 { 16, 4, NULL, "StackFrame.PopFrames" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001806
1807 /* ClassObjectReference command set (17) */
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001808 { 17, 1, COR_ReflectedType, "ClassObjectReference.ReflectedType" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001809
1810 /* Event command set (64) */
Elliott Hughesf327e072013-01-09 16:01:26 -08001811 { 64, 100, NULL, "Event.Composite" }, // sent from VM to debugger, never received by VM
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001812
Elliott Hughes6e9d22c2012-06-22 15:02:37 -07001813 { 199, 1, DDM_Chunk, "DDM.Chunk" },
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001814};
1815
Elliott Hughesa3c24aa2011-12-07 15:34:09 -08001816static const char* GetCommandName(size_t cmdSet, size_t cmd) {
Elliott Hughes74847412012-06-20 18:10:21 -07001817 for (size_t i = 0; i < arraysize(gHandlerMap); ++i) {
Elliott Hughesa3c24aa2011-12-07 15:34:09 -08001818 if (gHandlerMap[i].cmdSet == cmdSet && gHandlerMap[i].cmd == cmd) {
1819 return gHandlerMap[i].descr;
1820 }
1821 }
1822 return "?UNKNOWN?";
1823}
1824
1825static std::string DescribeCommand(const JdwpReqHeader* pHeader, int dataLen) {
1826 std::string result;
1827 result += "REQ: ";
1828 result += GetCommandName(pHeader->cmdSet, pHeader->cmd);
1829 result += StringPrintf(" (dataLen=%d id=0x%06x)", dataLen, pHeader->id);
1830 return result;
1831}
1832
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001833/*
1834 * Process a request from the debugger.
1835 *
1836 * On entry, the JDWP thread is in VMWAIT.
1837 */
Elliott Hughes376a7a02011-10-24 18:35:55 -07001838void JdwpState::ProcessRequest(const JdwpReqHeader* pHeader, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001839 JdwpError result = ERR_NONE;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001840
1841 if (pHeader->cmdSet != kJDWPDdmCmdSet) {
1842 /*
1843 * Activity from a debugger, not merely ddms. Mark us as having an
1844 * active debugger session, and zero out the last-activity timestamp
1845 * so waitForDebugger() doesn't return if we stall for a bit here.
1846 */
Elliott Hughesa2155262011-11-16 16:26:58 -08001847 Dbg::GoActive();
Ian Rogers9adbff52013-01-23 18:19:03 -08001848 QuasiAtomic::Write64(&last_activity_time_ms_, 0);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001849 }
1850
1851 /*
1852 * If a debugger event has fired in another thread, wait until the
1853 * initiating thread has suspended itself before processing messages
1854 * from the debugger. Otherwise we (the JDWP thread) could be told to
1855 * resume the thread before it has suspended.
1856 *
1857 * We call with an argument of zero to wait for the current event
1858 * thread to finish, and then clear the block. Depending on the thread
1859 * suspend policy, this may allow events in other threads to fire,
1860 * but those events have no bearing on what the debugger has sent us
1861 * in the current request.
1862 *
1863 * Note that we MUST clear the event token before waking the event
1864 * thread up, or risk waiting for the thread to suspend after we've
1865 * told it to resume.
1866 */
Elliott Hughes376a7a02011-10-24 18:35:55 -07001867 SetWaitForEventThread(0);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001868
1869 /*
1870 * Tell the VM that we're running and shouldn't be interrupted by GC.
1871 * Do this after anything that can stall indefinitely.
1872 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001873 Thread* self = Thread::Current();
1874 ThreadState old_state = self->TransitionFromSuspendedToRunnable();
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001875
1876 expandBufAddSpace(pReply, kJDWPHeaderLen);
1877
Elliott Hughesa3c24aa2011-12-07 15:34:09 -08001878 size_t i;
Elliott Hughesa96836a2013-01-17 12:27:49 -08001879 for (i = 0; i < arraysize(gHandlerMap); ++i) {
Elliott Hughesa3c24aa2011-12-07 15:34:09 -08001880 if (gHandlerMap[i].cmdSet == pHeader->cmdSet && gHandlerMap[i].cmd == pHeader->cmd && gHandlerMap[i].func != NULL) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001881 VLOG(jdwp) << DescribeCommand(pHeader, dataLen);
Elliott Hughes376a7a02011-10-24 18:35:55 -07001882 result = (*gHandlerMap[i].func)(this, buf, dataLen, pReply);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001883 break;
1884 }
1885 }
1886 if (i == arraysize(gHandlerMap)) {
Elliott Hughesbfbf0e22012-03-29 18:09:19 -07001887 LOG(ERROR) << "Command not implemented: " << DescribeCommand(pHeader, dataLen);
1888 LOG(ERROR) << HexDump(buf, dataLen);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001889 result = ERR_NOT_IMPLEMENTED;
1890 }
1891
1892 /*
1893 * Set up the reply header.
1894 *
1895 * If we encountered an error, only send the header back.
1896 */
1897 uint8_t* replyBuf = expandBufGetBuffer(pReply);
Elliott Hughesf7c3b662011-10-27 12:04:56 -07001898 Set4BE(replyBuf + 4, pHeader->id);
1899 Set1(replyBuf + 8, kJDWPFlagReply);
1900 Set2BE(replyBuf + 9, result);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001901 if (result == ERR_NONE) {
Elliott Hughesf7c3b662011-10-27 12:04:56 -07001902 Set4BE(replyBuf + 0, expandBufGetLength(pReply));
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001903 } else {
Elliott Hughesf7c3b662011-10-27 12:04:56 -07001904 Set4BE(replyBuf + 0, kJDWPHeaderLen);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001905 }
1906
Elliott Hughesa3c24aa2011-12-07 15:34:09 -08001907 size_t respLen = expandBufGetLength(pReply) - kJDWPHeaderLen;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001908 if (false) {
1909 LOG(INFO) << "reply: dataLen=" << respLen << " err=" << result << (result != ERR_NONE ? " **FAILED**" : "");
Elliott Hughesbfbf0e22012-03-29 18:09:19 -07001910 LOG(INFO) << HexDump(expandBufGetBuffer(pReply) + kJDWPHeaderLen, respLen);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001911 }
1912
1913 /*
1914 * Update last-activity timestamp. We really only need this during
1915 * the initial setup. Only update if this is a non-DDMS packet.
1916 */
1917 if (pHeader->cmdSet != kJDWPDdmCmdSet) {
Ian Rogers9adbff52013-01-23 18:19:03 -08001918 QuasiAtomic::Write64(&last_activity_time_ms_, MilliTime());
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001919 }
1920
1921 /* tell the VM that GC is okay again */
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001922 self->TransitionFromRunnableToSuspended(old_state);
1923
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001924}
1925
1926} // namespace JDWP
1927
1928} // namespace art