@@ -1121,16 +1121,6 @@ DebuggerController::DebuggerController(Thread * pThread, AppDomain * pAppDomain)
11211121    {
11221122        m_next = g_controllers;
11231123        g_controllers = this ;
1124- 
1125- #ifdef  OUT_OF_PROCESS_SETTHREADCONTEXT
1126-         if  (DebuggerController::GetProcessingDetach ())
1127-         {
1128-             //  If we are detaching, we need to increment the active dispatched exceptions
1129-             //  so that we can send the detach complete message when we are done.
1130-             int  cActiveDispatchedExceptions = DebuggerController::IncrementActiveDispatchedExceptions ();
1131-             LOG ((LF_CORDB, LL_INFO10000, " DC::DC %p incrementing ActiveDispatchedExceptions=%d\n "  , this , cActiveDispatchedExceptions));
1132-         }
1133- #endif  //  OUT_OF_PROCESS_SETTHREADCONTEXT
11341124    }
11351125}
11361126
@@ -1207,20 +1197,14 @@ DebuggerController::~DebuggerController()
12071197#ifdef  OUT_OF_PROCESS_SETTHREADCONTEXT
12081198        if  (DebuggerController::GetProcessingDetach ())
12091199        {
1210-             int  cActiveDispatchedExceptions = DebuggerController::DecrementActiveDispatchedExceptions ();
1211-             LOG ((LF_CORDB, LL_INFO10000, " DC::~DC %p decrementing ActiveDispatchedExceptions=%d\n "  , this , cActiveDispatchedExceptions));
1212- 
1213-             if  (cActiveDispatchedExceptions == 0 )
1214-             {
1215-                 DebuggerController::SetProcessingDetach (FALSE );
1216-                 sendDetachComplete = true ;
1217-             }
1200+             sendDetachComplete = CanSendDetach ();
12181201        }
12191202#endif  //  OUT_OF_PROCESS_SETTHREADCONTEXT
12201203    }
12211204#ifdef  OUT_OF_PROCESS_SETTHREADCONTEXT
12221205    if  (sendDetachComplete && g_pDebugger != NULL )
12231206    {
1207+         LOG ((LF_CORDB, LL_INFO1000, " DC::~DC: Sending DetachComplete\n "  ));
12241208        g_pDebugger->SendDetachComplete ();
12251209    }
12261210#endif 
@@ -3095,15 +3079,6 @@ DPOSS_ACTION DebuggerController::DispatchPatchOrSingleStep(Thread *thread, CONTE
30953079    }
30963080    _ASSERTE (g_patches != NULL );
30973081
3098- #ifdef  OUT_OF_PROCESS_SETTHREADCONTEXT
3099-     {
3100-         int  cDispatchedExceptions = DebuggerController::IncrementActiveDispatchedExceptions ();
3101-         LOG ((LF_CORDB|LF_ENC, LL_INFO10000, " DC::DPOSS Incremented Exception Count = %d\n "  , cDispatchedExceptions));
3102-     }
3103- 
3104-     bool  isProcessingDetach = DebuggerController::GetProcessingDetach ();
3105- #endif 
3106- 
31073082    CrstHolderWithState lockController (&g_criticalSection);
31083083
31093084    TADDR originalAddress = 0 ;
@@ -3169,15 +3144,6 @@ DPOSS_ACTION DebuggerController::DispatchPatchOrSingleStep(Thread *thread, CONTE
31693144    address = (CORDB_ADDRESS_TYPE *)(UINT_PTR)0xAABBCCFF ;
31703145#endif  // _DEBUG
31713146
3172- #ifdef  OUT_OF_PROCESS_SETTHREADCONTEXT
3173-     if  (DebuggerController::GetProcessingDetach () && IsInUsedAction (used))
3174-     {
3175-         int  cDispatchedFlares = DebuggerController::IncrementDispatchedFlares ();
3176-         isProcessingDetach = true ;
3177-         LOG ((LF_CORDB|LF_ENC, LL_INFO10000, " DC::DPOSS Incremented Flare Count = %d\n "  , cDispatchedFlares));
3178-     }
3179- #endif  //  OUT_OF_PROCESS_SETTHREADCONTEXT
3180- 
31813147    if  (dcq.dcqGetCount ()> 0 )
31823148    {
31833149        lockController.Release ();
@@ -3278,14 +3244,6 @@ DPOSS_ACTION DebuggerController::DispatchPatchOrSingleStep(Thread *thread, CONTE
32783244
32793245    lockController.Release ();
32803246
3281- #ifdef  OUT_OF_PROCESS_SETTHREADCONTEXT
3282-     if  (DebuggerController::GetProcessingDetach () && IsInUsedAction (used) && !isProcessingDetach)
3283-     {
3284-         int  cDispatchedFlares = DebuggerController::IncrementDispatchedFlares ();
3285-         isProcessingDetach = true ;
3286-         LOG ((LF_CORDB|LF_ENC, LL_INFO10000, " DC::DPOSS Incremented Flare Count = %d\n "  , cDispatchedFlares));
3287-     }
3288- #endif  //  OUT_OF_PROCESS_SETTHREADCONTEXT
32893247
32903248    //  We pulse the GC mode here too cooperate w/ a thread trying to suspend the runtime. If we didn't pulse
32913249    //  the GC, the odds of catching this thread in interruptible code may be very small (since this filter
@@ -3312,43 +3270,6 @@ DPOSS_ACTION DebuggerController::DispatchPatchOrSingleStep(Thread *thread, CONTE
33123270
33133271    }
33143272
3315- #ifdef  OUT_OF_PROCESS_SETTHREADCONTEXT
3316-     if  (DebuggerController::GetProcessingDetach () && IsInUsedAction (used) && !isProcessingDetach)
3317-     {
3318-         int  cDispatchedFlares = DebuggerController::IncrementDispatchedFlares ();
3319-         isProcessingDetach = true ;
3320-         LOG ((LF_CORDB|LF_ENC, LL_INFO10000, " DC::DPOSS Incremented Flare Count = %d\n "  , cDispatchedFlares));
3321-     }
3322- 
3323-     if  (DebuggerController::GetProcessingDetach ())
3324-     {
3325-         lockController.Acquire ();
3326- 
3327-         int  cDispatchedExceptions = DebuggerController::DecrementActiveDispatchedExceptions ();
3328-         LOG ((LF_CORDB|LF_ENC, LL_INFO10000, " DC::DPOSS Decrement Exception Count = %d\n "  , cDispatchedExceptions));
3329- 
3330-         int  cDispatchedFlares = DebuggerController::GetDispatchedFlares ();
3331-         _ASSERTE (cDispatchedFlares >= 0 );
3332-         _ASSERTE (cDispatchedExceptions >= 0 );
3333- 
3334-         if  (cDispatchedExceptions == 0 )
3335-         {
3336-             DebuggerController::SetProcessingDetach (FALSE );
3337-             lockController.Release ();
3338- 
3339-             if  (g_pDebugger != NULL )
3340-             {
3341-                 g_pDebugger->SendDetachComplete ();
3342-             }
3343-         }
3344-     }
3345-     else 
3346-     {
3347-         int  cDispatchedExceptions = DebuggerController::DecrementActiveDispatchedExceptions ();
3348-         LOG ((LF_CORDB|LF_ENC, LL_INFO10000, " DC::DPOSS Decrement Exception Count = %d\n "  , cDispatchedExceptions));
3349-     }
3350- #endif 
3351- 
33523273    RETURN used;
33533274}
33543275
@@ -4463,26 +4384,43 @@ void DebuggerController::TriggerExternalMethodFixup(PCODE target)
44634384}
44644385
44654386#ifdef  OUT_OF_PROCESS_SETTHREADCONTEXT
4466- /* static */   int   DebuggerController::GetNumPendingControllers  ( )
4387+ bool   DebuggerController::CanSendDetach  ( bool   fDecrementActiveExceptions )
44674388{
4468-     CONTRACTL
4469-     {
4470-         NOTHROW;
4471-         GC_NOTRIGGER;
4472-     }
4473-     CONTRACTL_END;
4474-     
4475-     ControllerLockHolder lockController;
4476-     int  cTotalPendingControllers = 0 ;
4477- 
4478-     for  (DebuggerController* p = g_controllers; p != NULL ; p = p->m_next )
4389+     bool  fCanSendDetach  = g_pDebugInterface == NULL  || !g_pDebugInterface->IsOutOfProcessSetContextEnabled ();
4390+     if  (!fCanSendDetach )
44794391    {
4480-         cTotalPendingControllers++;
4392+         ControllerLockHolder lockController;
4393+         bool  fHasControllers  = (g_controllers != NULL );
4394+         int  cActiveDispatchedExceptions = fDecrementActiveExceptions  ? DebuggerController::DecrementActiveDispatchedExceptions () : DebuggerController::GetActiveDispatchedExceptions ();
4395+ #ifdef  _DEBUG
4396+         if  (fDecrementActiveExceptions )
4397+         {
4398+             LOG ((LF_CORDB, LL_INFO10000, " DC::CSD --active dispatched exceptions count = %d, HasControllers = %d\n "  , cActiveDispatchedExceptions, fHasControllers ));
4399+         }
4400+         else 
4401+         {
4402+             LOG ((LF_CORDB, LL_INFO10000, " DC::CSD active dispatched exceptions count = %d, HasControllers = %d\n "  , cActiveDispatchedExceptions, fHasControllers ));
4403+         }
4404+ #endif 
4405+         if  (!fHasControllers  && cActiveDispatchedExceptions == 0 )
4406+         {
4407+             //  No outstanding controllers or active dispatched exceptions, so it is safe to detach
4408+             DebuggerController::SetProcessingDetach (FALSE );
4409+             fCanSendDetach  = true ;
4410+             LOG ((LF_CORDB, LL_INFO10000, " DC::CSD Can Detach\n "  ));
4411+         }
4412+         else  if  (!DebuggerController::GetProcessingDetach ())
4413+         {
4414+             //  this will cause DC::DNE to respond to this IPC once the queue of pending controllers has been processed
4415+             DebuggerController::SetProcessingDetach (TRUE );
4416+             fCanSendDetach  = false ;
4417+             LOG ((LF_CORDB, LL_INFO10000, " DC::CSD Unable to Detach, need to drain existing controllers or exception processing\n "  ));
4418+         }
44814419    }
44824420
4483-     return  cTotalPendingControllers ;
4421+     return  fCanSendDetach ;
44844422}
4485- #endif 
4423+ #endif   //  OUT_OF_PROCESS_SETTHREADCONTEXT 
44864424
44874425#ifdef  _DEBUG
44884426//  See comment in DispatchNativeException
@@ -4583,16 +4521,6 @@ bool DebuggerController::DispatchNativeException(EXCEPTION_RECORD *pException,
45834521        return  FALSE ;
45844522    }
45854523
4586-     //  It's possible we're here without a debugger (since we have to call the
4587-     //  patch skippers). The Debugger may detach anytime,
4588-     //  so remember the attach state now.
4589- #ifdef  _DEBUG
4590-     bool  fWasAttached  = false ;
4591- #ifdef  DEBUGGING_SUPPORTED
4592-     fWasAttached  = (CORDebuggerAttached () != 0 );
4593- #endif  // DEBUGGING_SUPPORTED
4594- #endif  // _DEBUG
4595- 
45964524    {
45974525        //  If we're in cooperative mode, it's unsafe to do a GC until we've put a filter context in place.
45984526        GCX_NOTRIGGER ();
@@ -4632,6 +4560,15 @@ bool DebuggerController::DispatchNativeException(EXCEPTION_RECORD *pException,
46324560        //  Otherwise it is an error to nest at all
46334561        _ASSERTE (pOldContext == NULL );
46344562
4563+         
4564+ #ifdef  OUT_OF_PROCESS_SETTHREADCONTEXT
4565+         if  (g_pDebugInterface != NULL  && g_pDebugInterface->IsOutOfProcessSetContextEnabled ())
4566+         {
4567+             int  cActiveDispatchedExceptions = DebuggerController::IncrementActiveDispatchedExceptions ();
4568+             LOG ((LF_CORDB, LL_INFO10000, " DC::DNE ++active dispatched exceptions count = %d\n "  , cActiveDispatchedExceptions));
4569+         }
4570+ #endif  //  OUT_OF_PROCESS_SETTHREADCONTEXT
4571+ 
46354572        fDispatch  = DebuggerController::DispatchExceptionHook (pCurThread,
46364573                                                                   pContext,
46374574                                                                   pException);
@@ -4695,13 +4632,6 @@ bool DebuggerController::DispatchNativeException(EXCEPTION_RECORD *pException,
46954632#endif 
46964633                                                       );
46974634            LOG ((LF_CORDB, LL_EVERYTHING, " DC::DNE DispatchPatch call returned\n "  ));
4698- 
4699-             //  If we detached, we should remove all our breakpoints. So if we try
4700-             //  to handle this breakpoint, make sure that we're attached.
4701-             if  (IsInUsedAction (result) == true )
4702-             {
4703-                 _ASSERTE (fWasAttached );
4704-             }
47054635            break ;
47064636
47074637        case  EXCEPTION_SINGLE_STEP:
@@ -4759,6 +4689,31 @@ bool DebuggerController::DispatchNativeException(EXCEPTION_RECORD *pException,
47594689        pCurThread->ApplySingleStep (pContext);
47604690#endif  //  FEATURE_EMULATE_SINGLESTEP
47614691
4692+ #ifdef  OUT_OF_PROCESS_SETTHREADCONTEXT
4693+     {
4694+         if  (fDebuggers  && g_pDebugInterface != NULL  && g_pDebugInterface->IsOutOfProcessSetContextEnabled ())
4695+         {
4696+             int  cDispatchedFlares = DebuggerController::IncrementDispatchedFlares ();
4697+             LOG ((LF_CORDB, LL_INFO10000, " DC::DNE ++dispatched flare count = %d\n "  , cDispatchedFlares));
4698+         }
4699+ 
4700+         if  (DebuggerController::GetProcessingDetach ())
4701+         {
4702+             LOG ((LF_CORDB, LL_INFO10000, " DC::DNE, Processing Detach: calling CanSendDetach...\n "  ));
4703+             if  (DebuggerController::CanSendDetach (true ) && g_pDebugger != NULL )
4704+             {
4705+                 LOG ((LF_CORDB, LL_INFO10000, " DC::DNE, Detaching...\n "  ));
4706+                 g_pDebugger->SendDetachComplete ();
4707+             }
4708+         }
4709+         else  if  (g_pDebugInterface != NULL  && g_pDebugInterface->IsOutOfProcessSetContextEnabled ())
4710+         {
4711+             int  cActiveDispatchedExceptions = DebuggerController::DecrementActiveDispatchedExceptions ();
4712+             LOG ((LF_CORDB, LL_INFO10000, " DC::DNE, NOT processing Detach, --active dispatched exceptions: %d\n "  , cActiveDispatchedExceptions));
4713+         }
4714+     }
4715+ #endif  //  OUT_OF_PROCESS_SETTHREADCONTEXT
4716+ 
47624717    FireEtwDebugExceptionProcessingEnd ();
47634718
47644719    return  fDebuggers ;
@@ -4916,7 +4871,7 @@ bool DebuggerPatchSkip::DebuggerDetachClean()
49164871
49174872#ifdef  OUT_OF_PROCESS_SETTHREADCONTEXT
49184873    //  during detach we need to ensure the context is only being updated out of process
4919-     bool  bUsingOutOfProcEvents = g_pDebugInterface->IsOutOfProcessSetContextEnabled ();
4874+     bool  bUsingOutOfProcEvents = g_pDebugInterface !=  NULL  && g_pDebugInterface ->IsOutOfProcessSetContextEnabled ();
49204875    if  (bUsingOutOfProcEvents)
49214876    {
49224877        return  false ; //  return false so that we do not delete this controller
0 commit comments