summaryrefslogtreecommitdiff
path: root/src/debugger.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/debugger.cc')
-rw-r--r--src/debugger.cc30
1 files changed, 28 insertions, 2 deletions
diff --git a/src/debugger.cc b/src/debugger.cc
index 77a9252120..158be0ba3c 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -1420,8 +1420,6 @@ bool Dbg::GetThreadStatus(JDWP::ObjectId threadId, JDWP::JdwpThreadStatus* pThre
MutexLock mu2(soa.Self(), *Locks::thread_suspend_count_lock_);
- // TODO: if we're in Thread.sleep(long), we should return TS_SLEEPING,
- // even if it's implemented using Object.wait(long).
switch (thread->GetState()) {
case kTerminated: *pThreadStatus = JDWP::TS_ZOMBIE; break;
case kRunnable: *pThreadStatus = JDWP::TS_RUNNING; break;
@@ -1444,6 +1442,34 @@ bool Dbg::GetThreadStatus(JDWP::ObjectId threadId, JDWP::JdwpThreadStatus* pThre
// Don't add a 'default' here so the compiler can spot incompatible enum changes.
}
+ if (thread->GetState() == kTimedWaiting) {
+ // Since Thread.sleep is implemented using Object.wait, see if Thread.sleep
+ // is on the stack and change state to TS_SLEEPING if it is.
+ struct SleepMethodVisitor : public StackVisitor {
+ SleepMethodVisitor(const ManagedStack* stack,
+ const std::deque<InstrumentationStackFrame>* instrumentation_stack)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ : StackVisitor(stack, instrumentation_stack, NULL), found_(false) {}
+
+ virtual bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ std::string name(PrettyMethod(GetMethod(), false));
+ if (name == "java.lang.Thread.sleep") {
+ found_ = true;
+ return false;
+ }
+ return true;
+ }
+
+ bool found_;
+ };
+
+ SleepMethodVisitor visitor(thread->GetManagedStack(), thread->GetInstrumentationStack());
+ visitor.WalkStack(false);
+ if (visitor.found_) {
+ *pThreadStatus = JDWP::TS_SLEEPING;
+ }
+ }
+
*pSuspendStatus = (thread->IsSuspended() ? JDWP::SUSPEND_STATUS_SUSPENDED : JDWP::SUSPEND_STATUS_NOT_SUSPENDED);
return true;