Skip to content

Commit

Permalink
Drop active statements when exiting break mode (dotnet#55773)
Browse files Browse the repository at this point in the history
* Drop active statements when exiting break mode
  • Loading branch information
tmat authored and CyrusNajmabadi committed Aug 24, 2021
1 parent 8524b2c commit a6ede13
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public async Task EnterBreakStateAsync(CancellationToken cancellationToken)

try
{
await session.BreakStateEnteredAsync(_diagnosticService, cancellationToken).ConfigureAwait(false);
await session.BreakStateChangedAsync(_diagnosticService, inBreakState: true, cancellationToken).ConfigureAwait(false);
}
catch (Exception e) when (FatalError.ReportAndCatchUnlessCanceled(e, cancellationToken))
{
Expand All @@ -135,16 +135,27 @@ public async Task EnterBreakStateAsync(CancellationToken cancellationToken)
await GetActiveStatementTrackingService().StartTrackingAsync(solution, session, cancellationToken).ConfigureAwait(false);
}

public Task ExitBreakStateAsync(CancellationToken cancellationToken)
public async Task ExitBreakStateAsync(CancellationToken cancellationToken)
{
GetDebuggingService().OnBeforeDebuggingStateChanged(DebuggingState.Break, DebuggingState.Run);

if (!_disabled)
if (_disabled)
{
GetActiveStatementTrackingService().EndTracking();
return;
}

return Task.CompletedTask;
var session = GetDebuggingSession();

try
{
await session.BreakStateChangedAsync(_diagnosticService, inBreakState: false, cancellationToken).ConfigureAwait(false);
GetActiveStatementTrackingService().EndTracking();
}
catch (Exception e) when (FatalError.ReportAndCatchUnlessCanceled(e, cancellationToken))
{
_disabled = true;
return;
}
}

public async Task CommitUpdatesAsync(CancellationToken cancellationToken)
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,15 @@ void VerifyReanalyzeInvocation(ImmutableArray<DocumentId> documentIds)

Contract.ThrowIfNull(sessionProxy);

// BreakStateEntered
// BreakStateChanged

mockEncService.BreakStateEnteredImpl = (out ImmutableArray<DocumentId> documentsToReanalyze) =>
mockEncService.BreakStateChangesImpl = (bool inBreakState, out ImmutableArray<DocumentId> documentsToReanalyze) =>
{
Assert.True(inBreakState);
documentsToReanalyze = ImmutableArray.Create(document.Id);
};

await sessionProxy.BreakStateEnteredAsync(mockDiagnosticService, CancellationToken.None).ConfigureAwait(false);
await sessionProxy.BreakStateChangedAsync(mockDiagnosticService, inBreakState: true, CancellationToken.None).ConfigureAwait(false);
VerifyReanalyzeInvocation(ImmutableArray.Create(document.Id));

var activeStatement = (await remoteDebuggeeModuleMetadataProvider!.GetActiveStatementsAsync(CancellationToken.None).ConfigureAwait(false)).Single();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

namespace Microsoft.CodeAnalysis.EditAndContinue.UnitTests
{
internal delegate void ActionOut<T>(out T arg);
internal delegate void ActionOut<TArg1>(out TArg1 arg);
internal delegate void ActionOut<TArg1, TArg2>(TArg1 arg1, out TArg2 arg2);

internal class MockEditAndContinueWorkspaceService : IEditAndContinueWorkspaceService
{
Expand All @@ -27,14 +28,14 @@ internal class MockEditAndContinueWorkspaceService : IEditAndContinueWorkspaceSe
public Func<Solution, ManagedInstructionId, bool?>? IsActiveStatementInExceptionRegionImpl;
public Action<Document>? OnSourceFileUpdatedImpl;
public ActionOut<ImmutableArray<DocumentId>>? CommitSolutionUpdateImpl;
public ActionOut<ImmutableArray<DocumentId>>? BreakStateEnteredImpl;
public ActionOut<bool, ImmutableArray<DocumentId>>? BreakStateChangesImpl;
public Action? DiscardSolutionUpdateImpl;
public Func<Document, ActiveStatementSpanProvider, ImmutableArray<Diagnostic>>? GetDocumentDiagnosticsImpl;

public void BreakStateEntered(DebuggingSessionId sessionId, out ImmutableArray<DocumentId> documentsToReanalyze)
public void BreakStateChanged(DebuggingSessionId sessionId, bool inBreakState, out ImmutableArray<DocumentId> documentsToReanalyze)
{
documentsToReanalyze = ImmutableArray<DocumentId>.Empty;
BreakStateEnteredImpl?.Invoke(out documentsToReanalyze);
BreakStateChangesImpl?.Invoke(inBreakState, out documentsToReanalyze);
}

public void CommitSolutionUpdate(DebuggingSessionId sessionId, out ImmutableArray<DocumentId> documentsToReanalyze)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ public void EndSession(out ImmutableArray<DocumentId> documentsToReanalyze, out
Dispose();
}

public void BreakStateEntered(out ImmutableArray<DocumentId> documentsToReanalyze)
=> RestartEditSession(nonRemappableRegions: null, inBreakState: true, out documentsToReanalyze);
public void BreakStateChanged(bool inBreakState, out ImmutableArray<DocumentId> documentsToReanalyze)
=> RestartEditSession(nonRemappableRegions: null, inBreakState, out documentsToReanalyze);

internal void RestartEditSession(ImmutableDictionary<ManagedMethodId, ImmutableArray<NonRemappableRegion>>? nonRemappableRegions, bool inBreakState, out ImmutableArray<DocumentId> documentsToReanalyze)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,11 @@ public void EndDebuggingSession(DebuggingSessionId sessionId, out ImmutableArray
debuggingSession.EndSession(out documentsToReanalyze, out var telemetryData);
}

public void BreakStateEntered(DebuggingSessionId sessionId, out ImmutableArray<DocumentId> documentsToReanalyze)
public void BreakStateChanged(DebuggingSessionId sessionId, bool inBreakState, out ImmutableArray<DocumentId> documentsToReanalyze)
{
var debuggingSession = TryGetDebuggingSession(sessionId);
Contract.ThrowIfNull(debuggingSession);
debuggingSession.BreakStateEntered(out documentsToReanalyze);
debuggingSession.BreakStateChanged(inBreakState, out documentsToReanalyze);
}

public ValueTask<ImmutableArray<Diagnostic>> GetDocumentDiagnosticsAsync(Document document, ActiveStatementSpanProvider activeStatementSpanProvider, CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ internal interface IEditAndContinueWorkspaceService : IWorkspaceService
void OnSourceFileUpdated(Document document);

ValueTask<DebuggingSessionId> StartDebuggingSessionAsync(Solution solution, IManagedEditAndContinueDebuggerService debuggerService, ImmutableArray<DocumentId> captureMatchingDocuments, bool captureAllMatchingDocuments, bool reportDiagnostics, CancellationToken cancellationToken);
void BreakStateEntered(DebuggingSessionId sessionId, out ImmutableArray<DocumentId> documentsToReanalyze);
void BreakStateChanged(DebuggingSessionId sessionId, bool inBreakState, out ImmutableArray<DocumentId> documentsToReanalyze);
void EndDebuggingSession(DebuggingSessionId sessionId, out ImmutableArray<DocumentId> documentsToReanalyze);

ValueTask<bool?> IsActiveStatementInExceptionRegionAsync(DebuggingSessionId sessionId, Solution solution, ManagedInstructionId instructionId, CancellationToken cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,12 @@ internal interface ICallback
/// <summary>
/// Returns ids of documents for which diagnostics need to be refreshed in-proc.
/// </summary>
ValueTask<ImmutableArray<DocumentId>> BreakStateEnteredAsync(DebuggingSessionId sessionId, CancellationToken cancellationToken);
ValueTask<ImmutableArray<DocumentId>> BreakStateChangedAsync(DebuggingSessionId sessionId, bool isBreakState, CancellationToken cancellationToken);

/// <summary>
/// Returns ids of documents for which diagnostics need to be refreshed in-proc.
/// </summary>
ValueTask<ImmutableArray<DocumentId>> EndDebuggingSessionAsync(DebuggingSessionId sessionId, CancellationToken cancellationToken);

ValueTask<ImmutableArray<ImmutableArray<ActiveStatementSpan>>> GetBaseActiveStatementSpansAsync(PinnedSolutionInfo solutionInfo, DebuggingSessionId sessionId, ImmutableArray<DocumentId> documentIds, CancellationToken cancellationToken);
ValueTask<ImmutableArray<ActiveStatementSpan>> GetAdjustedActiveStatementSpansAsync(PinnedSolutionInfo solutionInfo, RemoteServiceCallbackId callbackId, DebuggingSessionId sessionId, DocumentId documentId, CancellationToken cancellationToken);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,19 @@ public void Dispose()
private IEditAndContinueWorkspaceService GetLocalService()
=> _workspace.Services.GetRequiredService<IEditAndContinueWorkspaceService>();

public async ValueTask BreakStateEnteredAsync(IDiagnosticAnalyzerService diagnosticService, CancellationToken cancellationToken)
public async ValueTask BreakStateChangedAsync(IDiagnosticAnalyzerService diagnosticService, bool inBreakState, CancellationToken cancellationToken)
{
ImmutableArray<DocumentId> documentsToReanalyze;

var client = await RemoteHostClient.TryGetClientAsync(_workspace, cancellationToken).ConfigureAwait(false);
if (client == null)
{
GetLocalService().BreakStateEntered(_sessionId, out documentsToReanalyze);
GetLocalService().BreakStateChanged(_sessionId, inBreakState, out documentsToReanalyze);
}
else
{
var documentsToReanalyzeOpt = await client.TryInvokeAsync<IRemoteEditAndContinueService, ImmutableArray<DocumentId>>(
(service, cancallationToken) => service.BreakStateEnteredAsync(_sessionId, cancellationToken),
(service, cancallationToken) => service.BreakStateChangedAsync(_sessionId, inBreakState, cancellationToken),
cancellationToken).ConfigureAwait(false);

documentsToReanalyze = documentsToReanalyzeOpt.HasValue ? documentsToReanalyzeOpt.Value : ImmutableArray<DocumentId>.Empty;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Debugger.Contracts.EditAndContinue;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.EditAndContinue
{
Expand Down Expand Up @@ -81,11 +80,11 @@ public ValueTask<DebuggingSessionId> StartDebuggingSessionAsync(PinnedSolutionIn
/// <summary>
/// Remote API.
/// </summary>
public ValueTask<ImmutableArray<DocumentId>> BreakStateEnteredAsync(DebuggingSessionId sessionId, CancellationToken cancellationToken)
public ValueTask<ImmutableArray<DocumentId>> BreakStateChangedAsync(DebuggingSessionId sessionId, bool inBreakState, CancellationToken cancellationToken)
{
return RunServiceAsync(cancellationToken =>
{
GetService().BreakStateEntered(sessionId, out var documentsToReanalyze);
GetService().BreakStateChanged(sessionId, inBreakState, out var documentsToReanalyze);
return new ValueTask<ImmutableArray<DocumentId>>(documentsToReanalyze);
}, cancellationToken);
}
Expand Down

0 comments on commit a6ede13

Please sign in to comment.