More debugger support.
This gets us as far as the first DDMS-specific message, which means
it's time to bring in a bunch more code.
Change-Id: I3f9d75706d5ddde0aa21fcca558132282b94eff4
diff --git a/src/debugger.cc b/src/debugger.cc
index 7c26bd0..7d6d344 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -18,8 +18,35 @@
#include <sys/uio.h>
+#include "thread_list.h"
+
namespace art {
+class ObjectRegistry {
+ public:
+ ObjectRegistry() : lock_("ObjectRegistry lock") {
+ }
+
+ JDWP::ObjectId Add(Object* o) {
+ if (o == NULL) {
+ return 0;
+ }
+ JDWP::ObjectId id = static_cast<JDWP::ObjectId>(reinterpret_cast<uintptr_t>(o));
+ MutexLock mu(lock_);
+ map_[id] = o;
+ return id;
+ }
+
+ bool Contains(JDWP::ObjectId id) {
+ MutexLock mu(lock_);
+ return map_.find(id) != map_.end();
+ }
+
+ private:
+ Mutex lock_;
+ std::map<JDWP::ObjectId, Object*> map_;
+};
+
// JDWP is allowed unless the Zygote forbids it.
static bool gJdwpAllowed = true;
@@ -34,6 +61,8 @@
static bool gDebuggerConnected; // debugger or DDMS is connected.
static bool gDebuggerActive; // debugger is making requests.
+static ObjectRegistry* gRegistry = NULL;
+
/*
* Handle one of the JDWP name/value pairs.
*
@@ -146,12 +175,16 @@
return;
}
+ CHECK(gRegistry == NULL);
+ gRegistry = new ObjectRegistry;
+
// Init JDWP if the debugger is enabled. This may connect out to a
// debugger, passively listen for a debugger, or block waiting for a
// debugger.
gJdwpState = JDWP::JdwpState::Create(&gJdwpOptions);
if (gJdwpState == NULL) {
LOG(WARNING) << "debugger thread failed to initialize";
+ return;
}
// If a debugger has already attached, send the "welcome" message.
@@ -166,6 +199,8 @@
void Dbg::StopJdwp() {
delete gJdwpState;
+ delete gRegistry;
+ gRegistry = NULL;
}
void Dbg::SetJdwpAllowed(bool allowed) {
@@ -173,8 +208,15 @@
}
DebugInvokeReq* Dbg::GetInvokeReq() {
- UNIMPLEMENTED(FATAL);
- return NULL;
+ return Thread::Current()->GetInvokeReq();
+}
+
+Thread* Dbg::GetDebugThread() {
+ return (gJdwpState != NULL) ? gJdwpState->GetDebugThread() : NULL;
+}
+
+void Dbg::ClearWaitForEventThread() {
+ gJdwpState->ClearWaitForEventThread();
}
void Dbg::Connected() {
@@ -472,16 +514,15 @@
}
JDWP::ObjectId Dbg::GetThreadSelfId() {
- UNIMPLEMENTED(FATAL);
- return 0;
+ return gRegistry->Add(Thread::Current()->GetPeer());
}
-void Dbg::SuspendVM(bool isEvent) {
- UNIMPLEMENTED(FATAL);
+void Dbg::SuspendVM() {
+ Runtime::Current()->GetThreadList()->SuspendAll(true);
}
void Dbg::ResumeVM() {
- UNIMPLEMENTED(FATAL);
+ Runtime::Current()->GetThreadList()->ResumeAll(true);
}
void Dbg::SuspendThread(JDWP::ObjectId threadId) {
@@ -493,7 +534,7 @@
}
void Dbg::SuspendSelf() {
- UNIMPLEMENTED(FATAL);
+ Runtime::Current()->GetThreadList()->SuspendSelfForDebugger();
}
bool Dbg::GetThisObject(JDWP::ObjectId threadId, JDWP::FrameId frameId, JDWP::ObjectId* pThisId) {