void IMDbgProcessController.Stop(CorThread activeThread, object stopReason) { if (process == null) throw new InvalidOperationException("Process controller is not active anymore"); if (needAsyncStopCall) { process.CorProcess.Stop(int.MaxValue); process.m_stopCount++; } eventArgs.Continue = false; // signal to CorLayer that we want to stop process.InternalSignalRuntimeIsStopped(activeThread, stopReason); customStopRequested = true; }
private void InternalSignalRuntimeIsStopped(CorThread activeThread, Object stopReason) { lock (this) { // we need to be very carefull here. Debugger API is not reentrant. // Normally this method is called only from callback to signal to main thread // that debuggee has stopped but there is one important exception -- async break. // When we do async-break we are calling AsyncStop() method from another thread, which // is calling InternalSignalRuntimeIsStopped. Therefore we can be running this function // from async-break thread and from managed callback thread. Because this method is // calling DebuggerAPI and functions there are not reentrant, bad thinkgs are happening. // . OriginalMDbgMessages.WriteLine("InternalSignalRuntimeIsStopped (" + stopReason + ")"); m_stopCount++; OriginalMDbgMessages.WriteLine("Increasing StopCount to " + m_stopCount + " (" + stopReason + ")"); m_stopReason = stopReason; if (activeThread != null) { if (!m_threadMgr.HaveActive || !m_processAttaching) { m_threadMgr.SetActiveThread(activeThread); } MDbgThread t = m_threadMgr.GetThreadFromThreadId(activeThread.Id); // now check if we are in a special seqence point -- if so than just do another step. try { MDbgSourcePosition sp = t.CurrentSourcePosition; if (sp != null && sp.IsSpecial && (stopReason is StepCompleteStopReason)) { // we want to perform antother step when we end-up in special seqence point // only if we are stopped because of StepComplete. If we are stopped for any other // reason (e.g. ExceptionThrown, we should not make any other steps since then we // would receive stop reason for StepComplete and not for ExceptionThrown). OriginalMDbgMessages.WriteLine("Making another step because of special line number (0xfeefee)"); StepImpl(false, false); return; // we will be called again } } catch (MDbgNoCurrentFrameException) { // if we don't have current frame, let's ignore it. } } else { m_threadMgr.SetActiveThread(null); } if (IsAlive) m_engine.Processes.Active = this; OriginalMDbgMessages.WriteLine("Signaling Real Stop (" + stopReason + ")"); m_processAttaching = false; Thread.Sleep(100); // we are not interested in completing step if (m_activeStepper != null) try { m_activeStepper.Deactivate(); } catch (COMException) { // let's ignore if we cannot deactivate the stepper // This can happen in cases where the app finishes // (we receive ExitProcess callback) but we have outstanding // stepper. } m_stopCounter = g_stopCounter++; m_stopEvent.Set(); } }