Fix a dalvik bug in reporting the local variable table.
This still doesn't completely fix things; I've added a TODO.
Change-Id: I5e4eefeeac1344f3d50532b7c143c6acd3214525
diff --git a/src/debugger.cc b/src/debugger.cc
index 37b02af..c95d64a 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -744,6 +744,10 @@
*
* So, we remap the item in slot 0 to 1000, and remap "this" to zero. On
* SF.GetValues / SF.SetValues we map them back.
+ *
+ * TODO: jdb uses the value to determine whether a variable is a local or an argument,
+ * by checking whether it's less than the number of arguments. To make that work, we'd
+ * have to "mangle" all the arguments to come first, not just the implicit argument 'this'.
*/
static uint16_t MangleSlot(uint16_t slot, const char* name) {
uint16_t newSlot = slot;
@@ -755,9 +759,6 @@
return newSlot;
}
-/*
- * Reverse Eclipse hack.
- */
static uint16_t DemangleSlot(uint16_t slot, Frame& f) {
if (slot == kEclipseWorkaroundSlot) {
return 0;
@@ -768,7 +769,7 @@
return slot;
}
-void Dbg::OutputDeclaredFields(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply) {
+void Dbg::OutputDeclaredFields(JDWP::RefTypeId refTypeId, bool with_generic, JDWP::ExpandBuf* pReply) {
Class* c = gRegistry->Get<Class*>(refTypeId);
CHECK(c != NULL);
@@ -783,7 +784,7 @@
expandBufAddFieldId(pReply, ToFieldId(f));
expandBufAddUtf8String(pReply, f->GetName()->ToModifiedUtf8().c_str());
expandBufAddUtf8String(pReply, f->GetTypeDescriptor());
- if (withGeneric) {
+ if (with_generic) {
static const char genericSignature[1] = "";
expandBufAddUtf8String(pReply, genericSignature);
}
@@ -791,7 +792,7 @@
}
}
-void Dbg::OutputDeclaredMethods(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply) {
+void Dbg::OutputDeclaredMethods(JDWP::RefTypeId refTypeId, bool with_generic, JDWP::ExpandBuf* pReply) {
Class* c = gRegistry->Get<Class*>(refTypeId);
CHECK(c != NULL);
@@ -806,7 +807,7 @@
expandBufAddMethodId(pReply, ToMethodId(m));
expandBufAddUtf8String(pReply, m->GetName()->ToModifiedUtf8().c_str());
expandBufAddUtf8String(pReply, m->GetSignature()->ToModifiedUtf8().c_str());
- if (withGeneric) {
+ if (with_generic) {
static const char genericSignature[1] = "";
expandBufAddUtf8String(pReply, genericSignature);
}
@@ -868,29 +869,29 @@
JDWP::Set4BE(expandBufGetBuffer(pReply) + numLinesOffset, context.numItems);
}
-void Dbg::OutputVariableTable(JDWP::RefTypeId refTypeId, JDWP::MethodId methodId, bool withGeneric, JDWP::ExpandBuf* pReply) {
+void Dbg::OutputVariableTable(JDWP::RefTypeId refTypeId, JDWP::MethodId methodId, bool with_generic, JDWP::ExpandBuf* pReply) {
struct DebugCallbackContext {
- int numItems;
JDWP::ExpandBuf* pReply;
- bool withGeneric;
+ size_t variable_count;
+ bool with_generic;
- static void Callback(void* context, uint16_t slot, uint32_t startAddress, uint32_t endAddress, const char *name, const char *descriptor, const char *signature) {
+ static void Callback(void* context, uint16_t slot, uint32_t startAddress, uint32_t endAddress, const char* name, const char* descriptor, const char* signature) {
DebugCallbackContext* pContext = reinterpret_cast<DebugCallbackContext*>(context);
- LOG(VERBOSE) << StringPrintf(" %2d: %d(%d) '%s' '%s' '%s' slot=%d", pContext->numItems, startAddress, endAddress - startAddress, name, descriptor, signature, slot);
+ LOG(VERBOSE) << StringPrintf(" %2d: %d(%d) '%s' '%s' '%s' slot=%d", pContext->variable_count, startAddress, endAddress - startAddress, name, descriptor, signature, slot);
slot = MangleSlot(slot, name);
expandBufAdd8BE(pContext->pReply, startAddress);
expandBufAddUtf8String(pContext->pReply, name);
expandBufAddUtf8String(pContext->pReply, descriptor);
- if (pContext->withGeneric) {
+ if (pContext->with_generic) {
expandBufAddUtf8String(pContext->pReply, signature);
}
expandBufAdd4BE(pContext->pReply, endAddress - startAddress);
expandBufAdd4BE(pContext->pReply, slot);
- pContext->numItems++;
+ ++pContext->variable_count;
}
};
@@ -899,20 +900,23 @@
const DexFile& dex_file = class_linker->FindDexFile(m->GetDeclaringClass()->GetDexCache());
const DexFile::CodeItem* code_item = dex_file.GetCodeItem(m->GetCodeItemOffset());
- expandBufAdd4BE(pReply, m->NumIns());
+ // arg_count considers doubles and longs to take 2 units.
+ // variable_count considers everything to take 1 unit.
+ std::string shorty(m->GetShorty()->ToModifiedUtf8());
+ expandBufAdd4BE(pReply, m->NumArgRegisters(shorty));
- // Add numLocals later
- size_t numLocalsOffset = expandBufGetLength(pReply);
+ // We don't know the total number of variables yet, so leave a blank and update it later.
+ size_t variable_count_offset = expandBufGetLength(pReply);
expandBufAdd4BE(pReply, 0);
DebugCallbackContext context;
- context.numItems = 0;
context.pReply = pReply;
- context.withGeneric = withGeneric;
+ context.variable_count = 0;
+ context.with_generic = with_generic;
dex_file.DecodeDebugInfo(code_item, m, NULL, DebugCallbackContext::Callback, &context);
- JDWP::Set4BE(expandBufGetBuffer(pReply) + numLocalsOffset, context.numItems);
+ JDWP::Set4BE(expandBufGetBuffer(pReply) + variable_count_offset, context.variable_count);
}
uint8_t Dbg::GetFieldBasicTag(JDWP::ObjectId objId, JDWP::FieldId fieldId) {