Fix a bunch of JDWP bugs.
Most of these were broken in dalvikvm too.
Bug: http://code.google.com/p/android/issues/detail?id=20856
Change-Id: I88bc89e00a19edc21953cd4f42833f35bb5456a8
diff --git a/src/jdwp/jdwp_handler.cc b/src/jdwp/jdwp_handler.cc
index aabdcb8..5e4487c 100644
--- a/src/jdwp/jdwp_handler.cc
+++ b/src/jdwp/jdwp_handler.cc
@@ -630,8 +630,9 @@
static JdwpError handleCT_Superclass(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId classId = ReadRefTypeId(&buf);
RefTypeId superClassId;
- if (!Dbg::GetSuperclass(classId, superClassId)) {
- return ERR_INVALID_CLASS;
+ JdwpError status = Dbg::GetSuperclass(classId, superClassId);
+ if (status != ERR_NONE) {
+ return status;
}
expandBufAddRefTypeId(pReply, superClassId);
return ERR_NONE;
@@ -653,7 +654,10 @@
uint64_t value = jdwpReadValue(&buf, width);
VLOG(jdwp) << StringPrintf(" --> field=%x tag=%c -> %lld", fieldId, fieldTag, value);
- Dbg::SetStaticFieldValue(fieldId, value, width);
+ JdwpError status = Dbg::SetStaticFieldValue(fieldId, value, width);
+ if (status != ERR_NONE) {
+ return status;
+ }
}
return ERR_NONE;
@@ -730,26 +734,28 @@
return ERR_NONE;
}
-/*
- * Pull out the LocalVariableTable goodies.
- */
-static JdwpError handleM_VariableTableWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+static JdwpError handleM_VariableTable(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply, bool generic) {
RefTypeId classId = ReadRefTypeId(&buf);
MethodId methodId = ReadMethodId(&buf);
VLOG(jdwp) << StringPrintf(" Req for LocalVarTab in class=%s method=%s", Dbg::GetClassDescriptor(classId).c_str(), Dbg::GetMethodName(classId, methodId).c_str());
- /*
- * We could return ERR_ABSENT_INFORMATION here if the DEX file was
- * built without local variable information. That will cause Eclipse
- * to make a best-effort attempt at displaying local variables
- * anonymously. However, the attempt isn't very good, so we're probably
- * better off just not showing anything.
- */
- Dbg::OutputVariableTable(classId, methodId, true, pReply);
+ // We could return ERR_ABSENT_INFORMATION here if the DEX file was built without local variable
+ // information. That will cause Eclipse to make a best-effort attempt at displaying local
+ // variables anonymously. However, the attempt isn't very good, so we're probably better off just
+ // not showing anything.
+ Dbg::OutputVariableTable(classId, methodId, generic, pReply);
return ERR_NONE;
}
+static JdwpError handleM_VariableTable(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+ return handleM_VariableTable(state, buf, dataLen, pReply, false);
+}
+
+static JdwpError handleM_VariableTableWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+ return handleM_VariableTable(state, buf, dataLen, pReply, true);
+}
+
/*
* Given an object reference, return the runtime type of the object
* (class or array).
@@ -1133,11 +1139,14 @@
ObjectId arrayId = ReadObjectId(&buf);
VLOG(jdwp) << StringPrintf(" Req for length of array 0x%llx", arrayId);
- uint32_t arrayLength = Dbg::GetArrayLength(arrayId);
+ int length;
+ JdwpError status = Dbg::GetArrayLength(arrayId, length);
+ if (status != ERR_NONE) {
+ return status;
+ }
+ VLOG(jdwp) << StringPrintf(" --> %d", length);
- VLOG(jdwp) << StringPrintf(" --> %d", arrayLength);
-
- expandBufAdd4BE(pReply, arrayLength);
+ expandBufAdd4BE(pReply, length);
return ERR_NONE;
}
@@ -1149,18 +1158,9 @@
ObjectId arrayId = ReadObjectId(&buf);
uint32_t firstIndex = Read4BE(&buf);
uint32_t length = Read4BE(&buf);
+ VLOG(jdwp) << StringPrintf(" Req for array values 0x%llx first=%d len=%d", arrayId, firstIndex, length);
- uint8_t tag = Dbg::GetArrayElementTag(arrayId);
- VLOG(jdwp) << StringPrintf(" Req for array values 0x%llx first=%d len=%d (elem tag=%c)", arrayId, firstIndex, length, tag);
-
- expandBufAdd1(pReply, tag);
- expandBufAdd4BE(pReply, length);
-
- if (!Dbg::OutputArray(arrayId, firstIndex, length, pReply)) {
- return ERR_INVALID_LENGTH;
- }
-
- return ERR_NONE;
+ return Dbg::OutputArray(arrayId, firstIndex, length, pReply);
}
/*
@@ -1173,11 +1173,7 @@
VLOG(jdwp) << StringPrintf(" Req to set array values 0x%llx first=%d count=%d", arrayId, firstIndex, values);
- if (!Dbg::SetArrayElements(arrayId, firstIndex, values, buf)) {
- return ERR_INVALID_LENGTH;
- }
-
- return ERR_NONE;
+ return Dbg::SetArrayElements(arrayId, firstIndex, values, buf);
}
/*
@@ -1620,7 +1616,7 @@
/* Method command set (6) */
{ 6, 1, handleM_LineTable, "Method.LineTable" },
- { 6, 2, NULL, "Method.VariableTable" },
+ { 6, 2, handleM_VariableTable, "Method.VariableTable" },
{ 6, 3, NULL, "Method.Bytecodes" },
{ 6, 4, NULL, "Method.IsObsolete" },
{ 6, 5, handleM_VariableTableWithGeneric, "Method.VariableTableWithGeneric" },