1872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 2872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Copyright (C) 2008 The Android Open Source Project 3872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 4872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * you may not use this file except in compliance with the License. 6872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * You may obtain a copy of the License at 7872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 8872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 10872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Unless required by applicable law or agreed to in writing, software 11872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * See the License for the specific language governing permissions and 14872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * limitations under the License. 15872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 16872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1707ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include <stdlib.h> 1807ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include <string.h> 1907ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include <unistd.h> 20700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <memory> 21a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes#include <string> 22a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes 23872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include "atomic.h" 2443b2e0f9105848da6470458e7c04bf1fd7fcb25cIan Rogers#include "base/hex_dump.h" 2507ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h" 26761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h" 27e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringprintf.h" 28872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include "debugger.h" 29872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include "jdwp/jdwp_constants.h" 3007ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_event.h" 31872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include "jdwp/jdwp_expand_buf.h" 3207ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_priv.h" 332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "runtime.h" 34f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier#include "scoped_thread_state_change.h" 35693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers#include "thread-inl.h" 3680afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "utils.h" 37872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 38872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesnamespace art { 39872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 40872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesnamespace JDWP { 41872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 424b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughesstd::string DescribeField(const FieldId& field_id) { 43d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier return StringPrintf("%#" PRIx64 " (%s)", field_id, Dbg::GetFieldName(field_id).c_str()); 44a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes} 45a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes 464b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughesstd::string DescribeMethod(const MethodId& method_id) { 47d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier return StringPrintf("%#" PRIx64 " (%s)", method_id, Dbg::GetMethodName(method_id).c_str()); 48a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes} 49a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes 504b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughesstd::string DescribeRefTypeId(const RefTypeId& ref_type_id) { 51a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes std::string signature("unknown"); 52fc0e94bed3f88ed7e50854fd8dfaf5dcb345250fIan Rogers Dbg::GetSignature(ref_type_id, &signature); 53d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers return StringPrintf("%#" PRIx64 " (%s)", ref_type_id, signature.c_str()); 54872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 55872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 564993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughesstatic JdwpError WriteTaggedObject(ExpandBuf* reply, ObjectId object_id) 5790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 584993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes uint8_t tag; 59c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError rc = Dbg::GetObjectTag(object_id, &tag); 604993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes if (rc == ERR_NONE) { 614993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, tag); 624993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAddObjectId(reply, object_id); 634993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes } 644993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes return rc; 654993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes} 664993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes 670cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughesstatic JdwpError WriteTaggedObjectList(ExpandBuf* reply, const std::vector<ObjectId>& objects) 6890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 690cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes expandBufAdd4BE(reply, objects.size()); 700cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes for (size_t i = 0; i < objects.size(); ++i) { 710cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes JdwpError rc = WriteTaggedObject(reply, objects[i]); 720cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes if (rc != ERR_NONE) { 730cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes return rc; 740cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes } 750cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes } 760cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes return ERR_NONE; 770cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes} 780cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes 79872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 80872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Common code for *_InvokeMethod requests. 81872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 82748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes * If "is_constructor" is set, this returns "object_id" rather than the 83872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * expected-to-be-void return value of the called function. 84872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 85cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertzstatic JdwpError RequestInvoke(JdwpState*, Request* request, 861558b577907b613864e98f05862543557263e864Sebastien Hertz ObjectId thread_id, ObjectId object_id, 871558b577907b613864e98f05862543557263e864Sebastien Hertz RefTypeId class_id, MethodId method_id, bool is_constructor) 8890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 89748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes CHECK(!is_constructor || object_id != 0); 90872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 91c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers int32_t arg_count = request->ReadSigned32("argument count"); 92872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 93d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers VLOG(jdwp) << StringPrintf(" --> thread_id=%#" PRIx64 " object_id=%#" PRIx64, 94d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers thread_id, object_id); 95d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier VLOG(jdwp) << StringPrintf(" class_id=%#" PRIx64 " method_id=%#" PRIx64 " %s.%s", 96d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier class_id, method_id, Dbg::GetClassName(class_id).c_str(), 97a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes Dbg::GetMethodName(method_id).c_str()); 9845651fde99f52546e71241bb0e8a10d16a9f216aElliott Hughes VLOG(jdwp) << StringPrintf(" %d args:", arg_count); 9945651fde99f52546e71241bb0e8a10d16a9f216aElliott Hughes 1007d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz std::unique_ptr<JdwpTag[]> argTypes(arg_count > 0 ? new JdwpTag[arg_count] : nullptr); 1017d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz std::unique_ptr<uint64_t[]> argValues(arg_count > 0 ? new uint64_t[arg_count] : nullptr); 102a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes for (int32_t i = 0; i < arg_count; ++i) { 103c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers argTypes[i] = request->ReadTag(); 10445651fde99f52546e71241bb0e8a10d16a9f216aElliott Hughes size_t width = Dbg::GetTagWidth(argTypes[i]); 105c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers argValues[i] = request->ReadValue(width); 106d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers VLOG(jdwp) << " " << argTypes[i] << StringPrintf("(%zd): %#" PRIx64, width, 107d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers argValues[i]); 108872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 109872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 110c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint32_t options = request->ReadUnsigned32("InvokeOptions bit flags"); 11100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers VLOG(jdwp) << StringPrintf(" options=0x%04x%s%s", options, 11200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers (options & INVOKE_SINGLE_THREADED) ? " (SINGLE_THREADED)" : "", 11300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers (options & INVOKE_NONVIRTUAL) ? " (NONVIRTUAL)" : ""); 114872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 115cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz JDWP::JdwpError error = Dbg::PrepareInvokeMethod(request->GetId(), thread_id, object_id, 116cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz class_id, method_id, arg_count, 117cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz argValues.get(), argTypes.get(), options); 118cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz if (error == JDWP::ERR_NONE) { 119cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz // We successfully requested the invoke. The event thread now owns the arguments array in its 120cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz // DebugInvokeReq mailbox. 121cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz argValues.release(); 122872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 123cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz return error; 124872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 125872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 126c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_Version(JdwpState*, Request*, ExpandBuf* pReply) 12790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 128927bd29ded304e143a967ef014c13a02af4c5c4bElliott Hughes // Text information on runtime version. 129872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes std::string version(StringPrintf("Android Runtime %s", Runtime::Current()->GetVersion())); 1304740cdff25875c530649a670b15e8ac52bfd7252Elliott Hughes expandBufAddUtf8String(pReply, version); 131927bd29ded304e143a967ef014c13a02af4c5c4bElliott Hughes 132927bd29ded304e143a967ef014c13a02af4c5c4bElliott Hughes // JDWP version numbers, major and minor. 133927bd29ded304e143a967ef014c13a02af4c5c4bElliott Hughes expandBufAdd4BE(pReply, 1); 134927bd29ded304e143a967ef014c13a02af4c5c4bElliott Hughes expandBufAdd4BE(pReply, 6); 135927bd29ded304e143a967ef014c13a02af4c5c4bElliott Hughes 136927bd29ded304e143a967ef014c13a02af4c5c4bElliott Hughes // "java.version". 137927bd29ded304e143a967ef014c13a02af4c5c4bElliott Hughes expandBufAddUtf8String(pReply, "1.6.0"); 138927bd29ded304e143a967ef014c13a02af4c5c4bElliott Hughes 139927bd29ded304e143a967ef014c13a02af4c5c4bElliott Hughes // "java.vm.name". 140927bd29ded304e143a967ef014c13a02af4c5c4bElliott Hughes expandBufAddUtf8String(pReply, "Dalvik"); 141872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 142872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 143872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 144872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 145872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 146872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Given a class JNI signature (e.g. "Ljava/lang/Error;"), return the 147872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * referenceTypeID. We need to send back more than one if the class has 148872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * been loaded by multiple class loaders. 149872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 150c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_ClassesBySignature(JdwpState*, Request* request, ExpandBuf* pReply) 15190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 152c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers std::string classDescriptor(request->ReadUtf8String()); 153872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1546fa602d614d418f38afebb4d44f42e7dc0b4bd94Elliott Hughes std::vector<RefTypeId> ids; 155c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers Dbg::FindLoadedClassBySignature(classDescriptor.c_str(), &ids); 156872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1576fa602d614d418f38afebb4d44f42e7dc0b4bd94Elliott Hughes expandBufAdd4BE(pReply, ids.size()); 158872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1596fa602d614d418f38afebb4d44f42e7dc0b4bd94Elliott Hughes for (size_t i = 0; i < ids.size(); ++i) { 1606fa602d614d418f38afebb4d44f42e7dc0b4bd94Elliott Hughes // Get class vs. interface and status flags. 161436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes JDWP::JdwpTypeTag type_tag; 162436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes uint32_t class_status; 1637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz JDWP::JdwpError status = Dbg::GetClassInfo(ids[i], &type_tag, &class_status, nullptr); 164436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes if (status != ERR_NONE) { 165436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes return status; 1667b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes } 167872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 168436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes expandBufAdd1(pReply, type_tag); 1696fa602d614d418f38afebb4d44f42e7dc0b4bd94Elliott Hughes expandBufAddRefTypeId(pReply, ids[i]); 170436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes expandBufAdd4BE(pReply, class_status); 171872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 172872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 173872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 174872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 175872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 176872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 177872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Handle request for the thread IDs of all running threads. 178872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 179872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * We exclude ourselves from the list, because we don't allow ourselves 180872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * to be suspended, and that violates some JDWP expectations. 181872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 182c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_AllThreads(JdwpState*, Request*, ExpandBuf* pReply) 18390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 184caf7654a0e6c76c7489970b1a246fccf220f9982Elliott Hughes std::vector<ObjectId> thread_ids; 185a06430c76981d545b5f2b64a7ef53c44c030cf73Sebastien Hertz Dbg::GetThreads(nullptr /* all thread groups */, &thread_ids); 186872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 187caf7654a0e6c76c7489970b1a246fccf220f9982Elliott Hughes expandBufAdd4BE(pReply, thread_ids.size()); 188caf7654a0e6c76c7489970b1a246fccf220f9982Elliott Hughes for (uint32_t i = 0; i < thread_ids.size(); ++i) { 189caf7654a0e6c76c7489970b1a246fccf220f9982Elliott Hughes expandBufAddObjectId(pReply, thread_ids[i]); 190872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 191872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 192872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 193872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 194872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 195872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 196872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * List all thread groups that do not have a parent. 197872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 198c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_TopLevelThreadGroups(JdwpState*, Request*, ExpandBuf* pReply) 19990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 200872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* 201872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * TODO: maintain a list of parentless thread groups in the VM. 202872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 203872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * For now, just return "system". Application threads are created 204872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * in "main", which is a child of "system". 205872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 206872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes uint32_t groups = 1; 207872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAdd4BE(pReply, groups); 208caf7654a0e6c76c7489970b1a246fccf220f9982Elliott Hughes ObjectId thread_group_id = Dbg::GetSystemThreadGroupId(); 209caf7654a0e6c76c7489970b1a246fccf220f9982Elliott Hughes expandBufAddObjectId(pReply, thread_group_id); 210872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 211872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 212872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 213872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 214872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 215872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Respond with the sizes of the basic debugger types. 216872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 217c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_IDSizes(JdwpState*, Request*, ExpandBuf* pReply) 21890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 219872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAdd4BE(pReply, sizeof(FieldId)); 220872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAdd4BE(pReply, sizeof(MethodId)); 221872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAdd4BE(pReply, sizeof(ObjectId)); 222872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAdd4BE(pReply, sizeof(RefTypeId)); 223872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAdd4BE(pReply, sizeof(FrameId)); 224872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 225872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 226872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 227c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_Dispose(JdwpState*, Request*, ExpandBuf*) 22890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 2294e5b20863898006ec6c9d120cda167d38dda6e60Sebastien Hertz Dbg::Dispose(); 230872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 231872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 232872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 233872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 234872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Suspend the execution of the application running in the VM (i.e. suspend 235872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * all threads). 236872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 237872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * This needs to increment the "suspend count" on all threads. 238872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 239c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_Suspend(JdwpState*, Request*, ExpandBuf*) 24090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 241a77f0f68a59870ff027dad654fe31eb3fdaf3d5djeffhao Thread* self = Thread::Current(); 242f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier ScopedThreadSuspension sts(self, kWaitingForDebuggerSuspension); 243475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes Dbg::SuspendVM(); 244872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 245872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 246872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 247872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 248872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Resume execution. Decrements the "suspend count" of all threads. 249872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 250c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_Resume(JdwpState*, Request*, ExpandBuf*) 25190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 252872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes Dbg::ResumeVM(); 253872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 254872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 255872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 256c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_Exit(JdwpState* state, Request* request, ExpandBuf*) 25790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 258c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint32_t exit_status = request->ReadUnsigned32("exit_status"); 25964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes state->ExitAfterReplying(exit_status); 26064f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes return ERR_NONE; 261872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 262872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 263872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 264872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Create a new string in the VM and return its ID. 265872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 266872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * (Ctrl-Shift-I in Eclipse on an array of objects causes it to create the 267872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * string "java.util.Arrays".) 268872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 269c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_CreateString(JdwpState*, Request* request, ExpandBuf* pReply) 27090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 271c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers std::string str(request->ReadUtf8String()); 2722c3e77a0b91b2225fcdd3b34d8a734b85eec0579Sebastien Hertz ObjectId string_id; 2732c3e77a0b91b2225fcdd3b34d8a734b85eec0579Sebastien Hertz JdwpError status = Dbg::CreateString(str, &string_id); 2742c3e77a0b91b2225fcdd3b34d8a734b85eec0579Sebastien Hertz if (status != ERR_NONE) { 2752c3e77a0b91b2225fcdd3b34d8a734b85eec0579Sebastien Hertz return status; 276872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 2772c3e77a0b91b2225fcdd3b34d8a734b85eec0579Sebastien Hertz expandBufAddObjectId(pReply, string_id); 278872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 279872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 280872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 281c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_ClassPaths(JdwpState*, Request*, ExpandBuf* pReply) 28290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 283a3ae2b7c6598e9b1cf08e42ae4a8de38237b181bElliott Hughes expandBufAddUtf8String(pReply, "/"); 284872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 285a3ae2b7c6598e9b1cf08e42ae4a8de38237b181bElliott Hughes std::vector<std::string> class_path; 2866f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers Split(Runtime::Current()->GetClassPathString(), ':', &class_path); 287a3ae2b7c6598e9b1cf08e42ae4a8de38237b181bElliott Hughes expandBufAdd4BE(pReply, class_path.size()); 288e6c143fae8ec487704b3d0d28914cda3d6d19e88Sebastien Hertz for (const std::string& str : class_path) { 289e6c143fae8ec487704b3d0d28914cda3d6d19e88Sebastien Hertz expandBufAddUtf8String(pReply, str); 290872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 291872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 292a3ae2b7c6598e9b1cf08e42ae4a8de38237b181bElliott Hughes std::vector<std::string> boot_class_path; 2936f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers Split(Runtime::Current()->GetBootClassPathString(), ':', &boot_class_path); 294a3ae2b7c6598e9b1cf08e42ae4a8de38237b181bElliott Hughes expandBufAdd4BE(pReply, boot_class_path.size()); 295e6c143fae8ec487704b3d0d28914cda3d6d19e88Sebastien Hertz for (const std::string& str : boot_class_path) { 296e6c143fae8ec487704b3d0d28914cda3d6d19e88Sebastien Hertz expandBufAddUtf8String(pReply, str); 297872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 298872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 299872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 300872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 301872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 302c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_DisposeObjects(JdwpState*, Request* request, ExpandBuf*) 30390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 304c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers size_t object_count = request->ReadUnsigned32("object_count"); 30564f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes for (size_t i = 0; i < object_count; ++i) { 306c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId object_id = request->ReadObjectId(); 307c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint32_t reference_count = request->ReadUnsigned32("reference_count"); 30864f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes Dbg::DisposeObject(object_id, reference_count); 30964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes } 310872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 311872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 312872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 313c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_Capabilities(JdwpState*, Request*, ExpandBuf* reply) 31490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 315479fc1ecc12fa6560ca90d841c4d5174fb346618Sebastien Hertz expandBufAdd1(reply, true); // canWatchFieldModification 316479fc1ecc12fa6560ca90d841c4d5174fb346618Sebastien Hertz expandBufAdd1(reply, true); // canWatchFieldAccess 3179777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes expandBufAdd1(reply, true); // canGetBytecodes 3184993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, true); // canGetSyntheticAttribute 3194993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, true); // canGetOwnedMonitorInfo 320f9501700f51586cb6ba7cc0ffcb5a920bd64adf1Elliott Hughes expandBufAdd1(reply, true); // canGetCurrentContendedMonitor 3214993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, true); // canGetMonitorInfo 3224993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes return ERR_NONE; 3234993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes} 3244993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes 325c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_CapabilitiesNew(JdwpState*, Request* request, ExpandBuf* reply) 32690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 3274993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes // The first few capabilities are the same as those reported by the older call. 3287d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VM_Capabilities(nullptr, request, reply); 3294993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes 3304993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, false); // canRedefineClasses 3314993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, false); // canAddMethod 3324993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, false); // canUnrestrictedlyRedefineClasses 3334993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, false); // canPopFrames 3345f4e6f56fcc4289eed73e7ad00d874148aeb68d1Sebastien Hertz expandBufAdd1(reply, true); // canUseInstanceFilters 3354993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, false); // canGetSourceDebugExtension 3364993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, false); // canRequestVMDeathEvent 3374993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, false); // canSetDefaultStratum 338ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes expandBufAdd1(reply, true); // 1.6: canGetInstanceInfo 3394993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, false); // 1.6: canRequestMonitorEvents 340734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes expandBufAdd1(reply, true); // 1.6: canGetMonitorFrameInfo 3414993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, false); // 1.6: canUseSourceNameFilters 3424993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, false); // 1.6: canGetConstantPool 3434993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, false); // 1.6: canForceEarlyReturn 3444993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes 3454993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes // Fill in reserved22 through reserved32; note count started at 1. 3464993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes for (size_t i = 22; i <= 32; ++i) { 3474993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd1(reply, false); 348872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 349872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 350872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 351872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 35200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic JdwpError VM_AllClassesImpl(ExpandBuf* pReply, bool descriptor_and_status, bool generic) 35390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 3547b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes std::vector<JDWP::RefTypeId> classes; 355c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers Dbg::GetClassList(&classes); 356872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 3577b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes expandBufAdd4BE(pReply, classes.size()); 358872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 3597b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes for (size_t i = 0; i < classes.size(); ++i) { 360a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes static const char genericSignature[1] = ""; 361436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes JDWP::JdwpTypeTag type_tag; 362a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes std::string descriptor; 363436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes uint32_t class_status; 364436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes JDWP::JdwpError status = Dbg::GetClassInfo(classes[i], &type_tag, &class_status, &descriptor); 365436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes if (status != ERR_NONE) { 366436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes return status; 3677b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes } 368872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 369436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes expandBufAdd1(pReply, type_tag); 3707b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes expandBufAddRefTypeId(pReply, classes[i]); 3718696433d1b3d8ba15288483b777edd888de69135Elliott Hughes if (descriptor_and_status) { 3728696433d1b3d8ba15288483b777edd888de69135Elliott Hughes expandBufAddUtf8String(pReply, descriptor); 3738696433d1b3d8ba15288483b777edd888de69135Elliott Hughes if (generic) { 3748696433d1b3d8ba15288483b777edd888de69135Elliott Hughes expandBufAddUtf8String(pReply, genericSignature); 3758696433d1b3d8ba15288483b777edd888de69135Elliott Hughes } 376436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes expandBufAdd4BE(pReply, class_status); 3771fe7afb88498d48d1f808ee31e986324f2a1c842Elliott Hughes } 378872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 379872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 380872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 381872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 382872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 383c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_AllClasses(JdwpState*, Request*, ExpandBuf* pReply) 38490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 3856e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes return VM_AllClassesImpl(pReply, true, false); 3861fe7afb88498d48d1f808ee31e986324f2a1c842Elliott Hughes} 3871fe7afb88498d48d1f808ee31e986324f2a1c842Elliott Hughes 388c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_AllClassesWithGeneric(JdwpState*, Request*, ExpandBuf* pReply) 38990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 3906e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes return VM_AllClassesImpl(pReply, true, true); 3911fe7afb88498d48d1f808ee31e986324f2a1c842Elliott Hughes} 3921fe7afb88498d48d1f808ee31e986324f2a1c842Elliott Hughes 393c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError VM_InstanceCounts(JdwpState*, Request* request, ExpandBuf* pReply) 39490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 395c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers int32_t class_count = request->ReadSigned32("class count"); 396ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes if (class_count < 0) { 397ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes return ERR_ILLEGAL_ARGUMENT; 398ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes } 399ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes std::vector<RefTypeId> class_ids; 400ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes for (int32_t i = 0; i < class_count; ++i) { 401c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers class_ids.push_back(request->ReadRefTypeId()); 402ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes } 403ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes 404ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes std::vector<uint64_t> counts; 405c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError rc = Dbg::GetInstanceCounts(class_ids, &counts); 406ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes if (rc != ERR_NONE) { 407ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes return rc; 408ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes } 409ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes 410ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes expandBufAdd4BE(pReply, counts.size()); 411ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes for (size_t i = 0; i < counts.size(); ++i) { 412ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes expandBufAdd8BE(pReply, counts[i]); 413ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes } 414ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes return ERR_NONE; 415ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes} 416ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes 417c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_Modifiers(JdwpState*, Request* request, ExpandBuf* pReply) 41890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 419c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId refTypeId = request->ReadRefTypeId(); 420436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes return Dbg::GetModifiers(refTypeId, pReply); 421872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 422872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 423872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 424872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Get values from static fields in a reference type. 425872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 426c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_GetValues(JdwpState*, Request* request, ExpandBuf* pReply) 42790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 428c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId refTypeId = request->ReadRefTypeId(); 429c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers int32_t field_count = request->ReadSigned32("field count"); 4300cf7433fd2a93b7f83e8b2ac91d0d1b4f0e7d0c9Elliott Hughes expandBufAdd4BE(pReply, field_count); 431a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes for (int32_t i = 0; i < field_count; ++i) { 432c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers FieldId fieldId = request->ReadFieldId(); 4330cf7433fd2a93b7f83e8b2ac91d0d1b4f0e7d0c9Elliott Hughes JdwpError status = Dbg::GetStaticFieldValue(refTypeId, fieldId, pReply); 4343f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes if (status != ERR_NONE) { 4353f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes return status; 4363f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes } 437872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 438872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 439872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 440872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 441872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 442872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Get the name of the source file in which a reference type was declared. 443872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 444c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_SourceFile(JdwpState*, Request* request, ExpandBuf* pReply) 44590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 446c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId refTypeId = request->ReadRefTypeId(); 44703181a828cd493545b278e0aa4f150fdaf1e3325Elliott Hughes std::string source_file; 448c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError status = Dbg::GetSourceFile(refTypeId, &source_file); 449436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes if (status != ERR_NONE) { 450436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes return status; 451872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 4524740cdff25875c530649a670b15e8ac52bfd7252Elliott Hughes expandBufAddUtf8String(pReply, source_file); 45303181a828cd493545b278e0aa4f150fdaf1e3325Elliott Hughes return ERR_NONE; 454872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 455872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 456872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 457872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return the current status of the reference type. 458872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 459c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_Status(JdwpState*, Request* request, ExpandBuf* pReply) 46090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 461c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId refTypeId = request->ReadRefTypeId(); 462436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes JDWP::JdwpTypeTag type_tag; 463436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes uint32_t class_status; 4647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz JDWP::JdwpError status = Dbg::GetClassInfo(refTypeId, &type_tag, &class_status, nullptr); 465436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes if (status != ERR_NONE) { 466436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes return status; 4677b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes } 468436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes expandBufAdd4BE(pReply, class_status); 469872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 470872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 471872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 472872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 473872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return interfaces implemented directly by this class. 474872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 475c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_Interfaces(JdwpState*, Request* request, ExpandBuf* pReply) 47690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 477c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId refTypeId = request->ReadRefTypeId(); 478436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes return Dbg::OutputDeclaredInterfaces(refTypeId, pReply); 479872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 480872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 481872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 482872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return the class object corresponding to this type. 483872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 484c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_ClassObject(JdwpState*, Request* request, ExpandBuf* pReply) 48590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 486c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId refTypeId = request->ReadRefTypeId(); 487a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes ObjectId class_object_id; 488c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError status = Dbg::GetClassObject(refTypeId, &class_object_id); 489436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes if (status != ERR_NONE) { 490436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes return status; 4917b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes } 492d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers VLOG(jdwp) << StringPrintf(" --> ObjectId %#" PRIx64, class_object_id); 493a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes expandBufAddObjectId(pReply, class_object_id); 494872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 495872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 496872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 497872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 498872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Returns the value of the SourceDebugExtension attribute. 499872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 500872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * JDB seems interested, but DEX files don't currently support this. 501872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 502c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_SourceDebugExtension(JdwpState*, Request*, ExpandBuf*) 50390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 504872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* referenceTypeId in, string out */ 505872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_ABSENT_INFORMATION; 506872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 507872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 508c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_Signature(JdwpState*, Request* request, ExpandBuf* pReply, bool with_generic) 50990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 510c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId refTypeId = request->ReadRefTypeId(); 511872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 5127b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes std::string signature; 513fc0e94bed3f88ed7e50854fd8dfaf5dcb345250fIan Rogers JdwpError status = Dbg::GetSignature(refTypeId, &signature); 51498e43f6f6ebed9c5901de53f2d6b41a32cd6ad95Elliott Hughes if (status != ERR_NONE) { 51598e43f6f6ebed9c5901de53f2d6b41a32cd6ad95Elliott Hughes return status; 51698e43f6f6ebed9c5901de53f2d6b41a32cd6ad95Elliott Hughes } 51798e43f6f6ebed9c5901de53f2d6b41a32cd6ad95Elliott Hughes expandBufAddUtf8String(pReply, signature); 51898e43f6f6ebed9c5901de53f2d6b41a32cd6ad95Elliott Hughes if (with_generic) { 5190cf7433fd2a93b7f83e8b2ac91d0d1b4f0e7d0c9Elliott Hughes expandBufAddUtf8String(pReply, ""); 520872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 521872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 522872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 523872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 524c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_Signature(JdwpState* state, Request* request, ExpandBuf* pReply) 52590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 5264b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes return RT_Signature(state, request, pReply, false); 52798e43f6f6ebed9c5901de53f2d6b41a32cd6ad95Elliott Hughes} 52898e43f6f6ebed9c5901de53f2d6b41a32cd6ad95Elliott Hughes 529c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_SignatureWithGeneric(JdwpState* state, Request* request, ExpandBuf* pReply) 53090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 5314b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes return RT_Signature(state, request, pReply, true); 53298e43f6f6ebed9c5901de53f2d6b41a32cd6ad95Elliott Hughes} 53398e43f6f6ebed9c5901de53f2d6b41a32cd6ad95Elliott Hughes 534872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 535872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return the instance of java.lang.ClassLoader that loaded the specified 536872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * reference type, or null if it was loaded by the system loader. 537872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 538c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_ClassLoader(JdwpState*, Request* request, ExpandBuf* pReply) 53990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 540c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId refTypeId = request->ReadRefTypeId(); 541436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes return Dbg::GetClassLoader(refTypeId, pReply); 542872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 543872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 544872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 545872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Given a referenceTypeId, return a block of stuff that describes the 546872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * fields declared by a class. 547872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 548c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_FieldsWithGeneric(JdwpState*, Request* request, ExpandBuf* pReply) 54990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 550c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId refTypeId = request->ReadRefTypeId(); 551436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes return Dbg::OutputDeclaredFields(refTypeId, true, pReply); 5527b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes} 5537b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes 5547b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes// Obsolete equivalent of FieldsWithGeneric, without the generic type information. 555c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_Fields(JdwpState*, Request* request, ExpandBuf* pReply) 55690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 557c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId refTypeId = request->ReadRefTypeId(); 558436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes return Dbg::OutputDeclaredFields(refTypeId, false, pReply); 559872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 560872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 561872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 562872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Given a referenceTypeID, return a block of goodies describing the 563872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * methods declared by a class. 564872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 565c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_MethodsWithGeneric(JdwpState*, Request* request, ExpandBuf* pReply) 56690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 567c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId refTypeId = request->ReadRefTypeId(); 568436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes return Dbg::OutputDeclaredMethods(refTypeId, true, pReply); 5697b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes} 570872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 5717b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes// Obsolete equivalent of MethodsWithGeneric, without the generic type information. 572c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_Methods(JdwpState*, Request* request, ExpandBuf* pReply) 57390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 574c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId refTypeId = request->ReadRefTypeId(); 575436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes return Dbg::OutputDeclaredMethods(refTypeId, false, pReply); 576872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 577872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 578c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError RT_Instances(JdwpState*, Request* request, ExpandBuf* reply) 57990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 580c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId class_id = request->ReadRefTypeId(); 581c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers int32_t max_count = request->ReadSigned32("max count"); 5823b78c949ab839d21454bc6f18c7640d2ae8c22f3Elliott Hughes if (max_count < 0) { 5833b78c949ab839d21454bc6f18c7640d2ae8c22f3Elliott Hughes return ERR_ILLEGAL_ARGUMENT; 5843b78c949ab839d21454bc6f18c7640d2ae8c22f3Elliott Hughes } 5853b78c949ab839d21454bc6f18c7640d2ae8c22f3Elliott Hughes 5863b78c949ab839d21454bc6f18c7640d2ae8c22f3Elliott Hughes std::vector<ObjectId> instances; 587c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError rc = Dbg::GetInstances(class_id, max_count, &instances); 5883b78c949ab839d21454bc6f18c7640d2ae8c22f3Elliott Hughes if (rc != ERR_NONE) { 5893b78c949ab839d21454bc6f18c7640d2ae8c22f3Elliott Hughes return rc; 5903b78c949ab839d21454bc6f18c7640d2ae8c22f3Elliott Hughes } 5913b78c949ab839d21454bc6f18c7640d2ae8c22f3Elliott Hughes 5920cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes return WriteTaggedObjectList(reply, instances); 5933b78c949ab839d21454bc6f18c7640d2ae8c22f3Elliott Hughes} 5943b78c949ab839d21454bc6f18c7640d2ae8c22f3Elliott Hughes 595872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 596872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return the immediate superclass of a class. 597872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 598c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError CT_Superclass(JdwpState*, Request* request, ExpandBuf* pReply) 59990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 600c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId class_id = request->ReadRefTypeId(); 6017b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes RefTypeId superClassId; 602c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError status = Dbg::GetSuperclass(class_id, &superClassId); 6033d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes if (status != ERR_NONE) { 6043d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes return status; 6057b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes } 606872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAddRefTypeId(pReply, superClassId); 607872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 608872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 609872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 610872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 611872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Set static class values. 612872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 613c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError CT_SetValues(JdwpState* , Request* request, ExpandBuf*) 61490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 615c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId class_id = request->ReadRefTypeId(); 616c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers int32_t values_count = request->ReadSigned32("values count"); 617872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 618a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes UNUSED(class_id); 619872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 620a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes for (int32_t i = 0; i < values_count; ++i) { 621c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers FieldId fieldId = request->ReadFieldId(); 622aed4be94da51b4fbb54c728151f0daf11535f6abElliott Hughes JDWP::JdwpTag fieldTag = Dbg::GetStaticFieldBasicTag(fieldId); 623dbb4079eb1e7d7738c81a97c8dd2550885c1093aElliott Hughes size_t width = Dbg::GetTagWidth(fieldTag); 624c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint64_t value = request->ReadValue(width); 625872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 626a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes VLOG(jdwp) << " --> field=" << fieldId << " tag=" << fieldTag << " --> " << value; 6273d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes JdwpError status = Dbg::SetStaticFieldValue(fieldId, value, width); 6283d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes if (status != ERR_NONE) { 6293d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes return status; 6303d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes } 631872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 632872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 633872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 634872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 635872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 636872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 637872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Invoke a static method. 638872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 639872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Example: Eclipse sometimes uses java/lang/Class.forName(String s) on 640872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * values in the "variables" display. 641872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 642cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertzstatic JdwpError CT_InvokeMethod(JdwpState* state, Request* request, 643cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz ExpandBuf* pReply ATTRIBUTE_UNUSED) 64490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 645c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId class_id = request->ReadRefTypeId(); 646c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 647c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers MethodId method_id = request->ReadMethodId(); 648872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 649cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz return RequestInvoke(state, request, thread_id, 0, class_id, method_id, false); 650872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 651872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 652872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 653872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Create a new object of the requested type, and invoke the specified 654872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * constructor. 655872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 656872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Example: in IntelliJ, create a watch on "new String(myByteArray)" to 657872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * see the contents of a byte[] as a string. 658872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 659cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertzstatic JdwpError CT_NewInstance(JdwpState* state, Request* request, 660cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz ExpandBuf* pReply ATTRIBUTE_UNUSED) 66190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 662c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId class_id = request->ReadRefTypeId(); 663c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 664c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers MethodId method_id = request->ReadMethodId(); 665872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 666748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes ObjectId object_id; 667c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError status = Dbg::CreateObject(class_id, &object_id); 668436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes if (status != ERR_NONE) { 669436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes return status; 6707b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes } 671cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz return RequestInvoke(state, request, thread_id, object_id, class_id, method_id, true); 672872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 673872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 674872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 675872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Create a new array object of the requested type and length. 676872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 677c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError AT_newInstance(JdwpState*, Request* request, ExpandBuf* pReply) 67890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 679c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId arrayTypeId = request->ReadRefTypeId(); 680c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers int32_t length = request->ReadSigned32("length"); 681872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 682748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes ObjectId object_id; 683c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError status = Dbg::CreateArrayObject(arrayTypeId, length, &object_id); 684436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes if (status != ERR_NONE) { 685436e372e1c2b8e0bde47408e7407b4c3590f5071Elliott Hughes return status; 6867b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes } 687872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAdd1(pReply, JT_ARRAY); 688748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes expandBufAddObjectId(pReply, object_id); 689872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 690872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 691872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 692872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 69370fa1a5497c057eecf336c60975fbca015f8aebdAlex Light * Invoke a static method on an interface. 69470fa1a5497c057eecf336c60975fbca015f8aebdAlex Light */ 69570fa1a5497c057eecf336c60975fbca015f8aebdAlex Lightstatic JdwpError IT_InvokeMethod(JdwpState* state, Request* request, 69670fa1a5497c057eecf336c60975fbca015f8aebdAlex Light ExpandBuf* pReply ATTRIBUTE_UNUSED) 69770fa1a5497c057eecf336c60975fbca015f8aebdAlex Light SHARED_REQUIRES(Locks::mutator_lock_) { 69870fa1a5497c057eecf336c60975fbca015f8aebdAlex Light RefTypeId class_id = request->ReadRefTypeId(); 69970fa1a5497c057eecf336c60975fbca015f8aebdAlex Light ObjectId thread_id = request->ReadThreadId(); 70070fa1a5497c057eecf336c60975fbca015f8aebdAlex Light MethodId method_id = request->ReadMethodId(); 70170fa1a5497c057eecf336c60975fbca015f8aebdAlex Light 70270fa1a5497c057eecf336c60975fbca015f8aebdAlex Light return RequestInvoke(state, request, thread_id, 0, class_id, method_id, false); 70370fa1a5497c057eecf336c60975fbca015f8aebdAlex Light} 70470fa1a5497c057eecf336c60975fbca015f8aebdAlex Light 70570fa1a5497c057eecf336c60975fbca015f8aebdAlex Light/* 706872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return line number information for the method, if present. 707872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 708c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError M_LineTable(JdwpState*, Request* request, ExpandBuf* pReply) 70990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 710c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId refTypeId = request->ReadRefTypeId(); 711c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers MethodId method_id = request->ReadMethodId(); 712872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 713748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes Dbg::OutputLineTable(refTypeId, method_id, pReply); 714872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 715872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 716872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 717872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 718c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError M_VariableTable(JdwpState*, Request* request, ExpandBuf* pReply, 71900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool generic) 72090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 721c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId class_id = request->ReadRefTypeId(); 722c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers MethodId method_id = request->ReadMethodId(); 723872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 7243d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes // We could return ERR_ABSENT_INFORMATION here if the DEX file was built without local variable 7253d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes // information. That will cause Eclipse to make a best-effort attempt at displaying local 7263d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes // variables anonymously. However, the attempt isn't very good, so we're probably better off just 7273d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes // not showing anything. 728748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes Dbg::OutputVariableTable(class_id, method_id, generic, pReply); 729872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 730872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 731872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 732c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError M_VariableTable(JdwpState* state, Request* request, ExpandBuf* pReply) 73390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 7344b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes return M_VariableTable(state, request, pReply, false); 7353d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes} 7363d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes 737c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError M_VariableTableWithGeneric(JdwpState* state, Request* request, ExpandBuf* pReply) 73890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 7394b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes return M_VariableTable(state, request, pReply, true); 7403d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes} 7413d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes 742c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError M_Bytecodes(JdwpState*, Request* request, ExpandBuf* reply) 74390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 744c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId class_id = request->ReadRefTypeId(); 745c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers MethodId method_id = request->ReadMethodId(); 7469777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes 7479777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes std::vector<uint8_t> bytecodes; 748c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError rc = Dbg::GetBytecodes(class_id, method_id, &bytecodes); 7499777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes if (rc != ERR_NONE) { 7509777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes return rc; 7519777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes } 7529777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes 7539777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes expandBufAdd4BE(reply, bytecodes.size()); 7549777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes for (size_t i = 0; i < bytecodes.size(); ++i) { 7559777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes expandBufAdd1(reply, bytecodes[i]); 7569777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes } 7579777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes 7589777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes return ERR_NONE; 7599777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes} 7609777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes 7610a97fc6613d525370d9300819a3579f706d6fc67Sebastien Hertz// Default implementation for IDEs relying on this command. 7620a97fc6613d525370d9300819a3579f706d6fc67Sebastien Hertzstatic JdwpError M_IsObsolete(JdwpState*, Request* request, ExpandBuf* reply) 7630a97fc6613d525370d9300819a3579f706d6fc67Sebastien Hertz SHARED_REQUIRES(Locks::mutator_lock_) { 7640a97fc6613d525370d9300819a3579f706d6fc67Sebastien Hertz request->ReadRefTypeId(); // unused reference type ID 7650a97fc6613d525370d9300819a3579f706d6fc67Sebastien Hertz request->ReadMethodId(); // unused method ID 7660a97fc6613d525370d9300819a3579f706d6fc67Sebastien Hertz expandBufAdd1(reply, false); // a method is never obsolete. 7670a97fc6613d525370d9300819a3579f706d6fc67Sebastien Hertz return ERR_NONE; 7680a97fc6613d525370d9300819a3579f706d6fc67Sebastien Hertz} 7690a97fc6613d525370d9300819a3579f706d6fc67Sebastien Hertz 770872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 771872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Given an object reference, return the runtime type of the object 772872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * (class or array). 773872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 774748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes * This can get called on different things, e.g. thread_id gets 775872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * passed in here. 776872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 777c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError OR_ReferenceType(JdwpState*, Request* request, ExpandBuf* pReply) 77890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 779c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId object_id = request->ReadObjectId(); 780748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes return Dbg::GetReferenceType(object_id, pReply); 781872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 782872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 783872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 784872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Get values from the fields of an object. 785872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 786c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError OR_GetValues(JdwpState*, Request* request, ExpandBuf* pReply) 78790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 788c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId object_id = request->ReadObjectId(); 789c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers int32_t field_count = request->ReadSigned32("field count"); 790872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 7910cf7433fd2a93b7f83e8b2ac91d0d1b4f0e7d0c9Elliott Hughes expandBufAdd4BE(pReply, field_count); 792a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes for (int32_t i = 0; i < field_count; ++i) { 793c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers FieldId fieldId = request->ReadFieldId(); 794748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes JdwpError status = Dbg::GetFieldValue(object_id, fieldId, pReply); 7953f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes if (status != ERR_NONE) { 7963f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes return status; 7973f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes } 798872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 799872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 800872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 801872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 802872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 803872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 804872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Set values in the fields of an object. 805872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 806c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError OR_SetValues(JdwpState*, Request* request, ExpandBuf*) 80790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 808c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId object_id = request->ReadObjectId(); 809c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers int32_t field_count = request->ReadSigned32("field count"); 810872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 811a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes for (int32_t i = 0; i < field_count; ++i) { 812c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers FieldId fieldId = request->ReadFieldId(); 813872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 814aed4be94da51b4fbb54c728151f0daf11535f6abElliott Hughes JDWP::JdwpTag fieldTag = Dbg::GetFieldBasicTag(fieldId); 815dbb4079eb1e7d7738c81a97c8dd2550885c1093aElliott Hughes size_t width = Dbg::GetTagWidth(fieldTag); 816c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint64_t value = request->ReadValue(width); 817872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 8182435a5751431152aaeaa2faaa86b2a30d3eecfe3Elliott Hughes VLOG(jdwp) << " --> fieldId=" << fieldId << " tag=" << fieldTag << "(" << width << ") value=" << value; 819748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes JdwpError status = Dbg::SetFieldValue(object_id, fieldId, value, width); 8203f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes if (status != ERR_NONE) { 8213f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes return status; 8223f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes } 823872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 824872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 825872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 826872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 827872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 828c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError OR_MonitorInfo(JdwpState*, Request* request, ExpandBuf* reply) 82990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 830c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId object_id = request->ReadObjectId(); 831f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes return Dbg::GetMonitorInfo(object_id, reply); 832f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes} 833f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes 834872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 835872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Invoke an instance method. The invocation must occur in the specified 836872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * thread, which must have been suspended by an event. 837872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 838872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * The call is synchronous. All threads in the VM are resumed, unless the 839872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * SINGLE_THREADED flag is set. 840872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 841872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If you ask Eclipse to "inspect" an object (or ask JDB to "print" an 842872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * object), it will try to invoke the object's toString() function. This 843872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * feature becomes crucial when examining ArrayLists with Eclipse. 844872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 845cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertzstatic JdwpError OR_InvokeMethod(JdwpState* state, Request* request, 846cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz ExpandBuf* pReply ATTRIBUTE_UNUSED) 84790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 848c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId object_id = request->ReadObjectId(); 849c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 850c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId class_id = request->ReadRefTypeId(); 851c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers MethodId method_id = request->ReadMethodId(); 852872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 853cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz return RequestInvoke(state, request, thread_id, object_id, class_id, method_id, false); 854872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 855872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 856c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError OR_DisableCollection(JdwpState*, Request* request, ExpandBuf*) 85790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 858c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId object_id = request->ReadObjectId(); 85964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes return Dbg::DisableCollection(object_id); 860872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 861872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 862c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError OR_EnableCollection(JdwpState*, Request* request, ExpandBuf*) 86390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 864c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId object_id = request->ReadObjectId(); 86564f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes return Dbg::EnableCollection(object_id); 866872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 867872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 868c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError OR_IsCollected(JdwpState*, Request* request, ExpandBuf* pReply) 86990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 870c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId object_id = request->ReadObjectId(); 87164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes bool is_collected; 872c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError rc = Dbg::IsCollected(object_id, &is_collected); 87364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes expandBufAdd1(pReply, is_collected ? 1 : 0); 87464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes return rc; 875872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 876872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 877c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError OR_ReferringObjects(JdwpState*, Request* request, ExpandBuf* reply) 87890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 879c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId object_id = request->ReadObjectId(); 880c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers int32_t max_count = request->ReadSigned32("max count"); 8810cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes if (max_count < 0) { 8820cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes return ERR_ILLEGAL_ARGUMENT; 8830cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes } 8840cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes 8850cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes std::vector<ObjectId> referring_objects; 886c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError rc = Dbg::GetReferringObjects(object_id, max_count, &referring_objects); 8870cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes if (rc != ERR_NONE) { 8880cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes return rc; 8890cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes } 8900cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes 8910cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes return WriteTaggedObjectList(reply, referring_objects); 8920cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes} 8930cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes 894872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 895872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return the string value in a string object. 896872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 897c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError SR_Value(JdwpState*, Request* request, ExpandBuf* pReply) 89890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 899c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId stringObject = request->ReadObjectId(); 900b0b0b496125c16620e99ea4e4a05693c281eccf1Sebastien Hertz std::string str; 901b0b0b496125c16620e99ea4e4a05693c281eccf1Sebastien Hertz JDWP::JdwpError error = Dbg::StringToUtf8(stringObject, &str); 902b0b0b496125c16620e99ea4e4a05693c281eccf1Sebastien Hertz if (error != JDWP::ERR_NONE) { 903b0b0b496125c16620e99ea4e4a05693c281eccf1Sebastien Hertz return error; 904b0b0b496125c16620e99ea4e4a05693c281eccf1Sebastien Hertz } 905872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 90668b56858367e29461ae290fd797443a1ef6d8005Ian Rogers VLOG(jdwp) << StringPrintf(" --> %s", PrintableString(str.c_str()).c_str()); 907872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 9084740cdff25875c530649a670b15e8ac52bfd7252Elliott Hughes expandBufAddUtf8String(pReply, str); 909872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 910872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 911872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 912872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 913872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 914872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return a thread's name. 915872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 916c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TR_Name(JdwpState*, Request* request, ExpandBuf* pReply) 91790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 918c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 919872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 920a2e54f61453a2072181d5dd7aa2d5e845f5b53f6Elliott Hughes std::string name; 921c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError error = Dbg::GetThreadName(thread_id, &name); 922221229cb523f849f165fdafbf9785010963715daElliott Hughes if (error != ERR_NONE) { 923221229cb523f849f165fdafbf9785010963715daElliott Hughes return error; 924872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 925d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers VLOG(jdwp) << StringPrintf(" Name of thread %#" PRIx64 " is \"%s\"", thread_id, name.c_str()); 9264740cdff25875c530649a670b15e8ac52bfd7252Elliott Hughes expandBufAddUtf8String(pReply, name); 927872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 928872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 929872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 930872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 931872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 932872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Suspend the specified thread. 933872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 934872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * It's supposed to remain suspended even if interpreted code wants to 935872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * resume it; only the JDI is allowed to resume it. 936872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 937c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TR_Suspend(JdwpState*, Request* request, ExpandBuf*) 93890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 939c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 940872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 941748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes if (thread_id == Dbg::GetThreadSelfId()) { 942872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes LOG(INFO) << " Warning: ignoring request to suspend self"; 943872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_THREAD_NOT_SUSPENDED; 944872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 945a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes 94600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Thread* self = Thread::Current(); 947f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier ScopedThreadSuspension sts(self, kWaitingForDebuggerSend); 94800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JdwpError result = Dbg::SuspendThread(thread_id); 94900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return result; 950872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 951872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 952872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 953872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Resume the specified thread. 954872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 955c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TR_Resume(JdwpState*, Request* request, ExpandBuf*) 95690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 957c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 958872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 959748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes if (thread_id == Dbg::GetThreadSelfId()) { 960872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes LOG(INFO) << " Warning: ignoring request to resume self"; 961872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 962872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 963a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes 964748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes Dbg::ResumeThread(thread_id); 965872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 966872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 967872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 968872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 969872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return status of specified thread. 970872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 971c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TR_Status(JdwpState*, Request* request, ExpandBuf* pReply) 97290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 973c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 974872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 9753d30d9b09c16542d41554aad9f46ec9109ba5cb5Elliott Hughes JDWP::JdwpThreadStatus threadStatus; 9763d30d9b09c16542d41554aad9f46ec9109ba5cb5Elliott Hughes JDWP::JdwpSuspendStatus suspendStatus; 977221229cb523f849f165fdafbf9785010963715daElliott Hughes JdwpError error = Dbg::GetThreadStatus(thread_id, &threadStatus, &suspendStatus); 978221229cb523f849f165fdafbf9785010963715daElliott Hughes if (error != ERR_NONE) { 979221229cb523f849f165fdafbf9785010963715daElliott Hughes return error; 980872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 981872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 9824dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jdwp) << " --> " << threadStatus << ", " << suspendStatus; 983872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 984872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAdd4BE(pReply, threadStatus); 985872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAdd4BE(pReply, suspendStatus); 986872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 987872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 988872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 989872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 990872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 991872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return the thread group that the specified thread is a member of. 992872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 993c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TR_ThreadGroup(JdwpState*, Request* request, ExpandBuf* pReply) 99490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 995c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 996748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes return Dbg::GetThreadGroup(thread_id, pReply); 997872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 998872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 999872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1000872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return the current call stack of a suspended thread. 1001872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 1002872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If the thread isn't suspended, the error code isn't defined, but should 1003872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * be THREAD_NOT_SUSPENDED. 1004872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1005c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TR_Frames(JdwpState*, Request* request, ExpandBuf* pReply) 100690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1007c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 1008c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint32_t start_frame = request->ReadUnsigned32("start frame"); 1009c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint32_t length = request->ReadUnsigned32("length"); 1010872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1011221229cb523f849f165fdafbf9785010963715daElliott Hughes size_t actual_frame_count; 1012c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError error = Dbg::GetThreadFrameCount(thread_id, &actual_frame_count); 1013221229cb523f849f165fdafbf9785010963715daElliott Hughes if (error != ERR_NONE) { 1014221229cb523f849f165fdafbf9785010963715daElliott Hughes return error; 1015221229cb523f849f165fdafbf9785010963715daElliott Hughes } 1016872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 10173f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes if (actual_frame_count <= 0) { 10187934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom return ERR_THREAD_NOT_SUSPENDED; // 0 means no managed frames (which means "in native"). 1019872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 10203f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes 10213f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes if (start_frame > actual_frame_count) { 10223f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes return ERR_INVALID_INDEX; 10233f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes } 10243f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes if (length == static_cast<uint32_t>(-1)) { 10253f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes length = actual_frame_count - start_frame; 10263f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes } 10273f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes if (start_frame + length > actual_frame_count) { 10283f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes return ERR_INVALID_LENGTH; 1029872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1030872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 10316e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes return Dbg::GetThreadFrames(thread_id, start_frame, length, pReply); 1032872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1033872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1034872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1035872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Returns the #of frames on the specified thread, which must be suspended. 1036872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1037c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TR_FrameCount(JdwpState*, Request* request, ExpandBuf* pReply) 103890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1039c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 1040872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1041221229cb523f849f165fdafbf9785010963715daElliott Hughes size_t frame_count; 1042c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError rc = Dbg::GetThreadFrameCount(thread_id, &frame_count); 10434993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes if (rc != ERR_NONE) { 10444993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes return rc; 1045872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 10463f4d58f4a39f60057ebf8ea92340ddb78317ae51Elliott Hughes expandBufAdd4BE(pReply, static_cast<uint32_t>(frame_count)); 1047872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1048872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 1049872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1050872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1051c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TR_OwnedMonitors(Request* request, ExpandBuf* reply, bool with_stack_depths) 105290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1053c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 10544993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes 10554993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes std::vector<ObjectId> monitors; 1056734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes std::vector<uint32_t> stack_depths; 1057c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError rc = Dbg::GetOwnedMonitors(thread_id, &monitors, &stack_depths); 10584993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes if (rc != ERR_NONE) { 10594993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes return rc; 10604993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes } 10614993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes 10624993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes expandBufAdd4BE(reply, monitors.size()); 10634993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes for (size_t i = 0; i < monitors.size(); ++i) { 10644993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes rc = WriteTaggedObject(reply, monitors[i]); 10654993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes if (rc != ERR_NONE) { 10664993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes return rc; 10674993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes } 1068734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes if (with_stack_depths) { 1069734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes expandBufAdd4BE(reply, stack_depths[i]); 1070734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes } 10714993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes } 10724993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes return ERR_NONE; 10734993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes} 10744993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes 1075c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TR_OwnedMonitors(JdwpState*, Request* request, ExpandBuf* reply) 107690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 10774b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes return TR_OwnedMonitors(request, reply, false); 1078734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes} 1079734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes 1080c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TR_OwnedMonitorsStackDepthInfo(JdwpState*, Request* request, ExpandBuf* reply) 108190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 10824b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes return TR_OwnedMonitors(request, reply, true); 1083734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes} 1084734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes 1085c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TR_CurrentContendedMonitor(JdwpState*, Request* request, ExpandBuf* reply) 108690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1087c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 1088872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1089f9501700f51586cb6ba7cc0ffcb5a920bd64adf1Elliott Hughes ObjectId contended_monitor; 1090c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError rc = Dbg::GetContendedMonitor(thread_id, &contended_monitor); 1091f9501700f51586cb6ba7cc0ffcb5a920bd64adf1Elliott Hughes if (rc != ERR_NONE) { 1092f9501700f51586cb6ba7cc0ffcb5a920bd64adf1Elliott Hughes return rc; 1093f9501700f51586cb6ba7cc0ffcb5a920bd64adf1Elliott Hughes } 1094f9501700f51586cb6ba7cc0ffcb5a920bd64adf1Elliott Hughes return WriteTaggedObject(reply, contended_monitor); 1095f9501700f51586cb6ba7cc0ffcb5a920bd64adf1Elliott Hughes} 1096872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 10974b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillainstatic JdwpError TR_Interrupt(JdwpState*, Request* request, ExpandBuf* reply ATTRIBUTE_UNUSED) 109890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1099c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 1100f9501700f51586cb6ba7cc0ffcb5a920bd64adf1Elliott Hughes return Dbg::Interrupt(thread_id); 1101872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1102872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1103872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 110400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers * Return the debug suspend count for the specified thread. 1105872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 1106872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * (The thread *might* still be running -- it might not have examined 1107872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * its suspend count recently.) 1108872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1109c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TR_DebugSuspendCount(JdwpState*, Request* request, ExpandBuf* pReply) 111090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1111c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 111200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return Dbg::GetThreadDebugSuspendCount(thread_id, pReply); 1113872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1114872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1115872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1116872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return the name of a thread group. 1117872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 1118872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * The Eclipse debugger recognizes "main" and "system" as special. 1119872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1120c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TGR_Name(JdwpState*, Request* request, ExpandBuf* pReply) 112190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1122c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_group_id = request->ReadThreadGroupId(); 1123a06430c76981d545b5f2b64a7ef53c44c030cf73Sebastien Hertz return Dbg::GetThreadGroupName(thread_group_id, pReply); 1124872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1125872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1126872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1127872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Returns the thread group -- if any -- that contains the specified 1128872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * thread group. 1129872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1130c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TGR_Parent(JdwpState*, Request* request, ExpandBuf* pReply) 113190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1132c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_group_id = request->ReadThreadGroupId(); 1133a06430c76981d545b5f2b64a7ef53c44c030cf73Sebastien Hertz return Dbg::GetThreadGroupParent(thread_group_id, pReply); 1134872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1135872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1136872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1137872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return the active threads and thread groups that are part of the 1138872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * specified thread group. 1139872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1140c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError TGR_Children(JdwpState*, Request* request, ExpandBuf* pReply) 114190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1142c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_group_id = request->ReadThreadGroupId(); 1143a06430c76981d545b5f2b64a7ef53c44c030cf73Sebastien Hertz return Dbg::GetThreadGroupChildren(thread_group_id, pReply); 1144872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1145872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1146872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1147872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return the #of components in the array. 1148872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1149c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError AR_Length(JdwpState*, Request* request, ExpandBuf* pReply) 115090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1151c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId array_id = request->ReadArrayId(); 1152872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1153c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers int32_t length; 1154c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpError status = Dbg::GetArrayLength(array_id, &length); 11553d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes if (status != ERR_NONE) { 11563d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes return status; 11573d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes } 11582435a5751431152aaeaa2faaa86b2a30d3eecfe3Elliott Hughes VLOG(jdwp) << " --> " << length; 1159872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 11603d1ca6de2ddf3d9e39755d629c896bfecd9640fdElliott Hughes expandBufAdd4BE(pReply, length); 1161872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1162872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 1163872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1164872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1165872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1166872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return the values from an array. 1167872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1168c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError AR_GetValues(JdwpState*, Request* request, ExpandBuf* pReply) 116990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1170c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId array_id = request->ReadArrayId(); 1171c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint32_t offset = request->ReadUnsigned32("offset"); 1172c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint32_t length = request->ReadUnsigned32("length"); 1173a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes return Dbg::OutputArray(array_id, offset, length, pReply); 1174872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1175872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1176872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1177872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Set values in an array. 1178872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1179c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError AR_SetValues(JdwpState*, Request* request, ExpandBuf*) 118090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1181c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId array_id = request->ReadArrayId(); 1182c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint32_t offset = request->ReadUnsigned32("offset"); 1183c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint32_t count = request->ReadUnsigned32("count"); 11844b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes return Dbg::SetArrayElements(array_id, offset, count, request); 1185872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1186872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1187c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError CLR_VisibleClasses(JdwpState*, Request* request, ExpandBuf* pReply) 118890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1189c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers request->ReadObjectId(); // classLoaderObject 11908696433d1b3d8ba15288483b777edd888de69135Elliott Hughes // TODO: we should only return classes which have the given class loader as a defining or 11918696433d1b3d8ba15288483b777edd888de69135Elliott Hughes // initiating loader. The former would be easy; the latter is hard, because we don't have 11928696433d1b3d8ba15288483b777edd888de69135Elliott Hughes // any such notion. 11936e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes return VM_AllClassesImpl(pReply, false, false); 1194872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1195872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1196358bcaf13ec288ee45be8fc53cb09170c1b8a8f1Sebastien Hertz// Delete function class to use std::unique_ptr with JdwpEvent. 1197358bcaf13ec288ee45be8fc53cb09170c1b8a8f1Sebastien Hertzstruct JdwpEventDeleter { 1198358bcaf13ec288ee45be8fc53cb09170c1b8a8f1Sebastien Hertz void operator()(JdwpEvent* event) { 1199358bcaf13ec288ee45be8fc53cb09170c1b8a8f1Sebastien Hertz EventFree(event); 1200358bcaf13ec288ee45be8fc53cb09170c1b8a8f1Sebastien Hertz } 1201358bcaf13ec288ee45be8fc53cb09170c1b8a8f1Sebastien Hertz}; 1202358bcaf13ec288ee45be8fc53cb09170c1b8a8f1Sebastien Hertz 1203872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1204872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Set an event trigger. 1205872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 1206872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Reply with a requestID. 1207872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1208c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError ER_Set(JdwpState* state, Request* request, ExpandBuf* pReply) 120990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1210c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpEventKind event_kind = request->ReadEnum1<JdwpEventKind>("event kind"); 1211c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpSuspendPolicy suspend_policy = request->ReadEnum1<JdwpSuspendPolicy>("suspend policy"); 1212c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers int32_t modifier_count = request->ReadSigned32("modifier count"); 1213872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1214a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes CHECK_LT(modifier_count, 256); /* reasonableness check */ 1215872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1216358bcaf13ec288ee45be8fc53cb09170c1b8a8f1Sebastien Hertz std::unique_ptr<JDWP::JdwpEvent, JdwpEventDeleter> pEvent(EventAlloc(modifier_count)); 12174b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes pEvent->eventKind = event_kind; 12184b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes pEvent->suspend_policy = suspend_policy; 1219a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes pEvent->modCount = modifier_count; 1220872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1221872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* 1222872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Read modifiers. Ordering may be significant (see explanation of Count 1223872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * mods in JDWP doc). 1224872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1225a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes for (int32_t i = 0; i < modifier_count; ++i) { 1226972a47bf0c180dee7e4c697b74dd31daaf58e008Elliott Hughes JdwpEventMod& mod = pEvent->mods[i]; 1227c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers mod.modKind = request->ReadModKind(); 1228972a47bf0c180dee7e4c697b74dd31daaf58e008Elliott Hughes switch (mod.modKind) { 1229a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes case MK_COUNT: 1230872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes { 1231a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes // Report once, when "--count" reaches 0. 1232c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint32_t count = request->ReadUnsigned32("count"); 1233872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes if (count == 0) { 1234872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_INVALID_COUNT; 1235872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1236972a47bf0c180dee7e4c697b74dd31daaf58e008Elliott Hughes mod.count.count = count; 1237872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1238872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 1239a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes case MK_CONDITIONAL: 1240872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes { 1241a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes // Conditional on expression. 1242c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint32_t exprId = request->ReadUnsigned32("expr id"); 1243972a47bf0c180dee7e4c697b74dd31daaf58e008Elliott Hughes mod.conditional.exprId = exprId; 1244872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1245872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 1246a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes case MK_THREAD_ONLY: 1247872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes { 1248a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes // Only report events in specified thread. 1249c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 1250748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes mod.threadOnly.threadId = thread_id; 1251872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1252872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 1253a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes case MK_CLASS_ONLY: 1254872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes { 1255a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes // For ClassPrepare, MethodEntry. 1256c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId class_id = request->ReadRefTypeId(); 1257748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes mod.classOnly.refTypeId = class_id; 1258872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1259872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 1260a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes case MK_CLASS_MATCH: 1261872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes { 1262a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes // Restrict events to matching classes. 12638696433d1b3d8ba15288483b777edd888de69135Elliott Hughes // pattern is "java.foo.*", we want "java/foo/*". 1264c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers std::string pattern(request->ReadUtf8String()); 12658696433d1b3d8ba15288483b777edd888de69135Elliott Hughes std::replace(pattern.begin(), pattern.end(), '.', '/'); 1266972a47bf0c180dee7e4c697b74dd31daaf58e008Elliott Hughes mod.classMatch.classPattern = strdup(pattern.c_str()); 1267872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1268872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 1269a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes case MK_CLASS_EXCLUDE: 1270872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes { 1271a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes // Restrict events to non-matching classes. 12728696433d1b3d8ba15288483b777edd888de69135Elliott Hughes // pattern is "java.foo.*", we want "java/foo/*". 1273c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers std::string pattern(request->ReadUtf8String()); 12748696433d1b3d8ba15288483b777edd888de69135Elliott Hughes std::replace(pattern.begin(), pattern.end(), '.', '/'); 1275972a47bf0c180dee7e4c697b74dd31daaf58e008Elliott Hughes mod.classExclude.classPattern = strdup(pattern.c_str()); 1276872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1277872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 1278a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes case MK_LOCATION_ONLY: 1279872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes { 1280a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes // Restrict certain events based on location. 1281c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers JdwpLocation location = request->ReadLocation(); 1282a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes mod.locationOnly.loc = location; 1283872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1284872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 1285a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes case MK_EXCEPTION_ONLY: 1286872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes { 1287a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes // Modifies EK_EXCEPTION events, 1288c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers mod.exceptionOnly.refTypeId = request->ReadRefTypeId(); // null => all exceptions. 1289c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers mod.exceptionOnly.caught = request->ReadEnum1<uint8_t>("caught"); 1290c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers mod.exceptionOnly.uncaught = request->ReadEnum1<uint8_t>("uncaught"); 1291872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1292872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 1293a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes case MK_FIELD_ONLY: 1294872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes { 1295a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes // For field access/modification events. 1296c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId declaring = request->ReadRefTypeId(); 1297c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers FieldId fieldId = request->ReadFieldId(); 1298972a47bf0c180dee7e4c697b74dd31daaf58e008Elliott Hughes mod.fieldOnly.refTypeId = declaring; 1299972a47bf0c180dee7e4c697b74dd31daaf58e008Elliott Hughes mod.fieldOnly.fieldId = fieldId; 1300872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1301872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 1302a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes case MK_STEP: 1303872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes { 1304a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes // For use with EK_SINGLE_STEP. 1305c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 1306c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint32_t size = request->ReadUnsigned32("step size"); 1307c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint32_t depth = request->ReadUnsigned32("step depth"); 1308d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers VLOG(jdwp) << StringPrintf(" Step: thread=%#" PRIx64, thread_id) 1309872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes << " size=" << JdwpStepSize(size) << " depth=" << JdwpStepDepth(depth); 1310872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1311748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes mod.step.threadId = thread_id; 1312972a47bf0c180dee7e4c697b74dd31daaf58e008Elliott Hughes mod.step.size = size; 1313972a47bf0c180dee7e4c697b74dd31daaf58e008Elliott Hughes mod.step.depth = depth; 1314872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1315872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 1316a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes case MK_INSTANCE_ONLY: 1317872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes { 1318a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes // Report events related to a specific object. 1319c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId instance = request->ReadObjectId(); 1320972a47bf0c180dee7e4c697b74dd31daaf58e008Elliott Hughes mod.instanceOnly.objectId = instance; 1321872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1322872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 1323872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes default: 13246d7839e03348111a4237f0d47d0e70bc81b32e7aSebastien Hertz LOG(WARNING) << "Unsupported modifier " << mod.modKind << " for event " << pEvent->eventKind; 13256d7839e03348111a4237f0d47d0e70bc81b32e7aSebastien Hertz return JDWP::ERR_NOT_IMPLEMENTED; 1326872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1327872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1328872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1329872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* 1330872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * We reply with an integer "requestID". 1331872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1332376a7a033d29d5f2b6e16574a340c999ff2999a0Elliott Hughes uint32_t requestId = state->NextEventSerial(); 1333872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAdd4BE(pReply, requestId); 1334872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1335872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes pEvent->requestId = requestId; 1336872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 13374dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jdwp) << StringPrintf(" --> event requestId=%#x", requestId); 1338872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1339872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* add it to the list */ 1340358bcaf13ec288ee45be8fc53cb09170c1b8a8f1Sebastien Hertz JdwpError err = state->RegisterEvent(pEvent.get()); 1341872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes if (err != ERR_NONE) { 1342872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* registration failed, probably because event is bogus */ 1343872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes LOG(WARNING) << "WARNING: event request rejected"; 1344358bcaf13ec288ee45be8fc53cb09170c1b8a8f1Sebastien Hertz return err; 1345872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1346358bcaf13ec288ee45be8fc53cb09170c1b8a8f1Sebastien Hertz pEvent.release(); 1347358bcaf13ec288ee45be8fc53cb09170c1b8a8f1Sebastien Hertz return ERR_NONE; 1348872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1349872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1350c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError ER_Clear(JdwpState* state, Request* request, ExpandBuf*) 135190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1352c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers request->ReadEnum1<JdwpEventKind>("event kind"); 1353c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers uint32_t requestId = request->ReadUnsigned32("request id"); 1354872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 13554b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes // Failure to find an event with a matching ID is a no-op 13564b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes // and does not return an error. 1357761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes state->UnregisterEventById(requestId); 1358872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 1359872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1360872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1361872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1362872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return the values of arguments and local variables. 1363872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1364c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError SF_GetValues(JdwpState*, Request* request, ExpandBuf* pReply) 136590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 13668009f39c6d63181a6cd0e348ce732997dbdf3d20Sebastien Hertz return Dbg::GetLocalValues(request, pReply); 1367872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1368872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1369872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1370872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Set the values of arguments and local variables. 1371872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1372c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError SF_SetValues(JdwpState*, Request* request, ExpandBuf*) 137390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 13748009f39c6d63181a6cd0e348ce732997dbdf3d20Sebastien Hertz return Dbg::SetLocalValues(request); 1375872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1376872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1377c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError SF_ThisObject(JdwpState*, Request* request, ExpandBuf* reply) 137890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1379c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ObjectId thread_id = request->ReadThreadId(); 1380c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers FrameId frame_id = request->ReadFrameId(); 1381872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 13824993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes ObjectId object_id; 13834993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes JdwpError rc = Dbg::GetThisObject(thread_id, frame_id, &object_id); 13846e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes if (rc != ERR_NONE) { 13856e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes return rc; 1386546b986ecd09c2a498740bd8bf7127e612d94755Elliott Hughes } 1387872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 13884993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes return WriteTaggedObject(reply, object_id); 1389872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1390872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1391872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1392872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Return the reference type reflected by this class object. 1393872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 1394872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * This appears to be required because ReferenceTypeId values are NEVER 1395872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * reused, whereas ClassIds can be recycled like any other object. (Either 1396872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * that, or I have no idea what this is for.) 1397872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1398c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError COR_ReflectedType(JdwpState*, Request* request, ExpandBuf* pReply) 139990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1400c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers RefTypeId class_object_id = request->ReadRefTypeId(); 1401a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes return Dbg::GetReflectedType(class_object_id, pReply); 1402872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1403872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1404872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1405872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Handle a DDM packet with a single chunk in it. 1406872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1407c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic JdwpError DDM_Chunk(JdwpState* state, Request* request, ExpandBuf* pReply) 140890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 14094b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes state->NotifyDdmsActive(); 14107d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz uint8_t* replyBuf = nullptr; 1411872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes int replyLen = -1; 14124b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes if (Dbg::DdmHandlePacket(request, &replyBuf, &replyLen)) { 14134b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes // If they want to send something back, we copy it into the buffer. 14144b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes // TODO: consider altering the JDWP stuff to hold the packet header 14154b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes // in a separate buffer. That would allow us to writev() DDM traffic 14164b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes // instead of copying it into the expanding buffer. The reduction in 14174b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes // heap requirements is probably more valuable than the efficiency. 14184b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes CHECK_GT(replyLen, 0); 1419872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes memcpy(expandBufAddSpace(pReply, replyLen), replyBuf, replyLen); 14203901bbc170b73b13aa5092f5709a495a1847198fSebastien Hertz delete[] replyBuf; 1421872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1422872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 1423872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1424872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1425872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1426872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Handler map decl. 1427872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1428c0542af3e2170143ba40d89136e284997e16bf64Ian Rogerstypedef JdwpError (*JdwpRequestHandler)(JdwpState* state, Request* request, ExpandBuf* reply); 1429872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1430872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstruct JdwpHandlerMap { 14314b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes uint8_t cmdSet; 14324b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes uint8_t cmd; 14334b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes JdwpRequestHandler func; 14344b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes const char* name; 1435872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}; 1436872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1437872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1438872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Map commands to functions. 1439872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 1440872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Command sets 0-63 are incoming requests, 64-127 are outbound requests, 1441872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * and 128-256 are vendor-defined. 1442872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1443cb69306eefc1e6e42b3eaec8b479a268222b01b6Elliott Hughesstatic const JdwpHandlerMap gHandlers[] = { 1444872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* VirtualMachine command set (1) */ 1445f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 1, VM_Version, "VirtualMachine.Version" }, 1446f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 2, VM_ClassesBySignature, "VirtualMachine.ClassesBySignature" }, 1447f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 3, VM_AllClasses, "VirtualMachine.AllClasses" }, 1448f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 4, VM_AllThreads, "VirtualMachine.AllThreads" }, 1449f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 5, VM_TopLevelThreadGroups, "VirtualMachine.TopLevelThreadGroups" }, 1450f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 6, VM_Dispose, "VirtualMachine.Dispose" }, 1451f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 7, VM_IDSizes, "VirtualMachine.IDSizes" }, 1452f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 8, VM_Suspend, "VirtualMachine.Suspend" }, 1453f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 9, VM_Resume, "VirtualMachine.Resume" }, 1454f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 10, VM_Exit, "VirtualMachine.Exit" }, 1455f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 11, VM_CreateString, "VirtualMachine.CreateString" }, 1456f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 12, VM_Capabilities, "VirtualMachine.Capabilities" }, 1457f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 13, VM_ClassPaths, "VirtualMachine.ClassPaths" }, 1458f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 14, VM_DisposeObjects, "VirtualMachine.DisposeObjects" }, 14597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 1, 15, nullptr, "VirtualMachine.HoldEvents" }, 14607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 1, 16, nullptr, "VirtualMachine.ReleaseEvents" }, 1461f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 1, 17, VM_CapabilitiesNew, "VirtualMachine.CapabilitiesNew" }, 14627d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 1, 18, nullptr, "VirtualMachine.RedefineClasses" }, 14637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 1, 19, nullptr, "VirtualMachine.SetDefaultStratum" }, 14646e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 1, 20, VM_AllClassesWithGeneric, "VirtualMachine.AllClassesWithGeneric" }, 1465ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes { 1, 21, VM_InstanceCounts, "VirtualMachine.InstanceCounts" }, 1466872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1467872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* ReferenceType command set (2) */ 1468f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 2, 1, RT_Signature, "ReferenceType.Signature" }, 1469f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 2, 2, RT_ClassLoader, "ReferenceType.ClassLoader" }, 1470f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 2, 3, RT_Modifiers, "ReferenceType.Modifiers" }, 1471f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 2, 4, RT_Fields, "ReferenceType.Fields" }, 1472f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 2, 5, RT_Methods, "ReferenceType.Methods" }, 1473f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 2, 6, RT_GetValues, "ReferenceType.GetValues" }, 1474f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 2, 7, RT_SourceFile, "ReferenceType.SourceFile" }, 14757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 2, 8, nullptr, "ReferenceType.NestedTypes" }, 1476f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 2, 9, RT_Status, "ReferenceType.Status" }, 1477f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 2, 10, RT_Interfaces, "ReferenceType.Interfaces" }, 1478f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 2, 11, RT_ClassObject, "ReferenceType.ClassObject" }, 14796e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 2, 12, RT_SourceDebugExtension, "ReferenceType.SourceDebugExtension" }, 14806e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 2, 13, RT_SignatureWithGeneric, "ReferenceType.SignatureWithGeneric" }, 1481f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 2, 14, RT_FieldsWithGeneric, "ReferenceType.FieldsWithGeneric" }, 1482f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 2, 15, RT_MethodsWithGeneric, "ReferenceType.MethodsWithGeneric" }, 14833b78c949ab839d21454bc6f18c7640d2ae8c22f3Elliott Hughes { 2, 16, RT_Instances, "ReferenceType.Instances" }, 14847d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 2, 17, nullptr, "ReferenceType.ClassFileVersion" }, 14857d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 2, 18, nullptr, "ReferenceType.ConstantPool" }, 1486872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1487872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* ClassType command set (3) */ 14886e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 3, 1, CT_Superclass, "ClassType.Superclass" }, 14896e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 3, 2, CT_SetValues, "ClassType.SetValues" }, 14906e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 3, 3, CT_InvokeMethod, "ClassType.InvokeMethod" }, 14916e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 3, 4, CT_NewInstance, "ClassType.NewInstance" }, 1492872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1493872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* ArrayType command set (4) */ 14946e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 4, 1, AT_newInstance, "ArrayType.NewInstance" }, 1495872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1496872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* InterfaceType command set (5) */ 149770fa1a5497c057eecf336c60975fbca015f8aebdAlex Light { 5, 1, IT_InvokeMethod, "InterfaceType.InvokeMethod" }, 1498872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1499872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* Method command set (6) */ 1500f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 6, 1, M_LineTable, "Method.LineTable" }, 1501f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 6, 2, M_VariableTable, "Method.VariableTable" }, 15029777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes { 6, 3, M_Bytecodes, "Method.Bytecodes" }, 15030a97fc6613d525370d9300819a3579f706d6fc67Sebastien Hertz { 6, 4, M_IsObsolete, "Method.IsObsolete" }, 15046e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 6, 5, M_VariableTableWithGeneric, "Method.VariableTableWithGeneric" }, 1505872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1506872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* Field command set (8) */ 1507872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1508872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* ObjectReference command set (9) */ 1509f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 9, 1, OR_ReferenceType, "ObjectReference.ReferenceType" }, 1510f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 9, 2, OR_GetValues, "ObjectReference.GetValues" }, 1511f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 9, 3, OR_SetValues, "ObjectReference.SetValues" }, 15127d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 9, 4, nullptr, "ObjectReference.UNUSED" }, 1513f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 9, 5, OR_MonitorInfo, "ObjectReference.MonitorInfo" }, 1514f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 9, 6, OR_InvokeMethod, "ObjectReference.InvokeMethod" }, 15156e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 9, 7, OR_DisableCollection, "ObjectReference.DisableCollection" }, 1516f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 9, 8, OR_EnableCollection, "ObjectReference.EnableCollection" }, 1517f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes { 9, 9, OR_IsCollected, "ObjectReference.IsCollected" }, 15180cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes { 9, 10, OR_ReferringObjects, "ObjectReference.ReferringObjects" }, 1519872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1520872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* StringReference command set (10) */ 15216e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 10, 1, SR_Value, "StringReference.Value" }, 1522872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1523872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* ThreadReference command set (11) */ 1524734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes { 11, 1, TR_Name, "ThreadReference.Name" }, 1525734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes { 11, 2, TR_Suspend, "ThreadReference.Suspend" }, 1526734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes { 11, 3, TR_Resume, "ThreadReference.Resume" }, 1527734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes { 11, 4, TR_Status, "ThreadReference.Status" }, 1528734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes { 11, 5, TR_ThreadGroup, "ThreadReference.ThreadGroup" }, 1529734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes { 11, 6, TR_Frames, "ThreadReference.Frames" }, 1530734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes { 11, 7, TR_FrameCount, "ThreadReference.FrameCount" }, 1531734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes { 11, 8, TR_OwnedMonitors, "ThreadReference.OwnedMonitors" }, 1532734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes { 11, 9, TR_CurrentContendedMonitor, "ThreadReference.CurrentContendedMonitor" }, 15337d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 11, 10, nullptr, "ThreadReference.Stop" }, 1534734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes { 11, 11, TR_Interrupt, "ThreadReference.Interrupt" }, 1535734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes { 11, 12, TR_DebugSuspendCount, "ThreadReference.SuspendCount" }, 1536734b8c62cc637c25f4c2481ca6a48adbd7209c6cElliott Hughes { 11, 13, TR_OwnedMonitorsStackDepthInfo, "ThreadReference.OwnedMonitorsStackDepthInfo" }, 15377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 11, 14, nullptr, "ThreadReference.ForceEarlyReturn" }, 1538872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1539872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* ThreadGroupReference command set (12) */ 15406e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 12, 1, TGR_Name, "ThreadGroupReference.Name" }, 15416e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 12, 2, TGR_Parent, "ThreadGroupReference.Parent" }, 15426e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 12, 3, TGR_Children, "ThreadGroupReference.Children" }, 1543872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1544872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* ArrayReference command set (13) */ 15456e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 13, 1, AR_Length, "ArrayReference.Length" }, 15466e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 13, 2, AR_GetValues, "ArrayReference.GetValues" }, 15476e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 13, 3, AR_SetValues, "ArrayReference.SetValues" }, 1548872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1549872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* ClassLoaderReference command set (14) */ 15506e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 14, 1, CLR_VisibleClasses, "ClassLoaderReference.VisibleClasses" }, 1551872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1552872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* EventRequest command set (15) */ 15536e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 15, 1, ER_Set, "EventRequest.Set" }, 15546e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 15, 2, ER_Clear, "EventRequest.Clear" }, 15557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 15, 3, nullptr, "EventRequest.ClearAllBreakpoints" }, 1556872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1557872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* StackFrame command set (16) */ 15586e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 16, 1, SF_GetValues, "StackFrame.GetValues" }, 15596e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 16, 2, SF_SetValues, "StackFrame.SetValues" }, 15606e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 16, 3, SF_ThisObject, "StackFrame.ThisObject" }, 15617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 16, 4, nullptr, "StackFrame.PopFrames" }, 1562872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1563872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* ClassObjectReference command set (17) */ 15646e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 17, 1, COR_ReflectedType, "ClassObjectReference.ReflectedType" }, 1565872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1566872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* Event command set (64) */ 15677d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 64, 100, nullptr, "Event.Composite" }, // sent from VM to debugger, never received by VM 1568872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 15696e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes { 199, 1, DDM_Chunk, "DDM.Chunk" }, 1570872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}; 1571872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1572c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic const char* GetCommandName(Request* request) { 1573cb69306eefc1e6e42b3eaec8b479a268222b01b6Elliott Hughes for (size_t i = 0; i < arraysize(gHandlers); ++i) { 15747d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (gHandlers[i].cmdSet == request->GetCommandSet() && 15757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz gHandlers[i].cmd == request->GetCommand()) { 1576cb69306eefc1e6e42b3eaec8b479a268222b01b6Elliott Hughes return gHandlers[i].name; 1577a3c24aaf30fcce6c4393c923beeaad385f1257dbElliott Hughes } 1578a3c24aaf30fcce6c4393c923beeaad385f1257dbElliott Hughes } 1579a3c24aaf30fcce6c4393c923beeaad385f1257dbElliott Hughes return "?UNKNOWN?"; 1580a3c24aaf30fcce6c4393c923beeaad385f1257dbElliott Hughes} 1581a3c24aaf30fcce6c4393c923beeaad385f1257dbElliott Hughes 1582c0542af3e2170143ba40d89136e284997e16bf64Ian Rogersstatic std::string DescribeCommand(Request* request) { 1583a3c24aaf30fcce6c4393c923beeaad385f1257dbElliott Hughes std::string result; 158464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes result += "REQUEST: "; 1585cb69306eefc1e6e42b3eaec8b479a268222b01b6Elliott Hughes result += GetCommandName(request); 1586c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers result += StringPrintf(" (length=%zu id=0x%06x)", request->GetLength(), request->GetId()); 1587a3c24aaf30fcce6c4393c923beeaad385f1257dbElliott Hughes return result; 1588a3c24aaf30fcce6c4393c923beeaad385f1257dbElliott Hughes} 1589a3c24aaf30fcce6c4393c923beeaad385f1257dbElliott Hughes 1590cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz// Returns true if the given command_set and command identify an "invoke" command. 1591cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertzstatic bool IsInvokeCommand(uint8_t command_set, uint8_t command) { 1592cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz if (command_set == kJDWPClassTypeCmdSet) { 1593cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz return command == kJDWPClassTypeInvokeMethodCmd || command == kJDWPClassTypeNewInstanceCmd; 1594cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz } else if (command_set == kJDWPObjectReferenceCmdSet) { 1595cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz return command == kJDWPObjectReferenceInvokeCmd; 159670fa1a5497c057eecf336c60975fbca015f8aebdAlex Light } else if (command_set == kJDWPInterfaceTypeCmdSet) { 159770fa1a5497c057eecf336c60975fbca015f8aebdAlex Light return command == kJDWPInterfaceTypeInvokeMethodCmd; 1598cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz } else { 1599cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz return false; 1600cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz } 1601cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz} 1602cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz 1603872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1604cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz * Process a request from the debugger. The skip_reply flag is set to true to indicate to the 1605cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz * caller the reply must not be sent to the debugger. This is used for invoke commands where the 1606cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz * reply is sent by the event thread after completing the invoke. 1607872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 1608872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * On entry, the JDWP thread is in VMWAIT. 1609872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1610cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertzsize_t JdwpState::ProcessRequest(Request* request, ExpandBuf* pReply, bool* skip_reply) { 1611872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes JdwpError result = ERR_NONE; 1612cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz *skip_reply = false; 1613872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1614c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers if (request->GetCommandSet() != kJDWPDdmCmdSet) { 1615872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* 1616872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Activity from a debugger, not merely ddms. Mark us as having an 1617872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * active debugger session, and zero out the last-activity timestamp 1618872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * so waitForDebugger() doesn't return if we stall for a bit here. 1619872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1620a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes Dbg::GoActive(); 162137f3c968ecd04e77802fe17bb82dabc07de21ca1Ian Rogers last_activity_time_ms_.StoreSequentiallyConsistent(0); 1622872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1623872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1624872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* 1625872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If a debugger event has fired in another thread, wait until the 16262bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz * initiating thread has suspended itself before processing commands 1627872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * from the debugger. Otherwise we (the JDWP thread) could be told to 1628872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * resume the thread before it has suspended. 1629872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 1630872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Note that we MUST clear the event token before waking the event 1631872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * thread up, or risk waiting for the thread to suspend after we've 1632872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * told it to resume. 1633872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 16342bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz AcquireJdwpTokenForCommand(); 1635400a3a9d332ee17e69b876cbbfb47d9e576fc4f2Sebastien Hertz 1636400a3a9d332ee17e69b876cbbfb47d9e576fc4f2Sebastien Hertz /* 1637872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Tell the VM that we're running and shouldn't be interrupted by GC. 1638872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Do this after anything that can stall indefinitely. 1639872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 164000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Thread* self = Thread::Current(); 1641f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier ScopedObjectAccess soa(self); 1642872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1643872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAddSpace(pReply, kJDWPHeaderLen); 1644872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1645a3c24aaf30fcce6c4393c923beeaad385f1257dbElliott Hughes size_t i; 1646cb69306eefc1e6e42b3eaec8b479a268222b01b6Elliott Hughes for (i = 0; i < arraysize(gHandlers); ++i) { 16477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (gHandlers[i].cmdSet == request->GetCommandSet() && 16487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz gHandlers[i].cmd == request->GetCommand() && 16497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz gHandlers[i].func != nullptr) { 1650cb69306eefc1e6e42b3eaec8b479a268222b01b6Elliott Hughes VLOG(jdwp) << DescribeCommand(request); 1651cb69306eefc1e6e42b3eaec8b479a268222b01b6Elliott Hughes result = (*gHandlers[i].func)(this, request, pReply); 16524b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes if (result == ERR_NONE) { 1653c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers request->CheckConsumed(); 16544b9702c6912c6f8745a77f5b5af56e7fe196e7c2Elliott Hughes } 16552c3e77a0b91b2225fcdd3b34d8a734b85eec0579Sebastien Hertz self->AssertNoPendingException(); 1656872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 1657872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1658872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1659cb69306eefc1e6e42b3eaec8b479a268222b01b6Elliott Hughes if (i == arraysize(gHandlers)) { 1660cb69306eefc1e6e42b3eaec8b479a268222b01b6Elliott Hughes LOG(ERROR) << "Command not implemented: " << DescribeCommand(request); 1661c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers LOG(ERROR) << HexDump(request->data(), request->size(), false, ""); 1662872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes result = ERR_NOT_IMPLEMENTED; 1663872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1664872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1665cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz size_t replyLength = 0U; 1666cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz if (result == ERR_NONE && IsInvokeCommand(request->GetCommandSet(), request->GetCommand())) { 1667cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz // We successfully request an invoke in the event thread. It will send the reply once the 1668cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz // invoke completes so we must not send it now. 1669cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz *skip_reply = true; 1670cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz } else { 1671cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz /* 1672cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz * Set up the reply header. 1673cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz * 1674cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz * If we encountered an error, only send the header back. 1675cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz */ 1676cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz uint8_t* replyBuf = expandBufGetBuffer(pReply); 1677cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz replyLength = (result == ERR_NONE) ? expandBufGetLength(pReply) : kJDWPHeaderLen; 1678cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz Set4BE(replyBuf + kJDWPHeaderSizeOffset, replyLength); 1679cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz Set4BE(replyBuf + kJDWPHeaderIdOffset, request->GetId()); 1680cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz Set1(replyBuf + kJDWPHeaderFlagsOffset, kJDWPFlagReply); 1681cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz Set2BE(replyBuf + kJDWPHeaderErrorCodeOffset, result); 1682cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz 1683cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz CHECK_GT(expandBufGetLength(pReply), 0U) << GetCommandName(request) << " " << request->GetId(); 1684cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz 1685cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz size_t respLen = expandBufGetLength(pReply) - kJDWPHeaderLen; 1686cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz VLOG(jdwp) << "REPLY: " << GetCommandName(request) << " " << result << " (length=" << respLen << ")"; 1687cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz if (false) { 1688cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz VLOG(jdwp) << HexDump(expandBufGetBuffer(pReply) + kJDWPHeaderLen, respLen, false, ""); 1689cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz } 1690872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1691872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1692cb69306eefc1e6e42b3eaec8b479a268222b01b6Elliott Hughes VLOG(jdwp) << "----------"; 1693cb69306eefc1e6e42b3eaec8b479a268222b01b6Elliott Hughes 1694872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* 1695872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Update last-activity timestamp. We really only need this during 1696872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * the initial setup. Only update if this is a non-DDMS packet. 1697872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1698c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers if (request->GetCommandSet() != kJDWPDdmCmdSet) { 169937f3c968ecd04e77802fe17bb82dabc07de21ca1Ian Rogers last_activity_time_ms_.StoreSequentiallyConsistent(MilliTime()); 1700872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1701872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 170243c8d729556844d1a74449a8a300c795d6a5406aSebastien Hertz return replyLength; 1703872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1704872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1705872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} // namespace JDWP 1706872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1707872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} // namespace art 1708