diff options
| author | 2013-01-04 17:05:30 -0800 | |
|---|---|---|
| committer | 2013-01-04 17:36:24 -0800 | |
| commit | e5fe0f7c3e859a90bf1ed5bd24ce8fbb3027b81c (patch) | |
| tree | 4f675dae88f8e50d72edcc02aadedbbf4d826510 /src | |
| parent | 6641ea12b98dda9ec45d29f20e43f85698b88a02 (diff) | |
Fix debugger to properly return TS_SLEEPING.
Thread.sleep is implemented with Object.wait, so the code can't
distinguish the two. I added a check to see if Thread.sleep
is somewhere on the stack, indicating that the thread is actually
sleeping instead of waiting.
Change-Id: I288befc1b3dc76e30c0620ab9c850c66b81c7a6d
Diffstat (limited to 'src')
| -rw-r--r-- | src/debugger.cc | 30 |
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; |