Fix a bug in Dbg::GetClassDescriptor.
The callers were incorrectly assuming we always returned a descriptor, which
isn't true when handed bad input.
Change-Id: I5509d18d8c234d97fa5ec2e0a01d4cdb44acfc55
diff --git a/src/debugger.cc b/src/debugger.cc
index cd1081d..662757d 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -499,12 +499,12 @@
}
}
-std::string Dbg::GetClassDescriptor(JDWP::RefTypeId classId) {
+std::string Dbg::GetClassName(JDWP::RefTypeId classId) {
Object* o = gRegistry->Get<Object*>(classId);
if (o == NULL || !o->IsClass()) {
return StringPrintf("non-class %p", o); // This is only used for debugging output anyway.
}
- return ClassHelper(o->AsClass()).GetDescriptor();
+ return DescriptorToName(ClassHelper(o->AsClass()).GetDescriptor());
}
bool Dbg::GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& classObjectId) {
diff --git a/src/debugger.h b/src/debugger.h
index 5089995..625f941 100644
--- a/src/debugger.h
+++ b/src/debugger.h
@@ -131,7 +131,7 @@
/*
* Class, Object, Array
*/
- static std::string GetClassDescriptor(JDWP::RefTypeId id);
+ static std::string GetClassName(JDWP::RefTypeId id);
static bool GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& classObjectId);
static JDWP::JdwpError GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId& superclassId);
static JDWP::ObjectId GetClassLoader(JDWP::RefTypeId id);
diff --git a/src/jdwp/jdwp_event.cc b/src/jdwp/jdwp_event.cc
index d68d011..b688993 100644
--- a/src/jdwp/jdwp_event.cc
+++ b/src/jdwp/jdwp_event.cc
@@ -726,7 +726,7 @@
basket.classId = pLoc->classId;
basket.thisPtr = thisPtr;
basket.threadId = Dbg::GetThreadSelfId();
- basket.className = DescriptorToName(Dbg::GetClassDescriptor(pLoc->classId).c_str());
+ basket.className = Dbg::GetClassName(pLoc->classId);
/*
* On rare occasions we may need to execute interpreted code in the VM
@@ -924,7 +924,7 @@
basket.pLoc = pThrowLoc;
basket.classId = pThrowLoc->classId;
basket.threadId = Dbg::GetThreadSelfId();
- basket.className = DescriptorToName(Dbg::GetClassDescriptor(basket.classId).c_str());
+ basket.className = Dbg::GetClassName(basket.classId);
basket.excepClassId = exceptionClassId;
basket.caught = (pCatchLoc->classId != 0);
basket.thisPtr = thisPtr;
@@ -1007,7 +1007,7 @@
memset(&basket, 0, sizeof(basket));
basket.classId = refTypeId;
basket.threadId = Dbg::GetThreadSelfId();
- basket.className = DescriptorToName(Dbg::GetClassDescriptor(basket.classId).c_str());
+ basket.className = Dbg::GetClassName(basket.classId);
/* suppress class prep caused by debugger */
if (InvokeInProgress()) {
diff --git a/src/jdwp/jdwp_handler.cc b/src/jdwp/jdwp_handler.cc
index d49454d..f17a4d8 100644
--- a/src/jdwp/jdwp_handler.cc
+++ b/src/jdwp/jdwp_handler.cc
@@ -109,7 +109,7 @@
uint32_t numArgs = Read4BE(&buf);
VLOG(jdwp) << StringPrintf(" --> threadId=%llx objectId=%llx", threadId, objectId);
- VLOG(jdwp) << StringPrintf(" classId=%llx methodId=%x %s.%s", classId, methodId, Dbg::GetClassDescriptor(classId).c_str(), Dbg::GetMethodName(classId, methodId).c_str());
+ VLOG(jdwp) << StringPrintf(" classId=%llx methodId=%x %s.%s", classId, methodId, Dbg::GetClassName(classId).c_str(), Dbg::GetMethodName(classId, methodId).c_str());
VLOG(jdwp) << StringPrintf(" %d args:", numArgs);
uint64_t* argArray = NULL;
@@ -531,7 +531,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::GetClassDescriptor(refTypeId).c_str());
+ 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;
}
@@ -697,7 +697,7 @@
ObjectId threadId = ReadObjectId(&buf);
MethodId methodId = ReadMethodId(&buf);
- VLOG(jdwp) << "Creating instance of " << Dbg::GetClassDescriptor(classId);
+ VLOG(jdwp) << "Creating instance of " << Dbg::GetClassName(classId);
ObjectId objectId;
if (!Dbg::CreateObject(classId, objectId)) {
return ERR_INVALID_CLASS;
@@ -715,7 +715,7 @@
RefTypeId arrayTypeId = ReadRefTypeId(&buf);
uint32_t length = Read4BE(&buf);
- VLOG(jdwp) << StringPrintf("Creating array %s[%u]", Dbg::GetClassDescriptor(arrayTypeId).c_str(), length);
+ VLOG(jdwp) << StringPrintf("Creating array %s[%u]", Dbg::GetClassName(arrayTypeId).c_str(), length);
ObjectId objectId;
if (!Dbg::CreateArrayObject(arrayTypeId, length, objectId)) {
return ERR_INVALID_CLASS;
@@ -735,7 +735,7 @@
RefTypeId refTypeId = ReadRefTypeId(&buf);
MethodId methodId = ReadMethodId(&buf);
- VLOG(jdwp) << StringPrintf(" Req for line table in %s.%s", Dbg::GetClassDescriptor(refTypeId).c_str(), Dbg::GetMethodName(refTypeId,methodId).c_str());
+ VLOG(jdwp) << StringPrintf(" Req for line table in %s.%s", Dbg::GetClassName(refTypeId).c_str(), Dbg::GetMethodName(refTypeId,methodId).c_str());
Dbg::OutputLineTable(refTypeId, methodId, pReply);
@@ -746,7 +746,7 @@
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());
+ VLOG(jdwp) << StringPrintf(" Req for LocalVarTab in class=%s method=%s", Dbg::GetClassName(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
@@ -1253,7 +1253,7 @@
case MK_CLASS_ONLY: /* for ClassPrepare, MethodEntry */
{
RefTypeId clazzId = ReadRefTypeId(&buf);
- VLOG(jdwp) << StringPrintf(" ClassOnly: %llx (%s)", clazzId, Dbg::GetClassDescriptor(clazzId).c_str());
+ VLOG(jdwp) << StringPrintf(" ClassOnly: %llx (%s)", clazzId, Dbg::GetClassName(clazzId).c_str());
pEvent->mods[idx].classOnly.refTypeId = clazzId;
}
break;
@@ -1294,7 +1294,7 @@
caught = Read1(&buf);
uncaught = Read1(&buf);
VLOG(jdwp) << StringPrintf(" ExceptionOnly: type=%llx(%s) caught=%d uncaught=%d",
- exceptionOrNull, (exceptionOrNull == 0) ? "null" : Dbg::GetClassDescriptor(exceptionOrNull).c_str(), caught, uncaught);
+ exceptionOrNull, (exceptionOrNull == 0) ? "null" : Dbg::GetClassName(exceptionOrNull).c_str(), caught, uncaught);
pEvent->mods[idx].exceptionOnly.refTypeId = exceptionOrNull;
pEvent->mods[idx].exceptionOnly.caught = caught;
@@ -1460,7 +1460,7 @@
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::GetClassDescriptor(classObjectId).c_str());
+ 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)) {
diff --git a/src/jdwp/jdwp_main.cc b/src/jdwp/jdwp_main.cc
index e408a76..a7e82aa 100644
--- a/src/jdwp/jdwp_main.cc
+++ b/src/jdwp/jdwp_main.cc
@@ -452,7 +452,7 @@
std::ostream& operator<<(std::ostream& os, const JdwpLocation& rhs) {
os << "JdwpLocation["
- << Dbg::GetClassDescriptor(rhs.classId) << "." << Dbg::GetMethodName(rhs.classId, rhs.methodId)
+ << Dbg::GetClassName(rhs.classId) << "." << Dbg::GetMethodName(rhs.classId, rhs.methodId)
<< "@" << rhs.idx << " " << rhs.typeTag << "]";
return os;
}
diff --git a/src/utils.cc b/src/utils.cc
index f599c0e..5348558 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -382,9 +382,9 @@
std::string DescriptorToName(const char* descriptor) {
size_t length = strlen(descriptor);
- DCHECK_GT(length, 0U);
- DCHECK_EQ(descriptor[0], 'L');
- DCHECK_EQ(descriptor[length - 1], ';');
+ CHECK_GT(length, 0U) << descriptor;
+ CHECK_EQ(descriptor[0], 'L') << descriptor;
+ CHECK_EQ(descriptor[length - 1], ';') << descriptor;
std::string result(descriptor + 1, length - 2);
return result;
}
@@ -787,7 +787,7 @@
std::string GetArtCacheFilenameOrDie(const std::string& location) {
std::string art_cache(GetArtCacheOrDie());
- CHECK_EQ(location[0], '/');
+ CHECK_EQ(location[0], '/') << location;
std::string cache_file(location, 1); // skip leading slash
std::replace(cache_file.begin(), cache_file.end(), '/', '@');
return art_cache + "/" + cache_file;