diff options
| author | Andy McFadden <fadden@android.com> | 2009-10-13 16:04:31 -0700 |
|---|---|---|
| committer | Andy McFadden <fadden@android.com> | 2009-10-13 16:04:31 -0700 |
| commit | 0d6fff2da41e53c3ee790f352a40e84ad782d286 (patch) | |
| tree | fbfdcd5bf977247a1e1720ef596ed3c7bfbe0840 /vm/Debugger.c | |
| parent | 6ff3c8fde9623dadad726dbd5e1658585c321751 (diff) | |
| download | android_dalvik-0d6fff2da41e53c3ee790f352a40e84ad782d286.tar.gz android_dalvik-0d6fff2da41e53c3ee790f352a40e84ad782d286.tar.bz2 android_dalvik-0d6fff2da41e53c3ee790f352a40e84ad782d286.zip | |
Avoid JDWP hang on nested thread suspension.
With jdb, you can suspend a thread multiple times. If you try to
execute a method -- which requires resuming a thread that has been
stopped at a breakpoint -- the VM currently only does a single "resume",
which means the thread is still suspended, and the JDWP thread hangs
waiting for it.
This adds a check to prevent the hang.
For bug 2183735.
Diffstat (limited to 'vm/Debugger.c')
| -rw-r--r-- | vm/Debugger.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/vm/Debugger.c b/vm/Debugger.c index 86adbb671..eec8176cc 100644 --- a/vm/Debugger.c +++ b/vm/Debugger.c @@ -2698,6 +2698,30 @@ JdwpError dvmDbgInvokeMethod(ObjectId threadId, ObjectId objectId, } /* + * We currently have a bug where we don't successfully resume the + * target thread if the suspend count is too deep. We're expected to + * require one "resume" for each "suspend", but when asked to execute + * a method we have to resume fully and then re-suspend it back to the + * same level. (The easiest way to cause this is to type "suspend" + * multiple times in jdb.) + * + * It's unclear what this means when the event specifies "resume all" + * and some threads are suspended more deeply than others. This is + * a rare problem, so for now we just prevent it from hanging forever + * by rejecting the method invocation request. Without this, we will + * be stuck waiting on a suspended thread. + */ + if (targetThread->suspendCount > 1) { + LOGW("threadid=%d: suspend count on threadid=%d is %d, too deep " + "for method exec\n", + dvmThreadSelf()->threadId, targetThread->threadId, + targetThread->suspendCount); + err = ERR_THREAD_SUSPENDED; /* probably not expected here */ + dvmUnlockThreadList(); + goto bail; + } + + /* * TODO: ought to screen the various IDs, and verify that the argument * list is valid. */ |
