summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Elliott Hughes <enh@google.com> 2011-12-08 21:28:17 -0800
committer Elliott Hughes <enh@google.com> 2011-12-08 21:45:49 -0800
commit7b3cdfcca472b779cf8745fb8460935e56229f11 (patch)
treee74e88286c9f121ed1312faece45981ba4e0b14c
parent6f1dfe415019de95f0305de66b3afb40005fe382 (diff)
More JDWP robustness.
We pass a lot more JDWP tests with this (fewer total failures than dalvik, because although dalvik implements more requests, it assumes that the debuggers only send it valid input). I've also added some of the missing constants (there are tests of modifier 12, SourceNameMatch, which was added in Java 6). Change-Id: I502e87b50fb305c5c8b061421339c8ceab104640
-rw-r--r--jdwpspy/Net.cpp4
-rw-r--r--src/debugger.cc154
-rw-r--r--src/debugger.h33
-rw-r--r--src/hprof/hprof.cc12
-rw-r--r--src/hprof/hprof.h2
-rw-r--r--src/jdwp/jdwp_bits.h16
-rw-r--r--src/jdwp/jdwp_constants.cc47
-rw-r--r--src/jdwp/jdwp_constants.h15
-rw-r--r--src/jdwp/jdwp_event.cc6
-rw-r--r--src/jdwp/jdwp_event.h24
-rw-r--r--src/jdwp/jdwp_handler.cc164
-rw-r--r--src/object.h6
12 files changed, 270 insertions, 213 deletions
diff --git a/jdwpspy/Net.cpp b/jdwpspy/Net.cpp
index 54d77305ae..eea21c8564 100644
--- a/jdwpspy/Net.cpp
+++ b/jdwpspy/Net.cpp
@@ -230,7 +230,7 @@ void jdwpNetFree(NetState* netState); /* fwd */
NetState* jdwpNetStartup(unsigned short listenPort, const char* connectHost,
unsigned short connectPort)
{
- NetState* netState = (NetState*) malloc(sizeof(*netState));
+ NetState* netState = new NetState;
memset(netState, 0, sizeof(*netState));
netState->listenSock = -1;
netState->dbg.sock = netState->vm.sock = -1;
@@ -342,7 +342,7 @@ void jdwpNetFree(NetState* netState)
return;
jdwpNetShutdown(netState);
- free(netState);
+ delete netState;
}
/*
diff --git a/src/debugger.cc b/src/debugger.cc
index b2ea527dea..eede552e59 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -447,18 +447,29 @@ void Dbg::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
}
std::string Dbg::GetClassDescriptor(JDWP::RefTypeId classId) {
- Class* c = gRegistry->Get<Class*>(classId);
- return ClassHelper(c).GetDescriptor();
+ 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();
}
-JDWP::ObjectId Dbg::GetClassObject(JDWP::RefTypeId id) {
- UNIMPLEMENTED(FATAL);
- return 0;
+bool Dbg::GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& classObjectId) {
+ Object* o = gRegistry->Get<Object*>(id);
+ if (o == NULL || !o->IsClass()) {
+ return false;
+ }
+ classObjectId = gRegistry->Add(o);
+ return true;
}
-JDWP::RefTypeId Dbg::GetSuperclass(JDWP::RefTypeId id) {
- Class* c = gRegistry->Get<Class*>(id);
- return gRegistry->Add(c->GetSuperClass());
+bool Dbg::GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId& superclassId) {
+ Object* o = gRegistry->Get<Object*>(id);
+ if (o == NULL || !o->IsClass()) {
+ return false;
+ }
+ superclassId = gRegistry->Add(o->AsClass()->GetSuperClass());
+ return true;
}
JDWP::ObjectId Dbg::GetClassLoader(JDWP::RefTypeId id) {
@@ -466,21 +477,32 @@ JDWP::ObjectId Dbg::GetClassLoader(JDWP::RefTypeId id) {
return gRegistry->Add(o->GetClass()->GetClassLoader());
}
-uint32_t Dbg::GetAccessFlags(JDWP::RefTypeId id) {
- Class* c = gRegistry->Get<Class*>(id);
- return c->GetAccessFlags() & kAccJavaFlagsMask;
+bool Dbg::GetAccessFlags(JDWP::RefTypeId id, uint32_t& access_flags) {
+ Object* o = gRegistry->Get<Object*>(id);
+ if (o == NULL || !o->IsClass()) {
+ return false;
+ }
+ access_flags = o->AsClass()->GetAccessFlags() & kAccJavaFlagsMask;
+ return true;
}
-bool Dbg::IsInterface(JDWP::RefTypeId classId) {
- Class* c = gRegistry->Get<Class*>(classId);
- return c->IsInterface();
+bool Dbg::IsInterface(JDWP::RefTypeId classId, bool& is_interface) {
+ Object* o = gRegistry->Get<Object*>(classId);
+ if (o == NULL || !o->IsClass()) {
+ return false;
+ }
+ is_interface = o->AsClass()->IsInterface();
+ return true;
}
-void Dbg::GetClassList(uint32_t* pClassCount, JDWP::RefTypeId** pClasses) {
+void Dbg::GetClassList(std::vector<JDWP::RefTypeId>& classes) {
// Get the complete list of reference classes (i.e. all classes except
// the primitive types).
// Returns a newly-allocated buffer full of RefTypeId values.
struct ClassListCreator {
+ ClassListCreator(std::vector<JDWP::RefTypeId>& classes) : classes(classes) {
+ }
+
static bool Visit(Class* c, void* arg) {
return reinterpret_cast<ClassListCreator*>(arg)->Visit(c);
}
@@ -492,24 +514,24 @@ void Dbg::GetClassList(uint32_t* pClassCount, JDWP::RefTypeId** pClasses) {
return true;
}
- std::vector<JDWP::RefTypeId> classes;
+ std::vector<JDWP::RefTypeId>& classes;
};
- ClassListCreator clc;
+ ClassListCreator clc(classes);
Runtime::Current()->GetClassLinker()->VisitClasses(ClassListCreator::Visit, &clc);
- *pClassCount = clc.classes.size();
- *pClasses = new JDWP::RefTypeId[clc.classes.size()];
- for (size_t i = 0; i < clc.classes.size(); ++i) {
- (*pClasses)[i] = clc.classes[i];
- }
}
void Dbg::GetVisibleClassList(JDWP::ObjectId classLoaderId, uint32_t* pNumClasses, JDWP::RefTypeId** pClassRefBuf) {
UNIMPLEMENTED(FATAL);
}
-void Dbg::GetClassInfo(JDWP::RefTypeId classId, JDWP::JdwpTypeTag* pTypeTag, uint32_t* pStatus, std::string* pDescriptor) {
- Class* c = gRegistry->Get<Class*>(classId);
+bool Dbg::GetClassInfo(JDWP::RefTypeId classId, JDWP::JdwpTypeTag* pTypeTag, uint32_t* pStatus, std::string* pDescriptor) {
+ Object* o = gRegistry->Get<Object*>(classId);
+ if (o == NULL || !o->IsClass()) {
+ return false;
+ }
+
+ Class* c = o->AsClass();
if (c->IsArrayClass()) {
*pStatus = JDWP::CS_VERIFIED | JDWP::CS_PREPARED;
*pTypeTag = JDWP::TT_ARRAY;
@@ -525,9 +547,10 @@ void Dbg::GetClassInfo(JDWP::RefTypeId classId, JDWP::JdwpTypeTag* pTypeTag, uin
if (pDescriptor != NULL) {
*pDescriptor = ClassHelper(c).GetDescriptor();
}
+ return true;
}
-void Dbg::FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>& ids) {
+void Dbg::FindLoadedClassBySignature(const std::string& descriptor, std::vector<JDWP::RefTypeId>& ids) {
std::vector<Class*> classes;
Runtime::Current()->GetClassLinker()->LookupClasses(descriptor, classes);
ids.clear();
@@ -553,17 +576,22 @@ uint8_t Dbg::GetClassObjectType(JDWP::RefTypeId refTypeId) {
return 0;
}
-std::string Dbg::GetSignature(JDWP::RefTypeId refTypeId) {
- Class* c = gRegistry->Get<Class*>(refTypeId);
- CHECK(c != NULL);
- return ClassHelper(c).GetDescriptor();
+bool Dbg::GetSignature(JDWP::RefTypeId refTypeId, std::string& signature) {
+ Object* o = gRegistry->Get<Object*>(refTypeId);
+ if (o == NULL || !o->IsClass()) {
+ return false;
+ }
+ signature = ClassHelper(o->AsClass()).GetDescriptor();
+ return true;
}
bool Dbg::GetSourceFile(JDWP::RefTypeId refTypeId, std::string& result) {
- Class* c = gRegistry->Get<Class*>(refTypeId);
- CHECK(c != NULL);
- result = ClassHelper(c).GetSourceFile();
- return result == NULL;
+ Object* o = gRegistry->Get<Object*>(refTypeId);
+ if (o == NULL || !o->IsClass()) {
+ return false;
+ }
+ result = ClassHelper(o->AsClass()).GetSourceFile();
+ return result != NULL;
}
uint8_t Dbg::GetObjectTag(JDWP::ObjectId objectId) {
@@ -700,25 +728,33 @@ bool Dbg::SetArrayElements(JDWP::ObjectId arrayId, int offset, int count, const
return true;
}
-JDWP::ObjectId Dbg::CreateString(const char* str) {
- return gRegistry->Add(String::AllocFromModifiedUtf8(str));
+JDWP::ObjectId Dbg::CreateString(const std::string& str) {
+ return gRegistry->Add(String::AllocFromModifiedUtf8(str.c_str()));
}
-JDWP::ObjectId Dbg::CreateObject(JDWP::RefTypeId classId) {
- Class* c = gRegistry->Get<Class*>(classId);
- return gRegistry->Add(c->AllocObject());
+bool Dbg::CreateObject(JDWP::RefTypeId classId, JDWP::ObjectId& new_object) {
+ Object* o = gRegistry->Get<Object*>(classId);
+ if (o == NULL || !o->IsClass()) {
+ return false;
+ }
+ new_object = gRegistry->Add(o->AsClass()->AllocObject());
+ return true;
}
/*
* Used by Eclipse's "Display" view to evaluate "new byte[5]" to get "(byte[]) [0, 0, 0, 0, 0]".
*/
-JDWP::ObjectId Dbg::CreateArrayObject(JDWP::RefTypeId arrayTypeId, uint32_t length) {
- Class* array_class = gRegistry->Get<Class*>(arrayTypeId);
- CHECK(array_class->IsArrayClass()) << PrettyClass(array_class);
- return gRegistry->Add(Array::Alloc(array_class, length));
+bool Dbg::CreateArrayObject(JDWP::RefTypeId arrayTypeId, uint32_t length, JDWP::ObjectId& new_array) {
+ Object* o = gRegistry->Get<Object*>(arrayTypeId);
+ if (o == NULL || !o->IsClass()) {
+ return false;
+ }
+ new_array = gRegistry->Add(Array::Alloc(o->AsClass(), length));
+ return true;
}
bool Dbg::MatchType(JDWP::RefTypeId instClassId, JDWP::RefTypeId classId) {
+ // TODO: error handling if the RefTypeIds aren't actually Class*s.
return gRegistry->Get<Class*>(instClassId)->InstanceOf(gRegistry->Get<Class*>(classId));
}
@@ -815,10 +851,13 @@ static uint16_t DemangleSlot(uint16_t slot, Frame& f) {
return slot;
}
-void Dbg::OutputDeclaredFields(JDWP::RefTypeId refTypeId, bool with_generic, JDWP::ExpandBuf* pReply) {
- Class* c = gRegistry->Get<Class*>(refTypeId);
- CHECK(c != NULL);
+bool Dbg::OutputDeclaredFields(JDWP::RefTypeId refTypeId, bool with_generic, JDWP::ExpandBuf* pReply) {
+ Object* o = gRegistry->Get<Object*>(refTypeId);
+ if (o == NULL || !o->IsClass()) {
+ return false;
+ }
+ Class* c = o->AsClass();
size_t instance_field_count = c->NumInstanceFields();
size_t static_field_count = c->NumStaticFields();
@@ -836,12 +875,16 @@ void Dbg::OutputDeclaredFields(JDWP::RefTypeId refTypeId, bool with_generic, JDW
}
expandBufAdd4BE(pReply, MangleAccessFlags(f->GetAccessFlags()));
}
+ return true;
}
-void Dbg::OutputDeclaredMethods(JDWP::RefTypeId refTypeId, bool with_generic, JDWP::ExpandBuf* pReply) {
- Class* c = gRegistry->Get<Class*>(refTypeId);
- CHECK(c != NULL);
+bool Dbg::OutputDeclaredMethods(JDWP::RefTypeId refTypeId, bool with_generic, JDWP::ExpandBuf* pReply) {
+ Object* o = gRegistry->Get<Object*>(refTypeId);
+ if (o == NULL || !o->IsClass()) {
+ return false;
+ }
+ Class* c = o->AsClass();
size_t direct_method_count = c->NumDirectMethods();
size_t virtual_method_count = c->NumVirtualMethods();
@@ -859,17 +902,21 @@ void Dbg::OutputDeclaredMethods(JDWP::RefTypeId refTypeId, bool with_generic, JD
}
expandBufAdd4BE(pReply, MangleAccessFlags(m->GetAccessFlags()));
}
+ return true;
}
-void Dbg::OutputDeclaredInterfaces(JDWP::RefTypeId refTypeId, JDWP::ExpandBuf* pReply) {
- Class* c = gRegistry->Get<Class*>(refTypeId);
- CHECK(c != NULL);
- ClassHelper kh(c);
+bool Dbg::OutputDeclaredInterfaces(JDWP::RefTypeId refTypeId, JDWP::ExpandBuf* pReply) {
+ Object* o = gRegistry->Get<Object*>(refTypeId);
+ if (o == NULL || !o->IsClass()) {
+ return false;
+ }
+ ClassHelper kh(o->AsClass());
size_t interface_count = kh.NumInterfaces();
expandBufAdd4BE(pReply, interface_count);
for (size_t i = 0; i < interface_count; ++i) {
expandBufAddRefTypeId(pReply, gRegistry->Add(kh.GetInterface(i)));
}
+ return true;
}
void Dbg::OutputLineTable(JDWP::RefTypeId refTypeId, JDWP::MethodId methodId, JDWP::ExpandBuf* pReply) {
@@ -1621,11 +1668,12 @@ void Dbg::ExecuteMethod(DebugInvokeReq* pReq) {
// Translate the method through the vtable, unless the debugger wants to suppress it.
Method* m = pReq->method_;
+ LOG(VERBOSE) << "ExecuteMethod " << PrettyMethod(m);
if ((pReq->options_ & JDWP::INVOKE_NONVIRTUAL) == 0 && pReq->receiver_ != NULL) {
m = pReq->class_->FindVirtualMethodForVirtualOrInterface(pReq->method_);
+ LOG(VERBOSE) << "ExecuteMethod " << PrettyMethod(m);
}
CHECK(m != NULL);
- LOG(VERBOSE) << "ExecuteMethod " << PrettyMethod(m);
CHECK_EQ(sizeof(jvalue), sizeof(uint64_t));
diff --git a/src/debugger.h b/src/debugger.h
index 079863559b..bcc5d79523 100644
--- a/src/debugger.h
+++ b/src/debugger.h
@@ -37,7 +37,10 @@ struct Thread;
* Invoke-during-breakpoint support.
*/
struct DebugInvokeReq {
- DebugInvokeReq() : lock_("a DebugInvokeReq lock"), cond_("a DebugInvokeReq condition variable") {
+ DebugInvokeReq()
+ : invoke_needed_(false),
+ lock_("a DebugInvokeReq lock"),
+ cond_("a DebugInvokeReq condition variable") {
}
/* boolean; only set when we're in the tail end of an event handler */
@@ -126,18 +129,18 @@ public:
* Class, Object, Array
*/
static std::string GetClassDescriptor(JDWP::RefTypeId id);
- static JDWP::ObjectId GetClassObject(JDWP::RefTypeId id);
- static JDWP::RefTypeId GetSuperclass(JDWP::RefTypeId id);
+ static bool GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& classObjectId);
+ static bool GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId& superclassId);
static JDWP::ObjectId GetClassLoader(JDWP::RefTypeId id);
- static uint32_t GetAccessFlags(JDWP::RefTypeId id);
- static bool IsInterface(JDWP::RefTypeId id);
- static void GetClassList(uint32_t* pNumClasses, JDWP::RefTypeId** pClassRefBuf);
+ static bool GetAccessFlags(JDWP::RefTypeId id, uint32_t& access_flags);
+ static bool IsInterface(JDWP::RefTypeId classId, bool& is_interface);
+ static void GetClassList(std::vector<JDWP::RefTypeId>& classes);
static void GetVisibleClassList(JDWP::ObjectId classLoaderId, uint32_t* pNumClasses, JDWP::RefTypeId** pClassRefBuf);
- static void GetClassInfo(JDWP::RefTypeId classId, JDWP::JdwpTypeTag* pTypeTag, uint32_t* pStatus, std::string* pDescriptor);
- static void FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>& ids);
+ static bool GetClassInfo(JDWP::RefTypeId classId, JDWP::JdwpTypeTag* pTypeTag, uint32_t* pStatus, std::string* pDescriptor);
+ static void FindLoadedClassBySignature(const std::string& descriptor, std::vector<JDWP::RefTypeId>& ids);
static void GetObjectType(JDWP::ObjectId objectId, JDWP::JdwpTypeTag* pRefTypeTag, JDWP::RefTypeId* pRefTypeId);
static uint8_t GetClassObjectType(JDWP::RefTypeId refTypeId);
- static std::string GetSignature(JDWP::RefTypeId refTypeId);
+ static bool GetSignature(JDWP::RefTypeId refTypeId, std::string& signature);
static bool GetSourceFile(JDWP::RefTypeId refTypeId, std::string& source_file);
static uint8_t GetObjectTag(JDWP::ObjectId objectId);
static size_t GetTagWidth(JDWP::JdwpTag tag);
@@ -147,9 +150,9 @@ public:
static bool OutputArray(JDWP::ObjectId arrayId, int firstIndex, int count, JDWP::ExpandBuf* pReply);
static bool SetArrayElements(JDWP::ObjectId arrayId, int firstIndex, int count, const uint8_t* buf);
- static JDWP::ObjectId CreateString(const char* str);
- static JDWP::ObjectId CreateObject(JDWP::RefTypeId classId);
- static JDWP::ObjectId CreateArrayObject(JDWP::RefTypeId arrayTypeId, uint32_t length);
+ static JDWP::ObjectId CreateString(const std::string& str);
+ static bool CreateObject(JDWP::RefTypeId classId, JDWP::ObjectId& new_object);
+ static bool CreateArrayObject(JDWP::RefTypeId arrayTypeId, uint32_t length, JDWP::ObjectId& new_array);
static bool MatchType(JDWP::RefTypeId instClassId, JDWP::RefTypeId classId);
@@ -157,9 +160,9 @@ public:
* Method and Field
*/
static std::string GetMethodName(JDWP::RefTypeId refTypeId, JDWP::MethodId id);
- static void OutputDeclaredFields(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply);
- static void OutputDeclaredMethods(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply);
- static void OutputDeclaredInterfaces(JDWP::RefTypeId refTypeId, JDWP::ExpandBuf* pReply);
+ static bool OutputDeclaredFields(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply);
+ static bool OutputDeclaredMethods(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply);
+ static bool OutputDeclaredInterfaces(JDWP::RefTypeId refTypeId, JDWP::ExpandBuf* pReply);
static void OutputLineTable(JDWP::RefTypeId refTypeId, JDWP::MethodId methodId, JDWP::ExpandBuf* pReply);
static void OutputVariableTable(JDWP::RefTypeId refTypeId, JDWP::MethodId id, bool withGeneric, JDWP::ExpandBuf* pReply);
diff --git a/src/hprof/hprof.cc b/src/hprof/hprof.cc
index d2134e0148..8dadfdf14a 100644
--- a/src/hprof/hprof.cc
+++ b/src/hprof/hprof.cc
@@ -59,7 +59,7 @@ Hprof::Hprof(const char* outputFileName, int fd, bool writeHeader, bool directTo
current_heap_(HPROF_HEAP_DEFAULT),
objects_in_segment_(0),
direct_to_ddms_(0),
- file_name_(NULL),
+ file_name_(outputFileName),
file_data_ptr_(NULL),
file_data_size_(0),
mem_fp_(NULL),
@@ -76,7 +76,6 @@ Hprof::Hprof(const char* outputFileName, int fd, bool writeHeader, bool directTo
}
direct_to_ddms_ = directToDdms;
- file_name_ = strdup(outputFileName);
mem_fp_ = fp;
fd_ = fd;
@@ -535,11 +534,11 @@ bool Hprof::Finish() {
FlushCurrentRecord();
// create a new Hprof for the start of the file (as opposed to this, which is the tail)
- Hprof headCtx(file_name_, fd_, true, direct_to_ddms_);
+ Hprof headCtx(file_name_.c_str(), fd_, true, direct_to_ddms_);
headCtx.classes_ = classes_;
headCtx.strings_ = strings_;
- LOG(INFO) << StringPrintf("hprof: dumping heap strings to \"%s\".", file_name_);
+ LOG(INFO) << StringPrintf("hprof: dumping heap strings to \"%s\".", file_name_.c_str());
headCtx.DumpStrings();
headCtx.DumpClasses();
@@ -575,9 +574,9 @@ bool Hprof::Finish() {
// continue to fail-handler below
}
} else {
- outFd = open(file_name_, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ outFd = open(file_name_.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (outFd < 0) {
- LOG(ERROR) << StringPrintf("can't open %s: %s", headCtx.file_name_, strerror(errno));
+ LOG(ERROR) << StringPrintf("can't open %s: %s", headCtx.file_name_.c_str(), strerror(errno));
// continue to fail-handler below
}
}
@@ -607,7 +606,6 @@ Hprof::~Hprof() {
fclose(mem_fp_);
}
free(current_record_.body_);
- free(file_name_);
free(file_data_ptr_);
}
diff --git a/src/hprof/hprof.h b/src/hprof/hprof.h
index e999dced54..7c1180e3fe 100644
--- a/src/hprof/hprof.h
+++ b/src/hprof/hprof.h
@@ -212,7 +212,7 @@ class Hprof {
// Otherwise, "file_name_" must be valid, though if "fd" >= 0 it will
// only be used for debug messages.
bool direct_to_ddms_;
- char* file_name_;
+ std::string file_name_;
char* file_data_ptr_; // for open_memstream
size_t file_data_size_; // for open_memstream
FILE *mem_fp_;
diff --git a/src/jdwp/jdwp_bits.h b/src/jdwp/jdwp_bits.h
index 344d2de9f3..5536c52f69 100644
--- a/src/jdwp/jdwp_bits.h
+++ b/src/jdwp/jdwp_bits.h
@@ -67,19 +67,15 @@ static inline uint64_t Read8BE(unsigned char const** ppSrc) {
}
/*
- * Read a UTF-8 string into newly-allocated storage, and null-terminate it.
- *
- * Returns the string and its length. (The latter is probably unnecessary
- * for the way we're using UTF8.)
+ * Reads a UTF-8 string into a std::string.
*/
-static inline char* ReadNewUtf8String(unsigned char const** ppSrc, size_t* pLength) {
+static inline std::string ReadNewUtf8String(unsigned char const** ppSrc) {
uint32_t length = Read4BE(ppSrc);
- char* buf = (char*) malloc(length+1);
- memcpy(buf, *ppSrc, length);
- buf[length] = '\0';
+ std::string s;
+ s.resize(length);
+ memcpy(&s[0], *ppSrc, length);
(*ppSrc) += length;
- *pLength = length;
- return buf;
+ return s;
}
static inline void Append1BE(std::vector<uint8_t>& bytes, uint8_t value) {
diff --git a/src/jdwp/jdwp_constants.cc b/src/jdwp/jdwp_constants.cc
index 7110eed2ce..ab4e841f83 100644
--- a/src/jdwp/jdwp_constants.cc
+++ b/src/jdwp/jdwp_constants.cc
@@ -40,6 +40,8 @@ const char* ErrorStr(JdwpError error) {
return "THREAD_NOT_SUSPENDED";
case ERR_THREAD_SUSPENDED:
return "THREAD_SUSPENDED";
+ case ERR_THREAD_NOT_ALIVE:
+ return "THREAD_NOT_ALIVE";
case ERR_INVALID_OBJECT:
return "INVALID_OBJEC";
case ERR_INVALID_CLASS:
@@ -157,7 +159,7 @@ const char* EventKindStr(JdwpEventKind kind) {
case EK_EXCEPTION: return "EXCEPTION";
case EK_USER_DEFINED: return "USER_DEFINED";
case EK_THREAD_START: return "THREAD_START";
- /*case EK_THREAD_END: return "THREAD_END";*/
+ case EK_THREAD_DEATH: return "THREAD_DEATH";
case EK_CLASS_PREPARE: return "CLASS_PREPARE";
case EK_CLASS_UNLOAD: return "CLASS_UNLOAD";
case EK_CLASS_LOAD: return "CLASS_LOAD";
@@ -166,11 +168,14 @@ const char* EventKindStr(JdwpEventKind kind) {
case EK_EXCEPTION_CATCH: return "EXCEPTION_CATCH";
case EK_METHOD_ENTRY: return "METHOD_ENTRY";
case EK_METHOD_EXIT: return "METHOD_EXIT";
- case EK_VM_INIT: return "VM_INIT";
+ case EK_METHOD_EXIT_WITH_RETURN_VALUE: return "METHOD_EXIT_WITH_RETURN_VALUE";
+ case EK_MONITOR_CONTENDED_ENTER: return "MONITOR_CONTENDED_ENTER";
+ case EK_MONITOR_CONTENDED_ENTERED: return "MONITOR_CONTENDED_ENTERED";
+ case EK_MONITOR_WAIT: return "MONITOR_WAIT";
+ case EK_MONITOR_WAITED: return "MONITOR_WAITED";
+ case EK_VM_START: return "VM_START";
case EK_VM_DEATH: return "VM_DEATH";
case EK_VM_DISCONNECTED: return "VM_DISCONNECTED";
- /*case EK_VM_START: return "VM_START";*/
- case EK_THREAD_DEATH: return "THREAD_DEATH";
default: return "?UNKNOWN?";
}
}
@@ -179,24 +184,24 @@ std::ostream& operator<<(std::ostream& os, const JdwpEventKind& value) {
return os;
}
-const char* ModKindStr(JdwpModKind kind) {
- switch (kind) {
- case MK_COUNT: return "COUNT";
- case MK_CONDITIONAL: return "CONDITIONAL";
- case MK_THREAD_ONLY: return "THREAD_ONLY";
- case MK_CLASS_ONLY: return "CLASS_ONLY";
- case MK_CLASS_MATCH: return "CLASS_MATCH";
- case MK_CLASS_EXCLUDE: return "CLASS_EXCLUDE";
- case MK_LOCATION_ONLY: return "LOCATION_ONLY";
- case MK_EXCEPTION_ONLY: return "EXCEPTION_ONLY";
- case MK_FIELD_ONLY: return "FIELD_ONLY";
- case MK_STEP: return "STEP";
- case MK_INSTANCE_ONLY: return "INSTANCE_ONLY";
- default: return "?UNKNOWN?";
- }
-}
std::ostream& operator<<(std::ostream& os, const JdwpModKind& value) {
- os << ModKindStr(value);
+ switch (value) {
+ case MK_COUNT: os << "COUNT"; break;
+ case MK_CONDITIONAL: os << "CONDITIONAL"; break;
+ case MK_THREAD_ONLY: os << "THREAD_ONLY"; break;
+ case MK_CLASS_ONLY: os << "CLASS_ONLY"; break;
+ case MK_CLASS_MATCH: os << "CLASS_MATCH"; break;
+ case MK_CLASS_EXCLUDE: os << "CLASS_EXCLUDE"; break;
+ case MK_LOCATION_ONLY: os << "LOCATION_ONLY"; break;
+ case MK_EXCEPTION_ONLY: os << "EXCEPTION_ONLY"; break;
+ case MK_FIELD_ONLY: os << "FIELD_ONLY"; break;
+ case MK_STEP: os << "STEP"; break;
+ case MK_INSTANCE_ONLY: os << "INSTANCE_ONLY"; break;
+ case MK_SOURCE_NAME_MATCH: os << "SOURCE_NAME_MATCH"; break;
+ default:
+ os << "JdwpModKind[" << static_cast<int>(value) << "]";
+ break;
+ }
return os;
}
diff --git a/src/jdwp/jdwp_constants.h b/src/jdwp/jdwp_constants.h
index 6d550f2551..14dc6cfa6a 100644
--- a/src/jdwp/jdwp_constants.h
+++ b/src/jdwp/jdwp_constants.h
@@ -35,6 +35,7 @@ enum JdwpError {
ERR_INVALID_PRIORITY = 12,
ERR_THREAD_NOT_SUSPENDED = 13,
ERR_THREAD_SUSPENDED = 14,
+ ERR_THREAD_NOT_ALIVE = 15,
ERR_INVALID_OBJECT = 20,
ERR_INVALID_CLASS = 21,
ERR_CLASS_NOT_PREPARED = 22,
@@ -110,7 +111,7 @@ enum JdwpEventKind {
EK_EXCEPTION = 4,
EK_USER_DEFINED = 5,
EK_THREAD_START = 6,
- EK_THREAD_END = 7,
+ EK_THREAD_DEATH = 7, // Formerly known as THREAD_END.
EK_CLASS_PREPARE = 8,
EK_CLASS_UNLOAD = 9,
EK_CLASS_LOAD = 10,
@@ -119,11 +120,14 @@ enum JdwpEventKind {
EK_EXCEPTION_CATCH = 30,
EK_METHOD_ENTRY = 40,
EK_METHOD_EXIT = 41,
- EK_VM_INIT = 90,
+ EK_METHOD_EXIT_WITH_RETURN_VALUE = 42,
+ EK_MONITOR_CONTENDED_ENTER = 43,
+ EK_MONITOR_CONTENDED_ENTERED = 44,
+ EK_MONITOR_WAIT = 45,
+ EK_MONITOR_WAITED = 46,
+ EK_VM_START = 90, // Formerly known as VM_INIT.
EK_VM_DEATH = 99,
- EK_VM_DISCONNECTED = 100, /* "Never sent across JDWP */
- EK_VM_START = EK_VM_INIT,
- EK_THREAD_DEATH = EK_THREAD_END,
+ EK_VM_DISCONNECTED = 100, // "Never sent across JDWP".
};
std::ostream& operator<<(std::ostream& os, const JdwpEventKind& value);
@@ -142,6 +146,7 @@ enum JdwpModKind {
MK_FIELD_ONLY = 9,
MK_STEP = 10,
MK_INSTANCE_ONLY = 11,
+ MK_SOURCE_NAME_MATCH = 12, // Since Java 6.
};
std::ostream& operator<<(std::ostream& os, const JdwpModKind& value);
diff --git a/src/jdwp/jdwp_event.cc b/src/jdwp/jdwp_event.cc
index 22d3c248e5..a405c9b4ff 100644
--- a/src/jdwp/jdwp_event.cc
+++ b/src/jdwp/jdwp_event.cc
@@ -128,7 +128,7 @@ static void dumpEvent(const JdwpEvent* pEvent) {
for (int i = 0; i < pEvent->modCount; i++) {
const JdwpEventMod* pMod = &pEvent->mods[i];
- LOG(INFO) << " " << static_cast<JdwpModKind>(pMod->modKind);
+ LOG(INFO) << " " << pMod->modKind;
/* TODO - show details */
}
}
@@ -451,8 +451,7 @@ static bool ModsMatch(JdwpEvent* pEvent, ModBasket* basket) {
}
break;
default:
- LOG(ERROR) << "unhandled mod kind " << pMod->modKind;
- CHECK(false);
+ LOG(FATAL) << "unknown mod kind " << pMod->modKind;
break;
}
}
@@ -544,7 +543,6 @@ void JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspendPolicy) {
SetWaitForEventThread(Dbg::GetThreadSelfId());
/* leave pReq->invoke_needed_ raised so we can check reentrancy */
- LOG(VERBOSE) << "invoking method...";
Dbg::ExecuteMethod(pReq);
pReq->error = ERR_NONE;
diff --git a/src/jdwp/jdwp_event.h b/src/jdwp/jdwp_event.h
index 5f18595024..e8f633f2a5 100644
--- a/src/jdwp/jdwp_event.h
+++ b/src/jdwp/jdwp_event.h
@@ -30,54 +30,54 @@ namespace JDWP {
* Event modifiers. A JdwpEvent may have zero or more of these.
*/
union JdwpEventMod {
- uint8_t modKind; /* JdwpModKind */
+ JdwpModKind modKind;
struct {
- uint8_t modKind;
+ JdwpModKind modKind;
int count;
} count;
struct {
- uint8_t modKind;
+ JdwpModKind modKind;
uint32_t exprId;
} conditional;
struct {
- uint8_t modKind;
+ JdwpModKind modKind;
ObjectId threadId;
} threadOnly;
struct {
- uint8_t modKind;
+ JdwpModKind modKind;
RefTypeId refTypeId;
} classOnly;
struct {
- uint8_t modKind;
+ JdwpModKind modKind;
char* classPattern;
} classMatch;
struct {
- uint8_t modKind;
+ JdwpModKind modKind;
char* classPattern;
} classExclude;
struct {
- uint8_t modKind;
+ JdwpModKind modKind;
JdwpLocation loc;
} locationOnly;
struct {
- uint8_t modKind;
+ JdwpModKind modKind;
uint8_t caught;
uint8_t uncaught;
RefTypeId refTypeId;
} exceptionOnly;
struct {
- uint8_t modKind;
+ JdwpModKind modKind;
RefTypeId refTypeId;
FieldId fieldId;
} fieldOnly;
struct {
- uint8_t modKind;
+ JdwpModKind modKind;
ObjectId threadId;
int size; /* JdwpStepSize */
int depth; /* JdwpStepDepth */
} step;
struct {
- uint8_t modKind;
+ JdwpModKind modKind;
ObjectId objectId;
} instanceOnly;
};
diff --git a/src/jdwp/jdwp_handler.cc b/src/jdwp/jdwp_handler.cc
index a11c8056f9..9f23af1a62 100644
--- a/src/jdwp/jdwp_handler.cc
+++ b/src/jdwp/jdwp_handler.cc
@@ -194,8 +194,7 @@ static JdwpError handleVM_Version(JdwpState* state, const uint8_t* buf, int data
* been loaded by multiple class loaders.
*/
static JdwpError handleVM_ClassesBySignature(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
- size_t strLen;
- char* classDescriptor = ReadNewUtf8String(&buf, &strLen);
+ std::string classDescriptor(ReadNewUtf8String(&buf));
LOG(VERBOSE) << " Req for class by signature '" << classDescriptor << "'";
std::vector<RefTypeId> ids;
@@ -207,15 +206,15 @@ static JdwpError handleVM_ClassesBySignature(JdwpState* state, const uint8_t* bu
// Get class vs. interface and status flags.
JDWP::JdwpTypeTag typeTag;
uint32_t status;
- Dbg::GetClassInfo(ids[i], &typeTag, &status, NULL);
+ if (!Dbg::GetClassInfo(ids[i], &typeTag, &status, NULL)) {
+ return ERR_INVALID_CLASS;
+ }
expandBufAdd1(pReply, typeTag);
expandBufAddRefTypeId(pReply, ids[i]);
expandBufAdd4BE(pReply, status);
}
- free(classDescriptor);
-
return ERR_NONE;
}
@@ -324,16 +323,12 @@ static JdwpError handleVM_Exit(JdwpState* state, const uint8_t* buf, int dataLen
* string "java.util.Arrays".)
*/
static JdwpError handleVM_CreateString(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
- size_t strLen;
- char* str = ReadNewUtf8String(&buf, &strLen);
-
+ std::string str(ReadNewUtf8String(&buf));
LOG(VERBOSE) << " Req to create string '" << str << "'";
-
ObjectId stringId = Dbg::CreateString(str);
if (stringId == 0) {
return ERR_OUT_OF_MEMORY;
}
-
expandBufAddObjectId(pReply, stringId);
return ERR_NONE;
}
@@ -425,30 +420,27 @@ static JdwpError handleVM_CapabilitiesNew(JdwpState* state, const uint8_t* buf,
* Cough up the complete list of classes.
*/
static JdwpError handleVM_AllClassesWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
- uint32_t numClasses = 0;
- RefTypeId* classRefBuf = NULL;
+ std::vector<JDWP::RefTypeId> classes;
+ Dbg::GetClassList(classes);
- Dbg::GetClassList(&numClasses, &classRefBuf);
+ expandBufAdd4BE(pReply, classes.size());
- expandBufAdd4BE(pReply, numClasses);
-
- for (uint32_t i = 0; i < numClasses; i++) {
+ for (size_t i = 0; i < classes.size(); ++i) {
static const char genericSignature[1] = "";
JDWP::JdwpTypeTag refTypeTag;
std::string descriptor;
uint32_t status;
-
- Dbg::GetClassInfo(classRefBuf[i], &refTypeTag, &status, &descriptor);
+ if (!Dbg::GetClassInfo(classes[i], &refTypeTag, &status, &descriptor)) {
+ return ERR_INVALID_CLASS;
+ }
expandBufAdd1(pReply, refTypeTag);
- expandBufAddRefTypeId(pReply, classRefBuf[i]);
+ expandBufAddRefTypeId(pReply, classes[i]);
expandBufAddUtf8String(pReply, descriptor);
expandBufAddUtf8String(pReply, genericSignature);
expandBufAdd4BE(pReply, status);
}
- free(classRefBuf);
-
return ERR_NONE;
}
@@ -460,9 +452,11 @@ static JdwpError handleRT_Signature(JdwpState* state, const uint8_t* buf, int da
RefTypeId refTypeId = ReadRefTypeId(&buf);
LOG(VERBOSE) << StringPrintf(" Req for signature of refTypeId=0x%llx", refTypeId);
- std::string signature(Dbg::GetSignature(refTypeId));
+ std::string signature;
+ if (!Dbg::GetSignature(refTypeId, signature)) {
+ return ERR_INVALID_CLASS;
+ }
expandBufAddUtf8String(pReply, signature);
-
return ERR_NONE;
}
@@ -471,8 +465,11 @@ static JdwpError handleRT_Signature(JdwpState* state, const uint8_t* buf, int da
*/
static JdwpError handleRT_Modifiers(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
- uint32_t modBits = Dbg::GetAccessFlags(refTypeId);
- expandBufAdd4BE(pReply, modBits);
+ uint32_t access_flags;
+ if (!Dbg::GetAccessFlags(refTypeId, access_flags)) {
+ return ERR_INVALID_CLASS;
+ }
+ expandBufAdd4BE(pReply, access_flags);
return ERR_NONE;
}
@@ -512,11 +509,11 @@ static JdwpError handleRT_SourceFile(JdwpState* state, const uint8_t* buf, int d
*/
static JdwpError handleRT_Status(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
-
- /* get status flags */
JDWP::JdwpTypeTag typeTag;
uint32_t status;
- Dbg::GetClassInfo(refTypeId, &typeTag, &status, NULL);
+ if (!Dbg::GetClassInfo(refTypeId, &typeTag, &status, NULL)) {
+ return ERR_INVALID_CLASS;
+ }
expandBufAdd4BE(pReply, status);
return ERR_NONE;
}
@@ -526,12 +523,8 @@ static JdwpError handleRT_Status(JdwpState* state, const uint8_t* buf, int dataL
*/
static JdwpError handleRT_Interfaces(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
-
LOG(VERBOSE) << StringPrintf(" Req for interfaces in %llx (%s)", refTypeId, Dbg::GetClassDescriptor(refTypeId).c_str());
-
- Dbg::OutputDeclaredInterfaces(refTypeId, pReply);
-
- return ERR_NONE;
+ return Dbg::OutputDeclaredInterfaces(refTypeId, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
}
/*
@@ -539,12 +532,12 @@ static JdwpError handleRT_Interfaces(JdwpState* state, const uint8_t* buf, int d
*/
static JdwpError handleRT_ClassObject(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
- ObjectId classObjId = Dbg::GetClassObject(refTypeId);
-
- LOG(VERBOSE) << StringPrintf(" RefTypeId %llx -> ObjectId %llx", refTypeId, classObjId);
-
- expandBufAddObjectId(pReply, classObjId);
-
+ ObjectId classObjectId;
+ if (!Dbg::GetClassObject(refTypeId, classObjectId)) {
+ return ERR_INVALID_CLASS;
+ }
+ LOG(VERBOSE) << StringPrintf(" RefTypeId %llx -> ObjectId %llx", refTypeId, classObjectId);
+ expandBufAddObjectId(pReply, classObjectId);
return ERR_NONE;
}
@@ -567,8 +560,8 @@ static JdwpError handleRT_SignatureWithGeneric(JdwpState* state, const uint8_t*
RefTypeId refTypeId = ReadRefTypeId(&buf);
LOG(VERBOSE) << StringPrintf(" Req for signature of refTypeId=0x%llx", refTypeId);
- std::string signature(Dbg::GetSignature(refTypeId));
- if (signature != NULL) {
+ std::string signature;
+ if (Dbg::GetSignature(refTypeId, signature)) {
expandBufAddUtf8String(pReply, signature);
} else {
LOG(WARNING) << StringPrintf("No signature for refTypeId=0x%llx", refTypeId);
@@ -591,16 +584,27 @@ static JdwpError handleRT_ClassLoader(JdwpState* state, const uint8_t* buf, int
return ERR_NONE;
}
+static std::string Describe(const RefTypeId& refTypeId) {
+ std::string signature("unknown");
+ Dbg::GetSignature(refTypeId, signature);
+ return StringPrintf("refTypeId=0x%llx (%s)", refTypeId, signature.c_str());
+}
+
/*
* Given a referenceTypeId, return a block of stuff that describes the
* fields declared by a class.
*/
static JdwpError handleRT_FieldsWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
- LOG(VERBOSE) << StringPrintf(" Req for fields in refTypeId=0x%llx", refTypeId);
- LOG(VERBOSE) << StringPrintf(" --> '%s'", Dbg::GetSignature(refTypeId).c_str());
- Dbg::OutputDeclaredFields(refTypeId, true, pReply);
- return ERR_NONE;
+ LOG(VERBOSE) << " Req for fields in " << Describe(refTypeId);
+ return Dbg::OutputDeclaredFields(refTypeId, true, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
+}
+
+// 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);
+ LOG(VERBOSE) << " Req for fields in " << Describe(refTypeId);
+ return Dbg::OutputDeclaredFields(refTypeId, false, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
}
/*
@@ -609,13 +613,15 @@ static JdwpError handleRT_FieldsWithGeneric(JdwpState* state, const uint8_t* buf
*/
static JdwpError handleRT_MethodsWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
+ LOG(VERBOSE) << " Req for methods in " << Describe(refTypeId);
+ return Dbg::OutputDeclaredMethods(refTypeId, true, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
+}
- LOG(VERBOSE) << StringPrintf(" Req for methods in refTypeId=0x%llx", refTypeId);
- LOG(VERBOSE) << StringPrintf(" --> '%s'", Dbg::GetSignature(refTypeId).c_str());
-
- Dbg::OutputDeclaredMethods(refTypeId, true, pReply);
-
- return ERR_NONE;
+// 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);
+ LOG(VERBOSE) << " Req for methods in " << Describe(refTypeId);
+ return Dbg::OutputDeclaredMethods(refTypeId, false, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
}
/*
@@ -623,11 +629,11 @@ static JdwpError handleRT_MethodsWithGeneric(JdwpState* state, const uint8_t* bu
*/
static JdwpError handleCT_Superclass(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId classId = ReadRefTypeId(&buf);
-
- RefTypeId superClassId = Dbg::GetSuperclass(classId);
-
+ RefTypeId superClassId;
+ if (!Dbg::GetSuperclass(classId, superClassId)) {
+ return ERR_INVALID_CLASS;
+ }
expandBufAddRefTypeId(pReply, superClassId);
-
return ERR_NONE;
}
@@ -680,7 +686,10 @@ static JdwpError handleCT_NewInstance(JdwpState* state, const uint8_t* buf, int
MethodId methodId = ReadMethodId(&buf);
LOG(VERBOSE) << "Creating instance of " << Dbg::GetClassDescriptor(classId);
- ObjectId objectId = Dbg::CreateObject(classId);
+ ObjectId objectId;
+ if (!Dbg::CreateObject(classId, objectId)) {
+ return ERR_INVALID_CLASS;
+ }
if (objectId == 0) {
return ERR_OUT_OF_MEMORY;
}
@@ -695,7 +704,10 @@ static JdwpError handleAT_newInstance(JdwpState* state, const uint8_t* buf, int
uint32_t length = Read4BE(&buf);
LOG(VERBOSE) << StringPrintf("Creating array %s[%u]", Dbg::GetClassDescriptor(arrayTypeId).c_str(), length);
- ObjectId objectId = Dbg::CreateArrayObject(arrayTypeId, length);
+ ObjectId objectId;
+ if (!Dbg::CreateArrayObject(arrayTypeId, length, objectId)) {
+ return ERR_INVALID_CLASS;
+ }
if (objectId == 0) {
return ERR_OUT_OF_MEMORY;
}
@@ -860,7 +872,7 @@ static JdwpError handleSR_Value(JdwpState* state, const uint8_t* buf, int dataLe
ObjectId stringObject = ReadObjectId(&buf);
std::string str(Dbg::StringToUtf8(stringObject));
- LOG(VERBOSE) << StringPrintf(" Req for str %llx --> '%s'", stringObject, str.c_str());
+ LOG(VERBOSE) << StringPrintf(" Req for str %llx --> '%s'", stringObject, PrintableString(str).c_str());
expandBufAddUtf8String(pReply, str);
@@ -1248,7 +1260,7 @@ static JdwpError handleER_Set(JdwpState* state, const uint8_t* buf, int dataLen,
* mods in JDWP doc).
*/
for (uint32_t idx = 0; idx < modifierCount; idx++) {
- uint8_t modKind = Read1(&buf);
+ JdwpModKind modKind = static_cast<JdwpModKind>(Read1(&buf));
pEvent->mods[idx].modKind = modKind;
@@ -1286,25 +1298,17 @@ static JdwpError handleER_Set(JdwpState* state, const uint8_t* buf, int dataLen,
break;
case MK_CLASS_MATCH: /* restrict events to matching classes */
{
- char* pattern;
- size_t strLen;
-
- pattern = ReadNewUtf8String(&buf, &strLen);
- LOG(VERBOSE) << StringPrintf(" ClassMatch: '%s'", pattern);
+ std::string pattern(ReadNewUtf8String(&buf));
+ LOG(VERBOSE) << StringPrintf(" ClassMatch: '%s'", pattern.c_str());
/* pattern is "java.foo.*", we want "java/foo/ *" */
- pEvent->mods[idx].classMatch.classPattern = dvmDotToSlash(pattern);
- free(pattern);
+ pEvent->mods[idx].classMatch.classPattern = dvmDotToSlash(pattern.c_str());
}
break;
case MK_CLASS_EXCLUDE: /* restrict events to non-matching classes */
{
- char* pattern;
- size_t strLen;
-
- pattern = ReadNewUtf8String(&buf, &strLen);
- LOG(VERBOSE) << StringPrintf(" ClassExclude: '%s'", pattern);
- pEvent->mods[idx].classExclude.classPattern = dvmDotToSlash(pattern);
- free(pattern);
+ std::string pattern(ReadNewUtf8String(&buf));
+ LOG(VERBOSE) << StringPrintf(" ClassExclude: '%s'", pattern.c_str());
+ pEvent->mods[idx].classExclude.classPattern = dvmDotToSlash(pattern.c_str());
}
break;
case MK_LOCATION_ONLY: /* restrict certain events based on loc */
@@ -1496,12 +1500,12 @@ static JdwpError handleCOR_ReflectedType(JdwpState* state, const uint8_t* buf, i
LOG(VERBOSE) << StringPrintf(" Req for refTypeId for class=%llx (%s)", classObjectId, Dbg::GetClassDescriptor(classObjectId).c_str());
- /* just hand the type back to them */
- if (Dbg::IsInterface(classObjectId)) {
- expandBufAdd1(pReply, TT_INTERFACE);
- } else {
- expandBufAdd1(pReply, TT_CLASS);
+ 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;
@@ -1587,8 +1591,8 @@ static const JdwpHandlerMap gHandlerMap[] = {
{ 2, 1, handleRT_Signature, "ReferenceType.Signature" },
{ 2, 2, handleRT_ClassLoader, "ReferenceType.ClassLoader" },
{ 2, 3, handleRT_Modifiers, "ReferenceType.Modifiers" },
- { 2, 4, NULL, "ReferenceType.Fields" },
- { 2, 5, NULL, "ReferenceType.Methods" },
+ { 2, 4, handleRT_Fields, "ReferenceType.Fields" },
+ { 2, 5, handleRT_Methods, "ReferenceType.Methods" },
{ 2, 6, handleRT_GetValues, "ReferenceType.GetValues" },
{ 2, 7, handleRT_SourceFile, "ReferenceType.SourceFile" },
{ 2, 8, NULL, "ReferenceType.NestedTypes" },
diff --git a/src/object.h b/src/object.h
index ddba9db290..eb379876e1 100644
--- a/src/object.h
+++ b/src/object.h
@@ -1370,7 +1370,7 @@ class MANAGED Class : public StaticStorageBase {
Class* GetSuperClass() const {
// Can only get super class for loaded classes (hack for when runtime is
// initializing)
- DCHECK(IsLoaded() || !Runtime::Current()->IsStarted());
+ DCHECK(IsLoaded() || !Runtime::Current()->IsStarted()) << IsLoaded();
return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_), false);
}
@@ -1908,8 +1908,8 @@ inline void Field::SetDeclaringClass(Class *new_declaring_class) {
inline Class* Method::GetDeclaringClass() const {
Class* result = GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Method, declaring_class_), false);
- DCHECK(result != NULL);
- DCHECK(result->IsIdxLoaded() || result->IsErroneous());
+ DCHECK(result != NULL) << this;
+ DCHECK(result->IsIdxLoaded() || result->IsErroneous()) << this;
return result;
}