OSDN Git Service

Fix a deadlock between debugger and GC.
authorHiroshi Yamauchi <yamauchi@google.com>
Tue, 19 Apr 2016 18:14:06 +0000 (11:14 -0700)
committerHiroshi Yamauchi <yamauchi@google.com>
Tue, 19 Apr 2016 18:17:09 +0000 (11:17 -0700)
Avoid a deadlock between GC and debugger's SuspendAllForDebugger where
GC gets suspended during GC.

Fix the jdwp tests with the CC collector, but the deadlock is NOT
specific to the CC collector.

Bug: 25800335
Bug: 12687968
Change-Id: I8f2869872bce4692d943020072e35ebf5a4e68a5

runtime/debugger.cc
runtime/gc/collector_type.h
runtime/gc/gc_cause.cc
runtime/gc/gc_cause.h

index d832552..55f68d3 100644 (file)
@@ -2362,6 +2362,10 @@ JDWP::ObjectId Dbg::GetThreadId(Thread* thread) {
 }
 
 void Dbg::SuspendVM() {
+  // Avoid a deadlock between GC and debugger where GC gets suspended during GC. b/25800335.
+  gc::ScopedGCCriticalSection gcs(Thread::Current(),
+                                  gc::kGcCauseDebugger,
+                                  gc::kCollectorTypeDebugger);
   Runtime::Current()->GetThreadList()->SuspendAllForDebugger();
 }
 
@@ -4101,6 +4105,8 @@ void Dbg::ExecuteMethodWithoutPendingException(ScopedObjectAccess& soa, DebugInv
   // Suspend other threads if the invoke is not single-threaded.
   if ((pReq->options & JDWP::INVOKE_SINGLE_THREADED) == 0) {
     ScopedThreadSuspension sts(soa.Self(), kWaitingForDebuggerSuspension);
+    // Avoid a deadlock between GC and debugger where GC gets suspended during GC. b/25800335.
+    gc::ScopedGCCriticalSection gcs(soa.Self(), gc::kGcCauseDebugger, gc::kCollectorTypeDebugger);
     VLOG(jdwp) << "      Suspending all threads";
     Runtime::Current()->GetThreadList()->SuspendAllForDebugger();
   }
index ae41226..4ffc8af 100644 (file)
@@ -44,6 +44,8 @@ enum CollectorType {
   kCollectorTypeInstrumentation,
   // Fake collector for adding or removing application image spaces.
   kCollectorTypeAddRemoveAppImageSpace,
+  // Fake collector used to implement exclusion between GC and debugger.
+  kCollectorTypeDebugger,
   // A homogeneous space compaction collector used in background transition
   // when both foreground and background collector are CMS.
   kCollectorTypeHomogeneousSpaceCompact,
index 679432b..18e5703 100644 (file)
@@ -35,6 +35,7 @@ const char* PrettyCause(GcCause cause) {
     case kGcCauseTrim: return "HeapTrim";
     case kGcCauseInstrumentation: return "Instrumentation";
     case kGcCauseAddRemoveAppImageSpace: return "AddRemoveAppImageSpace";
+    case kGcCauseDebugger: return "Debugger";
     default:
       LOG(FATAL) << "Unreachable";
       UNREACHABLE();
index c6b505c..ad67eb7 100644 (file)
@@ -43,6 +43,8 @@ enum GcCause {
   kGcCauseInstrumentation,
   // Not a real GC cause, used to add or remove app image spaces.
   kGcCauseAddRemoveAppImageSpace,
+  // Not a real GC cause, used to implement exclusion between GC and debugger.
+  kGcCauseDebugger,
   // GC triggered for background transition when both foreground and background collector are CMS.
   kGcCauseHomogeneousSpaceCompact,
 };