summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
}