Improve JDWP error handling.
In particular, we can't use NULL to mean "invalid"; some JDWP calls
legitimately need to handle NULL.
Change-Id: Iec4fac5521994bdb1f59677bd5af153684d4e266
diff --git a/src/jdwp/jdwp_handler.cc b/src/jdwp/jdwp_handler.cc
index 3f79601..9b5761a 100644
--- a/src/jdwp/jdwp_handler.cc
+++ b/src/jdwp/jdwp_handler.cc
@@ -204,15 +204,16 @@
for (size_t i = 0; i < ids.size(); ++i) {
// Get class vs. interface and status flags.
- JDWP::JdwpTypeTag typeTag;
- uint32_t status;
- if (!Dbg::GetClassInfo(ids[i], &typeTag, &status, NULL)) {
- return ERR_INVALID_CLASS;
+ JDWP::JdwpTypeTag type_tag;
+ uint32_t class_status;
+ JDWP::JdwpError status = Dbg::GetClassInfo(ids[i], &type_tag, &class_status, NULL);
+ if (status != ERR_NONE) {
+ return status;
}
- expandBufAdd1(pReply, typeTag);
+ expandBufAdd1(pReply, type_tag);
expandBufAddRefTypeId(pReply, ids[i]);
- expandBufAdd4BE(pReply, status);
+ expandBufAdd4BE(pReply, class_status);
}
return ERR_NONE;
@@ -419,21 +420,22 @@
for (size_t i = 0; i < classes.size(); ++i) {
static const char genericSignature[1] = "";
- JDWP::JdwpTypeTag refTypeTag;
+ JDWP::JdwpTypeTag type_tag;
std::string descriptor;
- uint32_t status;
- if (!Dbg::GetClassInfo(classes[i], &refTypeTag, &status, &descriptor)) {
- return ERR_INVALID_CLASS;
+ uint32_t class_status;
+ JDWP::JdwpError status = Dbg::GetClassInfo(classes[i], &type_tag, &class_status, &descriptor);
+ if (status != ERR_NONE) {
+ return status;
}
- expandBufAdd1(pReply, refTypeTag);
+ expandBufAdd1(pReply, type_tag);
expandBufAddRefTypeId(pReply, classes[i]);
if (descriptor_and_status) {
expandBufAddUtf8String(pReply, descriptor);
if (generic) {
expandBufAddUtf8String(pReply, genericSignature);
}
- expandBufAdd4BE(pReply, status);
+ expandBufAdd4BE(pReply, class_status);
}
}
@@ -468,17 +470,7 @@
static JdwpError handleRT_Modifiers(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
- uint32_t access_flags;
- if (!Dbg::GetAccessFlags(refTypeId, access_flags)) {
- return ERR_INVALID_CLASS;
- }
-
- // Set ACC_SUPER; dex files don't contain this flag, but all classes are supposed to have it set.
- // Class.getModifiers doesn't return it, but JDWP does, so we set it here.
- access_flags |= kAccSuper;
-
- expandBufAdd4BE(pReply, access_flags);
- return ERR_NONE;
+ return Dbg::GetModifiers(refTypeId, pReply);
}
/*
@@ -505,8 +497,9 @@
static JdwpError handleRT_SourceFile(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
std::string source_file;
- if (!Dbg::GetSourceFile(refTypeId, source_file)) {
- return ERR_ABSENT_INFORMATION;
+ JdwpError status = Dbg::GetSourceFile(refTypeId, source_file);
+ if (status != ERR_NONE) {
+ return status;
}
expandBufAddUtf8String(pReply, source_file);
return ERR_NONE;
@@ -517,12 +510,13 @@
*/
static JdwpError handleRT_Status(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
- JDWP::JdwpTypeTag typeTag;
- uint32_t status;
- if (!Dbg::GetClassInfo(refTypeId, &typeTag, &status, NULL)) {
- return ERR_INVALID_CLASS;
+ JDWP::JdwpTypeTag type_tag;
+ uint32_t class_status;
+ JDWP::JdwpError status = Dbg::GetClassInfo(refTypeId, &type_tag, &class_status, NULL);
+ if (status != ERR_NONE) {
+ return status;
}
- expandBufAdd4BE(pReply, status);
+ expandBufAdd4BE(pReply, class_status);
return ERR_NONE;
}
@@ -532,7 +526,7 @@
static JdwpError handleRT_Interfaces(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
VLOG(jdwp) << StringPrintf(" Req for interfaces in %llx (%s)", refTypeId, Dbg::GetClassName(refTypeId).c_str());
- return Dbg::OutputDeclaredInterfaces(refTypeId, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
+ return Dbg::OutputDeclaredInterfaces(refTypeId, pReply);
}
/*
@@ -541,8 +535,9 @@
static JdwpError handleRT_ClassObject(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
ObjectId classObjectId;
- if (!Dbg::GetClassObject(refTypeId, classObjectId)) {
- return ERR_INVALID_CLASS;
+ JdwpError status = Dbg::GetClassObject(refTypeId, classObjectId);
+ if (status != ERR_NONE) {
+ return status;
}
VLOG(jdwp) << StringPrintf(" RefTypeId %llx -> ObjectId %llx", refTypeId, classObjectId);
expandBufAddObjectId(pReply, classObjectId);
@@ -586,10 +581,7 @@
*/
static JdwpError handleRT_ClassLoader(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
-
- expandBufAddObjectId(pReply, Dbg::GetClassLoader(refTypeId));
-
- return ERR_NONE;
+ return Dbg::GetClassLoader(refTypeId, pReply);
}
static std::string Describe(const RefTypeId& refTypeId) {
@@ -605,14 +597,14 @@
static JdwpError handleRT_FieldsWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
VLOG(jdwp) << " Req for fields in " << Describe(refTypeId);
- return Dbg::OutputDeclaredFields(refTypeId, true, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
+ return Dbg::OutputDeclaredFields(refTypeId, true, pReply);
}
// Obsolete equivalent of FieldsWithGeneric, without the generic type information.
static JdwpError handleRT_Fields(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
VLOG(jdwp) << " Req for fields in " << Describe(refTypeId);
- return Dbg::OutputDeclaredFields(refTypeId, false, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
+ return Dbg::OutputDeclaredFields(refTypeId, false, pReply);
}
/*
@@ -622,14 +614,14 @@
static JdwpError handleRT_MethodsWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
VLOG(jdwp) << " Req for methods in " << Describe(refTypeId);
- return Dbg::OutputDeclaredMethods(refTypeId, true, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
+ return Dbg::OutputDeclaredMethods(refTypeId, true, pReply);
}
// Obsolete equivalent of MethodsWithGeneric, without the generic type information.
static JdwpError handleRT_Methods(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
VLOG(jdwp) << " Req for methods in " << Describe(refTypeId);
- return Dbg::OutputDeclaredMethods(refTypeId, false, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
+ return Dbg::OutputDeclaredMethods(refTypeId, false, pReply);
}
/*
@@ -699,8 +691,9 @@
VLOG(jdwp) << "Creating instance of " << Dbg::GetClassName(classId);
ObjectId objectId;
- if (!Dbg::CreateObject(classId, objectId)) {
- return ERR_INVALID_CLASS;
+ JdwpError status = Dbg::CreateObject(classId, objectId);
+ if (status != ERR_NONE) {
+ return status;
}
if (objectId == 0) {
return ERR_OUT_OF_MEMORY;
@@ -717,8 +710,9 @@
VLOG(jdwp) << "Creating array " << Dbg::GetClassName(arrayTypeId) << "[" << length << "]";
ObjectId objectId;
- if (!Dbg::CreateArrayObject(arrayTypeId, length, objectId)) {
- return ERR_INVALID_CLASS;
+ JdwpError status = Dbg::CreateArrayObject(arrayTypeId, length, objectId);
+ if (status != ERR_NONE) {
+ return status;
}
if (objectId == 0) {
return ERR_OUT_OF_MEMORY;
@@ -1440,18 +1434,8 @@
*/
static JdwpError handleCOR_ReflectedType(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId classObjectId = ReadRefTypeId(&buf);
-
VLOG(jdwp) << StringPrintf(" Req for refTypeId for class=%llx (%s)", classObjectId, Dbg::GetClassName(classObjectId).c_str());
-
- bool is_interface;
- if (!Dbg::IsInterface(classObjectId, is_interface)) {
- return ERR_INVALID_CLASS;
- }
-
- expandBufAdd1(pReply, is_interface ? TT_INTERFACE : TT_CLASS);
- expandBufAddRefTypeId(pReply, classObjectId);
-
- return ERR_NONE;
+ return Dbg::GetReflectedType(classObjectId, pReply);
}
/*