Home | History | Annotate | Download | only in runtime

Lines Matching refs:JDWP

33 #include "jdwp/object_registry.h"
294 // JDWP is allowed unless the Zygote forbids it.
297 // Was there a -Xrunjdwp or -agentlib:jdwp= argument on the command line?
300 // Broken-down JDWP options. (Only valid if IsJdwpConfigured() is true.)
301 static JDWP::JdwpOptions gJdwpOptions;
303 // Runtime JDWP state.
304 static JDWP::JdwpState* gJdwpState = NULL;
389 VLOG(jdwp) << "Hit breakpoint #" << i << ": " << gBreakpoints[i];
404 static mirror::Array* DecodeArray(JDWP::RefTypeId id, JDWP::JdwpError& status)
408 status = JDWP::ERR_INVALID_OBJECT;
412 status = JDWP::ERR_INVALID_ARRAY;
415 status = JDWP::ERR_NONE;
419 static mirror::Class* DecodeClass(JDWP::RefTypeId id, JDWP::JdwpError& status)
423 status = JDWP::ERR_INVALID_OBJECT;
427 status = JDWP::ERR_INVALID_CLASS;
430 status = JDWP::ERR_NONE;
434 static JDWP::JdwpError DecodeThread(ScopedObjectAccessUnchecked& soa, JDWP::ObjectId thread_id, Thread*& thread)
441 return JDWP::ERR_INVALID_OBJECT;
447 return JDWP::ERR_INVALID_THREAD;
453 return JDWP::ERR_THREAD_NOT_ALIVE;
455 return JDWP::ERR_NONE;
458 static JDWP::JdwpTag BasicTagFromDescriptor(const char* descriptor) {
459 // JDWP deliberately uses the descriptor characters' ASCII values for its enum.
461 return static_cast<JDWP::JdwpTag>(descriptor[0]);
464 static JDWP::JdwpTag BasicTagFromClass(mirror::Class* klass)
471 static JDWP::JdwpTag TagFromClass(const ScopedObjectAccessUnchecked& soa, mirror::Class* c)
475 return JDWP::JT_ARRAY;
478 return JDWP::JT_STRING;
481 return JDWP::JT_CLASS_OBJECT;
486 return JDWP::JT_THREAD;
493 return JDWP::JT_THREAD_GROUP;
500 return JDWP::JT_CLASS_LOADER;
503 return JDWP::JT_OBJECT;
514 JDWP::JdwpTag Dbg::TagFromObject(const ScopedObjectAccessUnchecked& soa, mirror::Object* o) {
515 return (o == NULL) ? JDWP::JT_OBJECT : TagFromClass(soa, o->GetClass());
518 static bool IsPrimitiveTag(JDWP::JdwpTag tag) {
520 case JDWP::JT_BOOLEAN:
521 case JDWP::JT_BYTE:
522 case JDWP::JT_CHAR:
523 case JDWP::JT_FLOAT:
524 case JDWP::JT_DOUBLE:
525 case JDWP::JT_INT:
526 case JDWP::JT_LONG:
527 case JDWP::JT_SHORT:
528 case JDWP::JT_VOID:
536 * Handle one of the JDWP name/value pairs.
538 * JDWP options are:
555 gJdwpOptions.transport = JDWP::kJdwpTransportSocket;
557 gJdwpOptions.transport = JDWP::kJdwpTransportAndroidAdb;
559 LOG(ERROR) << "JDWP transport not supported: " << value;
568 LOG(ERROR) << "JDWP option 'server' must be 'y' or 'n'";
577 LOG(ERROR) << "JDWP option 'suspend' must be 'y' or 'n'";
592 LOG(ERROR) << "JDWP address missing port: " << value;
598 LOG(ERROR) << "JDWP address has junk in port field: " << value;
604 LOG(INFO) << "Ignoring JDWP option '" << name << "'='" << value << "'";
606 LOG(INFO) << "Ignoring unrecognized JDWP option '" << name << "'='" << value << "'";
613 * Parse the latter half of a -Xrunjdwp/-agentlib:jdwp= string, e.g.:
617 VLOG(jdwp) << "ParseJdwpOptions: " << options;
625 LOG(ERROR) << "Can't parse JDWP option '" << pairs[i] << "' in '" << options << "'";
631 if (gJdwpOptions.transport == JDWP::kJdwpTransportUnknown) {
632 LOG(ERROR) << "Must specify JDWP transport: " << options;
635 LOG(ERROR) << "Must specify JDWP host and port when server=n: " << options;
645 // No JDWP for you!
652 // Init JDWP if the debugger is enabled. This may connect out to a
655 gJdwpState = JDWP::JdwpState::Create(&gJdwpOptions);
674 // Post VM_DEATH event before the JDWP connection is closed (either by the JDWP thread or the
679 // Prevent the JDWP thread from processing JDWP incoming packets after we close the connection.
690 VLOG(jdwp) << "Sending heap info to DDM";
695 VLOG(jdwp) << "Dumping heap to DDM";
700 VLOG(jdwp) << "Dumping native heap to DDM";
723 VLOG(jdwp) << "JDWP has attached";
745 // Only called from the JDWP handler thread.
841 std::string Dbg::GetClassName(JDWP::RefTypeId class_id) {
863 JDWP::JdwpError Dbg::GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& class_object_id) {
864 JDWP::JdwpError status;
870 return JDWP::ERR_NONE;
873 JDWP::JdwpError Dbg::GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId& superclass_id) {
874 JDWP::JdwpError status;
885 return JDWP::ERR_NONE;
888 JDWP::JdwpError Dbg::GetClassLoader(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply) {
891 return JDWP::ERR_INVALID_OBJECT;
894 return JDWP::ERR_NONE;
897 JDWP::JdwpError Dbg::GetModifiers(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply) {
898 JDWP::JdwpError status;
908 // Class.getModifiers doesn't return it, but JDWP does, so we set it here.
915 return JDWP::ERR_NONE;
918 JDWP::JdwpError Dbg::GetMonitorInfo(JDWP::ObjectId object_id, JDWP::ExpandBuf* reply)
922 return JDWP::ERR_INVALID_OBJECT;
946 return JDWP::ERR_NONE;
949 JDWP::JdwpError Dbg::GetOwnedMonitors(JDWP::ObjectId thread_id,
950 std::vector<JDWP::ObjectId>& monitors,
954 std::vector<JDWP::ObjectId>* monitor_vector,
978 std::vector<JDWP::ObjectId>* monitors;
986 JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
987 JDWP::ERR_NONE) {
991 return JDWP::ERR_THREAD_NOT_SUSPENDED;
997 return JDWP::ERR_NONE;
1000 JDWP::JdwpError Dbg::GetContendedMonitor(JDWP::ObjectId thread_id,
1001 JDWP::ObjectId& contended_monitor) {
1007 JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
1008 if (error != JDWP::ERR_NONE) {
1012 return JDWP::ERR_THREAD_NOT_SUSPENDED;
1019 return JDWP::ERR_NONE;
1022 JDWP::JdwpError Dbg::GetInstanceCounts(const std::vector<JDWP::RefTypeId>& class_ids,
1030 JDWP::JdwpError status;
1039 return JDWP::ERR_NONE;
1042 JDWP::JdwpError Dbg::GetInstances(JDWP::RefTypeId class_id, int32_t max_count, std::vector<JDWP::ObjectId>& instances)
1047 JDWP::JdwpError status;
1057 return JDWP::ERR_NONE;
1060 JDWP::JdwpError Dbg::GetReferringObjects(JDWP::ObjectId object_id, int32_t max_count,
1061 std::vector<JDWP::ObjectId>& referring_objects)
1067 return JDWP::ERR_INVALID_OBJECT;
1074 return JDWP::ERR_NONE;
1077 JDWP::JdwpError Dbg::DisableCollection(JDWP::ObjectId object_id)
1081 return JDWP::ERR_INVALID_OBJECT;
1084 return JDWP::ERR_NONE;
1087 JDWP::JdwpError Dbg::EnableCollection(JDWP::ObjectId object_id)
1090 // Unlike DisableCollection, JDWP specs do not state an invalid object causes an error. The RI
1095 return JDWP::ERR_INVALID_OBJECT;
1098 return JDWP::ERR_NONE;
1101 JDWP::JdwpError Dbg::IsCollected(JDWP::ObjectId object_id, bool& is_collected)
1105 return JDWP::ERR_INVALID_OBJECT;
1107 // JDWP specs state an INVALID_OBJECT error is returned if the object ID is not valid. However
1115 return JDWP::ERR_NONE;
1118 void Dbg::DisposeObject(JDWP::ObjectId object_id, uint32_t reference_count)
1123 JDWP::JdwpTypeTag Dbg::GetTypeTag(mirror::Class* klass) {
1126 return JDWP::TT_ARRAY;
1128 return JDWP::TT_INTERFACE;
1130 return JDWP::TT_CLASS;
1134 JDWP::JdwpError Dbg::GetReflectedType(JDWP::RefTypeId class_id, JDWP::ExpandBuf* pReply) {
1135 JDWP::JdwpError status;
1141 JDWP::JdwpTypeTag type_tag = GetTypeTag(c);
1144 return JDWP::ERR_NONE;
1147 void Dbg::GetClassList(std::vector<JDWP::RefTypeId>& classes) {
1152 explicit ClassListCreator(std::vector<JDWP::RefTypeId>& classes) : classes(classes) {
1168 std::vector<JDWP::RefTypeId>& classes;
1176 JDWP::JdwpError Dbg::GetClassInfo(JDWP::RefTypeId class_id, JDWP::JdwpTypeTag* pTypeTag,
1178 JDWP::JdwpError status;
1185 *pStatus = JDWP::CS_VERIFIED | JDWP::CS_PREPARED;
1186 *pTypeTag = JDWP::TT_ARRAY;
1189 *pStatus = JDWP::CS_ERROR;
1191 *pStatus = JDWP::CS_VERIFIED | JDWP::CS_PREPARED | JDWP::CS_INITIALIZED;
1193 *pTypeTag = c->IsInterface() ? JDWP::TT_INTERFACE : JDWP::TT_CLASS;
1200 return JDWP::ERR_NONE;
1203 void Dbg::FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>& ids) {
1212 JDWP::JdwpError Dbg::GetReferenceType(JDWP::ObjectId object_id, JDWP::ExpandBuf* pReply)
1216 return JDWP::ERR_INVALID_OBJECT;
1219 JDWP::JdwpTypeTag type_tag = GetTypeTag(o->GetClass());
1220 JDWP::RefTypeId type_id = gRegistry->AddRefType(o->GetClass());
1225 return JDWP::ERR_NONE;
1228 JDWP::JdwpError Dbg::GetSignature(JDWP::RefTypeId class_id, std::string* signature) {
1229 JDWP::JdwpError status;
1236 return JDWP::ERR_NONE;
1239 JDWP::JdwpError Dbg::GetSourceFile(JDWP::RefTypeId class_id, std::string& result) {
1240 JDWP::JdwpError status;
1247 return JDWP::ERR_ABSENT_INFORMATION;
1250 return JDWP::ERR_NONE;
1253 JDWP::JdwpError Dbg::GetObjectTag(JDWP::ObjectId object_id, uint8_t& tag) {
1257 return JDWP::ERR_INVALID_OBJECT;
1260 return JDWP::ERR_NONE;
1263 size_t Dbg::GetTagWidth(JDWP::JdwpTag tag) {
1265 case JDWP::JT_VOID:
1267 case JDWP::JT_BYTE:
1268 case JDWP::JT_BOOLEAN:
1270 case JDWP::JT_CHAR:
1271 case JDWP::JT_SHORT:
1273 case JDWP::JT_FLOAT:
1274 case JDWP::JT_INT:
1276 case JDWP::JT_ARRAY:
1277 case JDWP::JT_OBJECT:
1278 case JDWP::JT_STRING:
1279 case JDWP::JT_THREAD:
1280 case JDWP::JT_THREAD_GROUP:
1281 case JDWP::JT_CLASS_LOADER:
1282 case JDWP::JT_CLASS_OBJECT:
1283 return sizeof(JDWP::ObjectId);
1284 case JDWP::JT_DOUBLE:
1285 case JDWP::JT_LONG:
1293 JDWP::JdwpError Dbg::GetArrayLength(JDWP::ObjectId array_id, int& length) {
1294 JDWP::JdwpError status;
1300 return JDWP::ERR_NONE;
1303 JDWP::JdwpError Dbg::OutputArray(JDWP::ObjectId array_id, int offset, int count, JDWP::ExpandBuf* pReply) {
1304 JDWP::JdwpError status;
1312 return JDWP::ERR_INVALID_LENGTH;
1314 JDWP::JdwpTag element_tag = BasicTagFromClass(a->GetClass()->GetComponentType());
1323 for (int i = 0; i < count; ++i) JDWP::Write8BE(&dst, src8[offset + i]);
1326 for (int i = 0; i < count; ++i) JDWP::Write4BE(&dst, src4[offset + i]);
1329 for (int i = 0; i < count; ++i) JDWP::Write2BE(&dst, src2[offset + i]);
1339 JDWP::JdwpTag specific_tag = (element != nullptr) ? TagFromObject(soa, element)
1346 return JDWP::ERR_NONE;
1350 static void CopyArrayData(mirror::Array* a, JDWP::Request& src, int offset, int count)
1361 JDWP::JdwpError Dbg::SetArrayElements(JDWP::ObjectId array_id, int offset, int count,
1362 JDWP::Request& request)
1364 JDWP::JdwpError status;
1372 return JDWP::ERR_INVALID_LENGTH;
1374 JDWP::JdwpTag element_tag = BasicTagFromClass(dst->GetClass()->GetComponentType());
1390 JDWP::ObjectId id = request.ReadObjectId();
1393 return JDWP::ERR_INVALID_OBJECT;
1399 return JDWP::ERR_NONE;
1402 JDWP::ObjectId Dbg::CreateString(const std::string& str) {
1406 JDWP::JdwpError Dbg::CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId& new_object) {
1407 JDWP::JdwpError status;
1413 return JDWP::ERR_NONE;
1419 JDWP::JdwpError Dbg::CreateArrayObject(JDWP::RefTypeId array_class_id, uint32_t length,
1420 JDWP::ObjectId& new_array) {
1421 JDWP::JdwpError status;
1429 return JDWP::ERR_NONE;
1432 JDWP::FieldId Dbg::ToFieldId(const mirror::ArtField* f) {
1434 return static_cast<JDWP::FieldId>(reinterpret_cast<uintptr_t>(f));
1437 static JDWP::MethodId ToMethodId(const mirror::ArtMethod* m)
1440 return static_cast<JDWP::MethodId>(reinterpret_cast<uintptr_t>(m));
1443 static mirror::ArtField* FromFieldId(JDWP::FieldId fid)
1449 static mirror::ArtMethod* FromMethodId(JDWP::MethodId mid)
1455 bool Dbg::MatchThread(JDWP::ObjectId expected_thread_id, Thread* event_thread) {
1461 bool Dbg::MatchLocation(const JDWP::JdwpLocation& expected_location,
1462 const JDWP::EventLocation& event_location) {
1470 bool Dbg::MatchType(mirror::Class* event_class, JDWP::RefTypeId class_id) {
1474 JDWP::JdwpError status;
1480 bool Dbg::MatchField(JDWP::RefTypeId expected_type_id, JDWP::FieldId expected_field_id,
1489 bool Dbg::MatchInstance(JDWP::ObjectId expected_instance_id, mirror::Object* event_instance) {
1494 void Dbg::SetJdwpLocation(JDWP::JdwpLocation* location, mirror::ArtMethod* m, uint32_t dex_pc)
1507 std::string Dbg::GetMethodName(JDWP::MethodId method_id)
1516 std::string Dbg::GetFieldName(JDWP::FieldId field_id)
1583 JDWP::JdwpError Dbg::OutputDeclaredFields(JDWP::RefTypeId class_id, bool with_generic, JDWP::ExpandBuf* pReply) {
1584 JDWP::JdwpError status;
1606 return JDWP::ERR_NONE;
1609 JDWP::JdwpError Dbg::OutputDeclaredMethods(JDWP::RefTypeId class_id, bool with_generic,
1610 JDWP::ExpandBuf* pReply) {
1611 JDWP::JdwpError status;
1633 return JDWP::ERR_NONE;
1636 JDWP::JdwpError Dbg::OutputDeclaredInterfaces(JDWP::RefTypeId class_id, JDWP::ExpandBuf* pReply) {
1637 JDWP::JdwpError status;
1650 return JDWP::ERR_NONE;
1653 void Dbg::OutputLineTable(JDWP::RefTypeId, JDWP::MethodId method_id, JDWP::ExpandBuf* pReply)
1657 JDWP::ExpandBuf* pReply;
1696 JDWP::Set4BE(expandBufGetBuffer(pReply) + numLinesOffset, context.numItems);
1699 void Dbg::OutputVariableTable(JDWP::RefTypeId, JDWP::MethodId method_id, bool with_generic,
1700 JDWP::ExpandBuf* pReply) {
1703 JDWP::ExpandBuf* pReply;
1712 VLOG(jdwp) << StringPrintf(" %2zd: %d(%d) '%s' '%s' '%s' actual slot=%d mangled slot=%d",
1755 JDWP::Set4BE(expandBufGetBuffer(pReply) + variable_count_offset, context.variable_count);
1758 void Dbg::OutputMethodReturnValue(JDWP::MethodId method_id, const JValue* return_value,
1759 JDWP::ExpandBuf* pReply) {
1761 JDWP::JdwpTag tag = BasicTagFromDescriptor(m->GetShorty());
1765 void Dbg::OutputFieldValue(JDWP::FieldId field_id, const JValue* field_value,
1766 JDWP::ExpandBuf* pReply) {
1768 JDWP::JdwpTag tag = BasicTagFromDescriptor(f->GetTypeDescriptor());
1772 JDWP::JdwpError Dbg::GetBytecodes(JDWP::RefTypeId, JDWP::MethodId method_id,
1777 return JDWP::ERR_INVALID_METHODID;
1786 return JDWP::ERR_NONE;
1789 JDWP::JdwpTag Dbg::GetFieldBasicTag(JDWP::FieldId field_id) {
1793 JDWP::JdwpTag Dbg::GetStaticFieldBasicTag(JDWP::FieldId field_id) {
1797 static JDWP::JdwpError GetFieldValueImpl(JDWP::RefTypeId ref_type_id, JDWP::ObjectId object_id,
1798 JDWP::FieldId field_id, JDWP::ExpandBuf* pReply,
1801 JDWP::JdwpError status;
1809 return JDWP::ERR_INVALID_OBJECT;
1820 return JDWP::ERR_INVALID_FIELDID;
1827 return JDWP::ERR_INVALID_FIELDID;
1838 JDWP::JdwpTag tag = BasicTagFromDescriptor(f->GetTypeDescriptor());
1840 if (tag == JDWP::JT_VOID) {
1844 } else if (tag == JDWP::JT_DOUBLE || tag == JDWP::JT_LONG) {
1851 return JDWP::ERR_NONE;
1854 JDWP::JdwpError Dbg::GetFieldValue(JDWP::ObjectId object_id, JDWP::FieldId field_id,
1855 JDWP::ExpandBuf* pReply) {
1859 JDWP::JdwpError Dbg::GetStaticFieldValue(JDWP::RefTypeId ref_type_id, JDWP::FieldId field_id, JDWP::ExpandBuf* pReply) {
1863 static JDWP::JdwpError SetFieldValueImpl(JDWP::ObjectId object_id, JDWP::FieldId field_id,
1868 return JDWP::ERR_INVALID_OBJECT;
1876 return JDWP::ERR_INVALID_FIELDID;
1887 JDWP::JdwpTag tag = BasicTagFromDescriptor(f->GetTypeDescriptor());
1890 if (tag == JDWP::JT_DOUBLE || tag == JDWP::JT_LONG) {
1902 return JDWP::ERR_INVALID_OBJECT;
1914 return JDWP::ERR_INVALID_OBJECT;
1921 return JDWP::ERR_NONE;
1924 JDWP::JdwpError Dbg::SetFieldValue(JDWP::ObjectId object_id, JDWP::FieldId field_id, uint64_t value,
1929 JDWP::JdwpError Dbg::SetStaticFieldValue(JDWP::FieldId field_id, uint64_t value, int width) {
1933 JDWP::JdwpError Dbg::StringToUtf8(JDWP::ObjectId string_id, std::string* str) {
1936 return JDWP::ERR_INVALID_OBJECT;
1943 return JDWP::ERR_INVALID_STRING;
1947 return JDWP::ERR_NONE;
1950 void Dbg::OutputJValue(JDWP::JdwpTag tag, const JValue* return_value, JDWP::ExpandBuf* pReply) {
1953 if (tag == JDWP::JT_BOOLEAN || tag == JDWP::JT_BYTE) {
1955 } else if (tag == JDWP::JT_CHAR || tag == JDWP::JT_SHORT) {
1957 } else if (tag == JDWP::JT_FLOAT || tag == JDWP::JT_INT) {
1959 } else if (tag == JDWP::JT_DOUBLE || tag == JDWP::JT_LONG) {
1962 CHECK_EQ(tag, JDWP::JT_VOID);
1972 JDWP::JdwpError Dbg::GetThreadName(JDWP::ObjectId thread_id, std::string& name) {
1976 JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
1977 if (error != JDWP::ERR_NONE && error != JDWP::ERR_THREAD_NOT_ALIVE) {
1990 return JDWP::ERR_NONE;
1993 JDWP::JdwpError Dbg::GetThreadGroup(JDWP::ObjectId thread_id, JDWP::ExpandBuf* pReply) {
1997 return JDWP::ERR_INVALID_OBJECT;
2001 JDWP::JdwpError error;
2007 if (error == JDWP::ERR_THREAD_NOT_ALIVE) {
2009 expandBufAddObjectId(pReply, JDWP::ObjectId(0));
2010 error = JDWP::ERR_NONE;
2011 } else if (error == JDWP::ERR_NONE) {
2018 JDWP::ObjectId thread_group_id = gRegistry->Add(group);
2026 JDWP::ObjectId thread_group_id, JDWP::JdwpError* error)
2030 *error = JDWP::ERR_INVALID_OBJECT;
2037 *error = JDWP::ERR_INVALID_THREAD_GROUP;
2040 *error = JDWP::ERR_NONE;
2044 JDWP::JdwpError Dbg::GetThreadGroupName(JDWP::ObjectId thread_group_id, JDWP::ExpandBuf* pReply) {
2046 JDWP::JdwpError error;
2048 if (error != JDWP::ERR_NONE) {
2060 return JDWP::ERR_NONE;
2063 JDWP::JdwpError Dbg::GetThreadGroupParent(JDWP::ObjectId thread_group_id, JDWP::ExpandBuf* pReply) {
2065 JDWP::JdwpError error;
2067 if (error != JDWP::ERR_NONE) {
2078 JDWP::ObjectId parent_group_id = gRegistry->Add(parent);
2080 return JDWP::ERR_NONE;
2084 std::vector<JDWP::ObjectId>* child_thread_group_ids)
2106 JDWP::JdwpError Dbg::GetThreadGroupChildren(JDWP::ObjectId thread_group_id,
2107 JDWP::ExpandBuf* pReply) {
2109 JDWP::JdwpError error;
2111 if (error != JDWP::ERR_NONE) {
2117 std::vector<JDWP::ObjectId> child_thread_ids;
2120 for (JDWP::ObjectId child_thread_id : child_thread_ids) {
2127 std::vector<JDWP::ObjectId> child_thread_groups_ids;
2130 for (JDWP::ObjectId child_thread_group_id : child_thread_groups_ids) {
2135 return JDWP::ERR_NONE;
2138 JDWP::ObjectId Dbg::GetSystemThreadGroupId() {
2145 JDWP::JdwpThreadStatus Dbg::ToJdwpThreadStatus(ThreadState state) {
2148 return JDWP::TS_MONITOR;
2152 return JDWP::TS_RUNNING;
2154 return JDWP::TS_SLEEPING;
2157 return JDWP::TS_ZOMBIE;
2172 return JDWP::TS_WAIT;
2176 return JDWP::TS_ZOMBIE;
2179 JDWP::JdwpError Dbg::GetThreadStatus(JDWP::ObjectId thread_id, JDWP::JdwpThreadStatus* pThreadStatus,
2180 JDWP::JdwpSuspendStatus* pSuspendStatus) {
2183 *pSuspendStatus = JDWP::SUSPEND_STATUS_NOT_SUSPENDED;
2187 JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
2188 if (error != JDWP::ERR_NONE) {
2189 if (error == JDWP::ERR_THREAD_NOT_ALIVE) {
2190 *pThreadStatus = JDWP::TS_ZOMBIE;
2191 return JDWP::ERR_NONE;
2197 *pSuspendStatus = JDWP::SUSPEND_STATUS_SUSPENDED;
2201 return JDWP::ERR_NONE;
2204 JDWP::JdwpError Dbg::GetThreadDebugSuspendCount(JDWP::ObjectId thread_id, JDWP::ExpandBuf* pReply) {
2208 JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
2209 if (error != JDWP::ERR_NONE) {
2214 return JDWP::ERR_NONE;
2217 JDWP::JdwpError Dbg::Interrupt(JDWP::ObjectId thread_id) {
2221 JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
2222 if (error != JDWP::ERR_NONE) {
2226 return JDWP::ERR_NONE;
2242 void Dbg::GetThreads(mirror::Object* thread_group, std::vector<JDWP::ObjectId>* thread_ids) {
2251 // Skip the JDWP thread. Some debuggers get bent out of shape when they can't suspend and
2296 JDWP::JdwpError Dbg::GetThreadFrameCount(JDWP::ObjectId thread_id, size_t& result) {
2300 JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
2301 if (error != JDWP::ERR_NONE) {
2305 return JDWP::ERR_THREAD_NOT_SUSPENDED;
2308 return JDWP::ERR_NONE;
2311 JDWP::JdwpError Dbg::GetThreadFrames(JDWP::ObjectId thread_id, size_t start_frame,
2312 size_t frame_count, JDWP::ExpandBuf* buf) {
2315 GetFrameVisitor(Thread* thread, size_t start_frame, size_t frame_count, JDWP::ExpandBuf* buf)
2332 JDWP::FrameId frame_id(GetFrameId());
2333 JDWP::JdwpLocation location;
2335 VLOG(jdwp) << StringPrintf(" Frame %3zd: id=%3" PRIu64 " ", depth_, frame_id) << location;
2347 JDWP::ExpandBuf* buf_;
2353 JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
2354 if (error != JDWP::ERR_NONE) {
2358 return JDWP::ERR_THREAD_NOT_SUSPENDED;
2362 return JDWP::ERR_NONE;
2365 JDWP::ObjectId Dbg::GetThreadSelfId() {
2369 JDWP::ObjectId Dbg::GetThreadId(Thread* thread) {
2382 JDWP::JdwpError Dbg::SuspendThread(JDWP::ObjectId thread_id, bool request_suspension) {
2390 return JDWP::ERR_THREAD_NOT_ALIVE;
2400 return JDWP::ERR_NONE;
2402 return JDWP::ERR_INTERNAL;
2404 return JDWP::ERR_THREAD_NOT_ALIVE;
2408 void Dbg::ResumeThread(JDWP::ObjectId thread_id) {
2435 GetThisVisitor(Thread* thread, Context* context, JDWP::FrameId frame_id)
2451 JDWP::FrameId frame_id;
2454 JDWP::JdwpError Dbg::GetThisObject(JDWP::ObjectId thread_id, JDWP::FrameId frame_id,
2455 JDWP::ObjectId* result) {
2460 JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
2461 if (error != JDWP::ERR_NONE) {
2465 return JDWP::ERR_THREAD_NOT_SUSPENDED;
2472 return JDWP::ERR_NONE;
2478 FindFrameVisitor(Thread* thread, Context* context, JDWP::FrameId frame_id)
2480 : StackVisitor(thread, context), frame_id_(frame_id), error_(JDWP::ERR_INVALID_FRAMEID) {}
2491 error_ = JDWP::ERR_OPAQUE_FRAME;
2494 error_ = JDWP::ERR_NONE;
2499 JDWP::JdwpError GetError() const {
2504 const JDWP::FrameId frame_id_;
2505 JDWP::JdwpError error_;
2508 JDWP::JdwpError Dbg::GetLocalValues(JDWP::Request* request, JDWP::ExpandBuf* pReply) {
2509 JDWP::ObjectId thread_id = request->ReadThreadId();
2510 JDWP::FrameId frame_id = request->ReadFrameId();
2516 JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
2517 if (error != JDWP::ERR_NONE) {
2525 if (visitor.GetError() != JDWP::ERR_NONE) {
2534 JDWP::JdwpTag reqSigByte = request->ReadTag();
2536 VLOG(jdwp) << " --> slot " << slot << " " << reqSigByte;
2540 JDWP::JdwpError error = Dbg::GetLocalValue(visitor, soa, slot, reqSigByte, ptr, width);
2541 if (error != JDWP::ERR_NONE) {
2545 return JDWP::ERR_NONE;
2548 JDWP::JdwpError Dbg::GetLocalValue(const StackVisitor& visitor, ScopedObjectAccessUnchecked& soa,
2549 int slot, JDWP::JdwpTag tag, uint8_t* buf, size_t width) {
2554 constexpr JDWP::JdwpError kFailureErrorCode = JDWP::ERR_ABSENT_INFORMATION;
2556 case JDWP::JT_BOOLEAN: {
2560 VLOG(jdwp) << "get boolean local " << reg << " = " << intVal;
2561 JDWP::Set1(buf + 1, intVal != 0);
2563 VLOG(jdwp) << "failed to get boolean local " << reg;
2568 case JDWP::JT_BYTE: {
2572 VLOG(jdwp) << "get byte local " << reg << " = " << intVal;
2573 JDWP::Set1(buf + 1, intVal);
2575 VLOG(jdwp) << "failed to get byte local " << reg;
2580 case JDWP::JT_SHORT:
2581 case JDWP::JT_CHAR: {
2585 VLOG(jdwp) << "get short/char local " << reg << " = " << intVal;
2586 JDWP::Set2BE(buf + 1, intVal);
2588 VLOG(jdwp) << "failed to get short/char local " << reg;
2593 case JDWP::JT_INT: {
2597 VLOG(jdwp) << "get int local " << reg << " = " << intVal;
2598 JDWP::Set4BE(buf + 1, intVal);
2600 VLOG(jdwp) << "failed to get int local " << reg;
2605 case JDWP::JT_FLOAT: {
2609 VLOG(jdwp) << "get float local " << reg << " = " << intVal;
2610 JDWP::Set4BE(buf + 1, intVal);
2612 VLOG(jdwp) << "failed to get float local " << reg;
2617 case JDWP::JT_ARRAY:
2618 case JDWP::JT_CLASS_LOADER:
2619 case JDWP::JT_CLASS_OBJECT:
2620 case JDWP::JT_OBJECT:
2621 case JDWP::JT_STRING:
2622 case JDWP::JT_THREAD:
2623 case JDWP::JT_THREAD_GROUP: {
2624 CHECK_EQ(width, sizeof(JDWP::ObjectId));
2628 VLOG(jdwp) << "get " << tag << " object local " << reg << " = " << o;
2633 JDWP::SetObjectId(buf + 1, gRegistry->Add(o));
2635 VLOG(jdwp) << "failed to get " << tag << " object local " << reg;
2640 case JDWP::JT_DOUBLE: {
2644 VLOG(jdwp) << "get double local " << reg << " = " << longVal;
2645 JDWP::Set8BE(buf + 1, longVal);
2647 VLOG(jdwp) << "failed to get double local " << reg;
2652 case JDWP::JT_LONG: {
2656 VLOG(jdwp) << "get long local " << reg << " = " << longVal;
2657 JDWP::Set8BE(buf + 1, longVal);
2659 VLOG(jdwp) << "failed to get long local " << reg;
2670 JDWP::Set1(buf, tag);
2671 return JDWP::ERR_NONE;
2674 JDWP::JdwpError Dbg::SetLocalValues(JDWP::Request* request) {
2675 JDWP::ObjectId thread_id = request->ReadThreadId();
2676 JDWP::FrameId frame_id = request->ReadFrameId();
2682 JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
2683 if (error != JDWP::ERR_NONE) {
2691 if (visitor.GetError() != JDWP::ERR_NONE) {
2699 JDWP::JdwpTag sigByte = request->ReadTag();
2703 VLOG(jdwp) << " --> slot " << slot << " " << sigByte << " " << value;
2704 JDWP::JdwpError error = Dbg::SetLocalValue(visitor, slot, sigByte, value, width);
2705 if (error != JDWP::ERR_NONE) {
2709 return JDWP::ERR_NONE;
2712 JDWP::JdwpError Dbg::SetLocalValue(StackVisitor& visitor, int slot, JDWP::JdwpTag tag,
2718 constexpr JDWP::JdwpError kFailureErrorCode = JDWP::ERR_ABSENT_INFORMATION;
2720 case JDWP::JT_BOOLEAN:
2721 case JDWP::JT_BYTE:
2724 VLOG(jdwp) << "failed to set boolean/byte local " << reg << " = "
2729 case JDWP::JT_SHORT:
2730 case JDWP::JT_CHAR:
2733 VLOG(jdwp) << "failed to set short/char local " << reg << " = "
2738 case JDWP::JT_INT:
2741 VLOG(jdwp) << "failed to set int local " << reg << " = "
2746 case JDWP::JT_FLOAT:
2749 VLOG(jdwp) << "failed to set float local " << reg << " = "
2754 case JDWP::JT_ARRAY:
2755 case JDWP::JT_CLASS_LOADER:
2756 case JDWP::JT_CLASS_OBJECT:
2757 case JDWP::JT_OBJECT:
2758 case JDWP::JT_STRING:
2759 case JDWP::JT_THREAD:
2760 case JDWP::JT_THREAD_GROUP: {
2761 CHECK_EQ(width, sizeof(JDWP::ObjectId));
2762 mirror::Object* o = gRegistry->Get<mirror::Object*>(static_cast<JDWP::ObjectId>(value));
2764 VLOG(jdwp) << tag << " object " << o << " is an invalid object";
2765 return JDWP::ERR_INVALID_OBJECT;
2768 VLOG(jdwp) << "failed to set " << tag << " object local " << reg << " = " << o;
2773 case JDWP::JT_DOUBLE: {
2776 VLOG(jdwp) << "failed to set double local " << reg << " = " << value;
2781 case JDWP::JT_LONG: {
2784 VLOG(jdwp) << "failed to set double local " << reg << " = " << value;
2793 return JDWP::ERR_NONE;
2796 static void SetEventLocation(JDWP::EventLocation* location, mirror::ArtMethod* m, uint32_t dex_pc)
2814 JDWP::EventLocation location;
2827 JDWP::EventLocation location;
2842 JDWP::EventLocation location;
2854 JDWP::EventLocation exception_throw_location;
2856 JDWP::EventLocation exception_catch_location;
2887 if (single_step_control->step_depth == JDWP::SD_INTO) {
2893 VLOG(jdwp) << "SS new method";
2894 } else if (single_step_control->step_size == JDWP::SS_MIN) {
2896 VLOG(jdwp) << "SS new instruction";
2899 VLOG(jdwp) << "SS new line";
2901 } else if (single_step_control->step_depth == JDWP::SD_OVER) {
2913 VLOG(jdwp) << "SS method pop";
2916 if (single_step_control->step_size == JDWP::SS_MIN) {
2918 VLOG(jdwp) << "SS new instruction";
2921 VLOG(jdwp) << "SS new line";
2925 CHECK_EQ(single_step_control->step_depth, JDWP::SD_OUT);
2936 VLOG(jdwp) << "SS method pop";
2975 VLOG(jdwp) << StringPrintf("Add debugger as listener for instrumentation event 0x%x",
2981 VLOG(jdwp) << StringPrintf("Remove debugger as listener for instrumentation event 0x%x",
2988 VLOG(jdwp) << "Deoptimize the world ...";
2990 VLOG(jdwp) << "Deoptimize the world DONE";
2993 VLOG(jdwp) << "Undeoptimize the world ...";
2995 VLOG(jdwp) << "Undeoptimize the world DONE";
2998 VLOG(jdwp) << "Deoptimize method " << PrettyMethod(request.Method()) << " ...";
3000 VLOG(jdwp) << "Deoptimize method " << PrettyMethod(request.Method()) << " DONE";
3003 VLOG(jdwp) << "Undeoptimize method " << PrettyMethod(request.Method()) << " ...";
3005 VLOG(jdwp) << "Undeoptimize method " << PrettyMethod(request.Method()) << " DONE";
3053 VLOG(jdwp) << StringPrintf("Queue request #%zd to start listening to instrumentation event 0x%x",
3067 VLOG(jdwp) << StringPrintf("Queue request #%zd to stop listening to instrumentation event 0x%x",
3076 VLOG(jdwp) << "Queue request #" << deoptimization_requests_.size()
3088 VLOG(jdwp) << "Queue request #" << deoptimization_requests_.size()
3096 VLOG(jdwp) << "Queue request #" << deoptimization_requests_.size()
3103 VLOG(jdwp) << "Queue request #" << deoptimization_requests_.size()
3134 VLOG(jdwp) << "Process deoptimization request #" << req_index++;
3210 VLOG(jdwp) << "No need for deoptimization when fully running with interpreter for method "
3228 VLOG(jdwp) << "Need full deoptimization because of possible inlining of method "
3239 VLOG(jdwp) << "Need full deoptimization because of possible direct code call "
3243 VLOG(jdwp) << "Need selective deoptimization for compiled method " << PrettyMethod(m);
3248 VLOG(jdwp) << "No need for deoptimization for non-compiled method " << PrettyMethod(m);
3255 VLOG(jdwp) << "Breakpoint already set: no deoptimization is required";
3267 void Dbg::WatchLocation(const JDWP::JdwpLocation* location, DeoptimizationRequest* req) {
3295 VLOG(jdwp) << "Set breakpoint #" << (gBreakpoints.size() - 1) << ": "
3302 void Dbg::UnwatchLocation(const JDWP::JdwpLocation* location, DeoptimizationRequest* req) {
3309 VLOG(jdwp) << "Removed breakpoint #" << i << ": " << gBreakpoints[i];
3348 ScopedThreadSuspension(Thread* self, JDWP::ObjectId thread_id)
3352 error_(JDWP::ERR_NONE),
3360 if (error_ == JDWP::ERR_NONE) {
3377 error_ = JDWP::ERR_INVALID_THREAD;
3390 JDWP::JdwpError GetError() const {
3402 JDWP::JdwpError error_;
3407 JDWP::JdwpError Dbg::ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize step_size,
3408 JDWP::JdwpStepDepth step_depth) {
3411 if (sts.GetError() != JDWP::ERR_NONE) {
3525 if (VLOG_IS_ON(jdwp)) {
3526 VLOG(jdwp) << "Single-step thread: " << *thread;
3527 VLOG(jdwp) << "Single-step step size: " << single_step_control->step_size;
3528 VLOG(jdwp) << "Single-step step depth: " << single_step_control->step_depth;
3529 VLOG(jdwp) << "Single-step current method: " << PrettyMethod(single_step_control->method);
3530 VLOG(jdwp) << "Single-step current line: " << line_number;
3531 VLOG(jdwp) << "Single-step current stack depth: " << single_step_control->stack_depth;
3532 VLOG(jdwp) << "Single-step dex_pc values:";
3534 VLOG(jdwp) << StringPrintf(" %#x", dex_pc);
3538 return JDWP::ERR_NONE;
3541 void Dbg::UnconfigureStep(JDWP::ObjectId thread_id) {
3545 JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
3546 if (error == JDWP::ERR_NONE) {
3553 static char JdwpTagToShortyChar(JDWP::JdwpTag tag) {
3556 LOG(FATAL) << "unknown JDWP tag: " << PrintableChar(tag);
3559 case JDWP::JT_BYTE: return 'B';
3560 case JDWP::JT_CHAR: return 'C';
3561 case JDWP::JT_FLOAT: return 'F';
3562 case JDWP::JT_DOUBLE: return 'D';
3563 case JDWP::JT_INT: return 'I';
3564 case JDWP::JT_LONG: return 'J';
3565 case JDWP::JT_SHORT: return 'S';
3566 case JDWP::JT_VOID: return 'V';
3567 case JDWP::JT_BOOLEAN: return 'Z';
3570 case JDWP::JT_ARRAY:
3571 case JDWP::JT_OBJECT:
3572 case JDWP::JT_STRING:
3573 case JDWP::JT_THREAD:
3574 case JDWP::JT_THREAD_GROUP:
3575 case JDWP::JT_CLASS_LOADER:
3576 case JDWP::JT_CLASS_OBJECT:
3581 JDWP::JdwpError Dbg::InvokeMethod(JDWP::ObjectId thread_id, JDWP::ObjectId object_id,
3582 JDWP::RefTypeId class_id, JDWP::MethodId method_id,
3584 JDWP::JdwpTag* arg_types, uint32_t options,
3585 JDWP::JdwpTag* pResultTag, uint64_t* pResultValue,
3586 JDWP
3595 JDWP::JdwpError error = DecodeThread(soa, thread_id, targetThread);
3596 if (error != JDWP::ERR_NONE) {
3603 return JDWP::ERR_INVALID_THREAD;
3627 return JDWP::ERR_THREAD_SUSPENDED; // Probably not expected here.
3630 JDWP::JdwpError status;
3633 return JDWP::ERR_INVALID_OBJECT;
3638 return JDWP::ERR_INVALID_OBJECT;
3649 return JDWP::ERR_INVALID_METHODID;
3653 return JDWP::ERR_INVALID_METHODID;
3657 return JDWP::ERR_INVALID_METHODID;
3665 return JDWP::ERR_ILLEGAL_ARGUMENT;
3676 return JDWP::ERR_ILLEGAL_ARGUMENT;
3684 return JDWP::ERR_INVALID_OBJECT;
3687 return JDWP::ERR_ILLEGAL_ARGUMENT;
3715 * We change our (JDWP thread) status, which should be THREAD_RUNNING,
3722 VLOG(jdwp) << " Transferring control to event thread";
3726 if ((options & JDWP::INVOKE_SINGLE_THREADED) == 0) {
3727 VLOG(jdwp) << " Resuming all threads";
3730 VLOG(jdwp) << " Resuming event thread only";
3739 VLOG(jdwp) << " Control has returned from event thread";
3753 if ((options & JDWP::INVOKE_SINGLE_THREADED) == 0) {
3755 VLOG(jdwp) << " Suspending all threads";
3758 VLOG(jdwp) << " Resuming event thread to balance the count";
3797 if ((pReq->options & JDWP::INVOKE_NONVIRTUAL) == 0 && pReq->receiver != NULL) {
3800 VLOG(jdwp) << "ExecuteMethod translated " << PrettyMethod(m.Get()) << " to " << PrettyMethod(actual_method);
3804 VLOG(jdwp) << "ExecuteMethod " << PrettyMethod(m.Get())
3819 VLOG(jdwp) << " JDWP invocation returning with exception=" << exception
3822 } else if (pReq->result_tag == JDWP::JT_OBJECT) {
3824 JDWP::JdwpTag new_tag = TagFromObject(soa, pReq->result_value.GetL());
3826 VLOG(jdwp) << " JDWP promoted result from " << pReq->result_tag << " to " << new_tag;
3851 * "request" contains a full JDWP packet, possibly with multiple chunks. We
3861 bool Dbg::DdmHandlePacket(JDWP::Request& request, uint8_t** pReplyBuf, int* pReplyLen) {
3908 * integrates the JDWP code more tightly into the rest of the runtime, and doesn't work
3918 VLOG(jdwp) << StringPrintf("DDM reply: type=0x%08x data=%p offset=%d length=%d", type, replyData.get(), offset, length);
3929 JDWP::Set4BE(reply + 0, type);
3930 JDWP::Set4BE(reply + 4, length);
3936 VLOG(jdwp) << StringPrintf("dvmHandleDdm returning type=%.4s %p len=%d", reinterpret_cast<char*>(reply), reply, length);
3941 VLOG(jdwp) << "Broadcasting DDM " << (connect ? "connect" : "disconnect") << "...";
3983 JDWP::Set4BE(&buf[0], t->GetThreadId());
3994 JDWP::Append4BE(bytes, t->GetThreadId());
3995 JDWP::AppendUtf16BE(bytes, chars, char_count);
4054 VLOG(jdwp) << "Debugger thread not active, ignoring DDM send: " << type;
4124 JDWP::Append4BE(bytes, heap_count);
4125 JDWP::Append4BE(bytes, 1); // Heap id (bogus; we only have one heap).
4126 JDWP::Append8BE(bytes, MilliTime());
4127 JDWP::Append1BE(bytes, reason);
4128 JDWP::Append4BE(bytes, heap->GetMaxMemory()); // Max allowed heap size in bytes.
4129 JDWP::Append4BE(bytes, heap->GetTotalMemory()); // Current heap size in bytes.
4130 JDWP::Append4BE(bytes, heap->GetBytesAllocated());
4131 JDWP::Append4BE(bytes, heap->GetObjectsAllocated());
4197 JDWP::Write4BE(&p_, 1); // Heap id (bogus; we only have one heap).
4198 JDWP::Write1BE(&p_, 8); // Size of allocation unit, in bytes.
4200 JDWP::Write4BE(&p_, reinterpret_cast<uintptr_t>(chunk_ptr)); // virtual address of segment start.
4201 JDWP::Write4BE(&p_, 0); // offset of this piece (relative to the virtual address).
4205 JDWP::Write4BE(&p_, 0x55555555);
4218 JDWP::Set4BE(pieceLenField_, totalAllocationUnits_);
4416 JDWP::Set4BE(&heap_id[0], 1); // Heap id (bogus; we only have one heap).
4678 JDWP::AppendUtf16BE(bytes, s_utf16.get(), s_len);
4783 JDWP::Append1BE(bytes, kMessageHeaderLen);
4784 JDWP::Append1BE(bytes, kEntryHeaderLen);
4785 JDWP::Append1BE(bytes, kStackFrameLen);
4792 JDWP::Append2BE(bytes, capped_count);
4794 JDWP::Append4BE(bytes, 0); // We'll patch this later...
4795 JDWP::Append2BE(bytes, class_names.Size());
4796 JDWP::Append2BE(bytes, method_names.Size());
4797 JDWP::Append2BE(bytes, filenames.Size());
4811 JDWP::Append4BE(bytes, record->ByteCount());
4812 JDWP::Append2BE(bytes, record->ThinLockId());
4813 JDWP::Append2BE(bytes, allocated_object_class_name_index);
4814 JDWP::Append1BE(bytes, stack_depth);
4826 JDWP::Append2BE(bytes, class_name_index);
4827 JDWP::Append2BE(bytes, method_name_index);
4828 JDWP::Append2BE(bytes, file_name_index);
4829 JDWP::Append2BE(bytes, record->StackElement(stack_frame)->LineNumber());
4837 JDWP::Set4BE(&bytes[string_table_offset], bytes.size());