internal void LogEditSession(EncDebuggingSessionInfo encDebuggingSessionInfo) { lock (_encEditSessionInfoGuard) { Debug.Assert(_encEditSessionInfo != null); encDebuggingSessionInfo.EndEditSession(_encEditSessionInfo); _encEditSessionInfo = null; } }
public int StopDebuggingPE() { try { log.Write("Exit Debug Mode: project '{0}'", _vsProject.DisplayName); Debug.Assert(s_breakStateEnteredProjects.Count == 0); // Clear the solution stored while projects were entering break mode. // It should be cleared as soon as all tracked projects enter the break mode // but if the entering break mode fails for some projects we should avoid leaking the solution. Debug.Assert(s_breakStateEntrySolution == null); s_breakStateEntrySolution = null; // EnC service is global (per solution), but the debugger calls this for each project. // Avoid ending the debug session if it has already been ended. if (_encService.DebuggingSession != null) { _encService.OnBeforeDebuggingStateChanged(DebuggingState.Run, DebuggingState.Design); _encService.EndDebuggingSession(); LogEncSession(); s_encDebuggingSessionInfo = null; s_readOnlyDocumentTracker.Dispose(); s_readOnlyDocumentTracker = null; } if (_metadata != null) { _metadata.Dispose(); _metadata = null; s_debugStateProjectCount--; } else { // an error might have been reported: _diagnosticProvider.ClearDiagnostics(_encService.DebuggingSession, _vsProject.VisualStudioWorkspace, EditAndContinueDiagnosticUpdateSource.DebuggerErrorId, _vsProject.Id, documentId: null); } _activeMethods = null; _exceptionRegions = null; _committedBaseline = null; _activeStatementIds = null; Debug.Assert((_pdbReaderObjAsStream == IntPtr.Zero) || (_pdbReader == null)); if (_pdbReader != null) { Marshal.ReleaseComObject(_pdbReader); _pdbReader = null; } // The HResult is ignored by the debugger. return VSConstants.S_OK; } catch (Exception e) when (FatalError.ReportWithoutCrash(e)) { return VSConstants.E_FAIL; } }
/// <summary> /// Invoked when the debugger transitions from Design mode to Run mode or Break mode. /// </summary> public int StartDebuggingPE() { try { log.Write("Enter Debug Mode: project '{0}'", _vsProject.DisplayName); // EnC service is global (per solution), but the debugger calls this for each project. // Avoid starting the debug session if it has already been started. if (_encService.DebuggingSession == null) { Debug.Assert(s_debugStateProjectCount == 0); Debug.Assert(s_breakStateProjectCount == 0); Debug.Assert(s_breakStateEnteredProjects.Count == 0); _encService.OnBeforeDebuggingStateChanged(DebuggingState.Design, DebuggingState.Run); _encService.StartDebuggingSession(_vsProject.VisualStudioWorkspace.CurrentSolution); s_encDebuggingSessionInfo = new EncDebuggingSessionInfo(); s_readOnlyDocumentTracker = new VsReadOnlyDocumentTracker(_encService, _editorAdaptersFactoryService, _vsProject); } string outputPath = _vsProject.TryGetObjOutputPath(); // The project doesn't produce a debuggable binary or we can't read it. // Continue on since the debugger ignores HResults and we need to handle subsequent calls. if (outputPath != null) { try { InjectFault_MvidRead(); _metadata = ModuleMetadata.CreateFromFile(outputPath); _metadata.GetModuleVersionId(); } catch (FileNotFoundException) { // If the project isn't referenced by the project being debugged it might not be built. // In that case EnC is never allowed for the project, and thus we can assume the project hasn't entered debug state. log.Write("StartDebuggingPE: '{0}' metadata file not found: '{1}'", _vsProject.DisplayName, outputPath); _metadata = null; } catch (Exception e) { log.Write("StartDebuggingPE: error reading MVID of '{0}' ('{1}'): {2}", _vsProject.DisplayName, outputPath, e.Message); _metadata = null; var descriptor = new DiagnosticDescriptor("Metadata", "Metadata", ServicesVSResources.ErrorWhileReading, DiagnosticCategory.EditAndContinue, DiagnosticSeverity.Error, isEnabledByDefault: true, customTags: DiagnosticCustomTags.EditAndContinue); _diagnosticProvider.ReportDiagnostics(_encService.DebuggingSession, EditAndContinueDiagnosticUpdateSource.DebuggerErrorId, _vsProject.Id, _encService.DebuggingSession.InitialSolution, new[] { Diagnostic.Create(descriptor, Location.None, outputPath, e.Message) }); } } else { log.Write("StartDebuggingPE: project has no output path '{0}'", _vsProject.DisplayName); _metadata = null; } if (_metadata != null) { // The debugger doesn't call EnterBreakStateOnPE for projects that don't have MVID. // However a project that's initially not loaded (but it might be in future) enters // both the debug and break states. s_debugStateProjectCount++; } _activeMethods = new HashSet<uint>(); _exceptionRegions = new List<VsExceptionRegion>(); _activeStatementIds = new Dictionary<uint, ActiveStatementId>(); // The HResult is ignored by the debugger. return VSConstants.S_OK; } catch (Exception e) when (FatalError.ReportWithoutCrash(e)) { return VSConstants.E_FAIL; } }
private static void CreateSessionKeyValue(Dictionary<string, object> map, int sessionId, EncDebuggingSessionInfo session) { map[SessionId] = sessionId; map[SessionCount] = session.EditSessions.Count; map[EmptySessionCount] = session.EmptyEditSessions; }
public static KeyValueLogMessage Create(int sessionId, EncDebuggingSessionInfo session) { return KeyValueLogMessage.Create(m => CreateSessionKeyValue(m, sessionId, session)); }
public int StopDebuggingPE() { try { log.Write("Exit Debug Mode: project '{0}'", _vsProject.DisplayName); Debug.Assert(s_breakStateEnteredProjects.Count == 0); // EnC service is global (per solution), but the debugger calls this for each project. // Avoid ending the debug session if it has already been ended. if (_encService.DebuggingSession != null) { _encService.EndDebuggingSession(); LogEncSession(); s_encDebuggingSessionInfo = null; s_readOnlyDocumentTracker.Dispose(); s_readOnlyDocumentTracker = null; } if (_metadata != null) { _metadata.Dispose(); _metadata = null; s_debugStateProjectCount--; } else { // an error might have been reported: _diagnosticProvider.ClearDiagnostics(_encService.DebuggingSession, _vsProject.VisualStudioWorkspace, EditAndContinueDiagnosticUpdateSource.DebuggerErrorId, _vsProject.Id, documentId: null); } _activeMethods = null; _exceptionRegions = null; _committedBaseline = null; _activeStatementIds = null; if (_pdbReaderObj != null) { Marshal.ReleaseComObject(_pdbReaderObj); _pdbReaderObj = null; } if (_pdbProvider != null) { _pdbProvider.Dispose(); _pdbProvider = null; } _pdbReader = null; // The HResult is ignored by the debugger. return VSConstants.S_OK; } catch (Exception e) when(FatalError.Report(e)) { throw ExceptionUtilities.Unreachable; } }