Skip to content

Commit

Permalink
implement reverse execution
Browse files Browse the repository at this point in the history
send CapabilitiesEvent after target launch to correctly signal StepBack support
introduce IDebugReversibleEngineProgram160 to properly handle execution direction like VS
implement DAP step granularity
  • Loading branch information
Trass3r committed Aug 28, 2020
1 parent 4c21dbd commit 6c1d644
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 75 deletions.
33 changes: 24 additions & 9 deletions src/MICore/CommandFactories/MICommandFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using System.IO;
using System.Text;
using System.Collections.ObjectModel;
using System.Linq;
using System.Globalization;
using Microsoft.VisualStudio.Debugger.Interop;

namespace MICore
Expand Down Expand Up @@ -216,33 +213,43 @@ public async Task<ValueListValue> StackListVariables(PrintValues printValues, in

#region Program Execution

public async Task ExecStep(int threadId, ResultClass resultClass = ResultClass.running)
public async Task ExecStep(int threadId, bool forward = true, ResultClass resultClass = ResultClass.running)
{
string command = "-exec-step";
if (!forward)
command += " --reverse";
await ThreadFrameCmdAsync(command, resultClass, threadId, 0);
}

public async Task ExecNext(int threadId, ResultClass resultClass = ResultClass.running)
public async Task ExecNext(int threadId, bool forward = true, ResultClass resultClass = ResultClass.running)
{
string command = "-exec-next";
if (!forward)
command += " --reverse";
await ThreadFrameCmdAsync(command, resultClass, threadId, 0);
}

public async Task ExecFinish(int threadId, ResultClass resultClass = ResultClass.running)
public async Task ExecFinish(int threadId, bool forward = true, ResultClass resultClass = ResultClass.running)
{
string command = "-exec-finish";
if (!forward)
command += " --reverse";
await ThreadFrameCmdAsync(command, resultClass, threadId, 0);
}

public async Task ExecStepInstruction(int threadId, ResultClass resultClass = ResultClass.running)
public async Task ExecStepInstruction(int threadId, bool forward = true, ResultClass resultClass = ResultClass.running)
{
string command = "-exec-step-instruction";
if (!forward)
command += " --reverse";
await ThreadFrameCmdAsync(command, resultClass, threadId, 0);
}

public async Task ExecNextInstruction(int threadId, ResultClass resultClass = ResultClass.running)
public async Task ExecNextInstruction(int threadId, bool forward = true, ResultClass resultClass = ResultClass.running)
{
string command = "-exec-next-instruction";
if (!forward)
command += " --reverse";
await ThreadFrameCmdAsync(command, resultClass, threadId, 0);
}

Expand All @@ -258,9 +265,11 @@ public virtual async Task ExecRun()
/// <summary>
/// Continues running the target process
/// </summary>
public async Task ExecContinue()
public async Task ExecContinue(bool forward = true)
{
string command = "-exec-continue";
if (!forward)
command += " --reverse";
await _debugger.CmdAsync(command, ResultClass.running);
}

Expand Down Expand Up @@ -661,6 +670,12 @@ public virtual bool CanDetach()
return true;
}

public virtual async Task<string[]> GetTargetFeatures()
{
Results results = await _debugger.CmdAsync("-list-target-features", ResultClass.done);
return results.Find<ValueListValue>("features").AsStrings;
}

abstract public Task<List<ulong>> StartAddressesForLine(string file, uint line);

/// <summary>
Expand Down
24 changes: 18 additions & 6 deletions src/MIDebugEngine/AD7.Impl/AD7Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.ExceptionServices;
using Microsoft.VisualStudio.Debugger.Interop;
using Microsoft.VisualStudio.Debugger.Interop.UnixPortSupplier;
using System.Diagnostics;
Expand Down Expand Up @@ -35,7 +33,7 @@ namespace Microsoft.MIDebugEngine

[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.Guid("0fc2f352-2fc1-4f80-8736-51cd1ab28f16")]
sealed public class AD7Engine : IDebugEngine2, IDebugEngineLaunch2, IDebugEngine3, IDebugProgram3, IDebugEngineProgram2, IDebugMemoryBytes2, IDebugEngine110, IDebugProgramDAP, IDisposable
sealed public class AD7Engine : IDebugEngine2, IDebugEngineLaunch2, IDebugEngine3, IDebugProgram3, IDebugEngineProgram2, IDebugReversibleEngineProgram160, IDebugMemoryBytes2, IDebugEngine110, IDebugProgramDAP, IDisposable
{
// used to send events to the debugger. Some examples of these events are thread create, exception thrown, module load.
private EngineCallback _engineCallback;
Expand Down Expand Up @@ -176,6 +174,7 @@ internal bool ProgramCreateEventSent
get;
private set;
}
public ExecuteDirection ExecutionDirection { get; private set; }

public string GetAddressDescription(ulong ip)
{
Expand Down Expand Up @@ -800,11 +799,11 @@ public int Continue(IDebugThread2 pThread)
{
if (_pollThread.IsPollThread())
{
_debuggedProcess.Continue(thread?.GetDebuggedThread());
_debuggedProcess.Continue(thread?.GetDebuggedThread(), ExecutionDirection);
}
else
{
_pollThread.RunOperation(() => _debuggedProcess.Continue(thread?.GetDebuggedThread()));
_pollThread.RunOperation(() => _debuggedProcess.Continue(thread?.GetDebuggedThread(), ExecutionDirection));
}
}
catch (InvalidCoreDumpOperationException)
Expand Down Expand Up @@ -995,7 +994,7 @@ public int Step(IDebugThread2 pThread, enum_STEPKIND kind, enum_STEPUNIT unit)
return Constants.E_FAIL;
}

_debuggedProcess.WorkerThread.RunOperation(() => _debuggedProcess.Step(thread.GetDebuggedThread().Id, kind, unit));
_debuggedProcess.WorkerThread.RunOperation(() => _debuggedProcess.Step(thread.GetDebuggedThread().Id, kind, unit, ExecutionDirection));
}
catch (InvalidCoreDumpOperationException)
{
Expand Down Expand Up @@ -1083,6 +1082,19 @@ public int WatchForThreadStep(IDebugProgram2 pOriginatingProgram, uint dwTid, in

#endregion

#region IDebugEngineProgram2 Members
int IDebugReversibleEngineProgram160.CanReverse()
{
return DebuggedProcess.TargetFeatures.Contains("reverse") ? Constants.S_OK : Constants.S_FALSE;
}

int IDebugReversibleEngineProgram160.SetExecuteDirection(ExecuteDirection ExecuteDirection)
{
ExecutionDirection = ExecuteDirection;
return Constants.S_OK;
}
#endregion

#region IDebugMemoryBytes2 Members

public int GetSize(out ulong pqwSize)
Expand Down
32 changes: 21 additions & 11 deletions src/MIDebugEngine/Engine.Impl/DebuggedProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -31,6 +30,7 @@ internal class DebuggedProcess : MICore.Debugger
public Disassembly Disassembly { get; private set; }
public ExceptionManager ExceptionManager { get; private set; }
public CygwinFilePathMapper CygwinFilePathMapper { get; private set; }
public string[] TargetFeatures { get; private set; }

private List<DebuggedModule> _moduleList;
private ISampleEngineCallback _callback;
Expand Down Expand Up @@ -618,6 +618,8 @@ public async Task Initialize(HostWaitLoop waitLoop, CancellationToken token)
}
}
}
// now the exe is loaded and we can check target features
TargetFeatures = await MICommandFactory.GetTargetFeatures();

success = true;
}
Expand Down Expand Up @@ -1597,10 +1599,16 @@ protected override void ScheduleResultProcessing(Action func)
_worker.PostOperation(() => { func(); });
}

public async Task Execute(DebuggedThread thread)
public async Task Execute(DebuggedThread thread, ExecuteDirection executionDirection = ExecuteDirection.ExecuteDirection_Forward)
{
await ExceptionManager.EnsureSettingsUpdated();

if (executionDirection == ExecuteDirection.ExecuteDirection_Reverse)
{
await MICommandFactory.ExecContinue(false);
return;
}

// Should clear stepping state
if (_worker.IsPollThread())
{
Expand All @@ -1612,30 +1620,32 @@ public async Task Execute(DebuggedThread thread)
}
}

public Task Continue(DebuggedThread thread)
public Task Continue(DebuggedThread thread, ExecuteDirection executionDirection = ExecuteDirection.ExecuteDirection_Forward)
{
// Called after Stopping event
return Execute(thread);
return Execute(thread, executionDirection);
}

public async Task Step(int threadId, enum_STEPKIND kind, enum_STEPUNIT unit)
public async Task Step(int threadId, enum_STEPKIND kind, enum_STEPUNIT unit, ExecuteDirection direction = ExecuteDirection.ExecuteDirection_Forward)
{
this.VerifyNotDebuggingCoreDump();

await ExceptionManager.EnsureSettingsUpdated();

// STEP_BACKWARDS is deprecated, use direction
bool isForwardStep = direction == ExecuteDirection.ExecuteDirection_Forward;
if ((unit == enum_STEPUNIT.STEP_LINE) || (unit == enum_STEPUNIT.STEP_STATEMENT))
{
switch (kind)
{
case enum_STEPKIND.STEP_INTO:
await MICommandFactory.ExecStep(threadId);
await MICommandFactory.ExecStep(threadId, isForwardStep);
break;
case enum_STEPKIND.STEP_OVER:
await MICommandFactory.ExecNext(threadId);
await MICommandFactory.ExecNext(threadId, isForwardStep);
break;
case enum_STEPKIND.STEP_OUT:
await MICommandFactory.ExecFinish(threadId);
await MICommandFactory.ExecFinish(threadId, isForwardStep);
break;
default:
throw new NotImplementedException();
Expand All @@ -1646,13 +1656,13 @@ public async Task Step(int threadId, enum_STEPKIND kind, enum_STEPUNIT unit)
switch (kind)
{
case enum_STEPKIND.STEP_INTO:
await MICommandFactory.ExecStepInstruction(threadId);
await MICommandFactory.ExecStepInstruction(threadId, isForwardStep);
break;
case enum_STEPKIND.STEP_OVER:
await MICommandFactory.ExecNextInstruction(threadId);
await MICommandFactory.ExecNextInstruction(threadId, isForwardStep);
break;
case enum_STEPKIND.STEP_OUT:
await MICommandFactory.ExecFinish(threadId);
await MICommandFactory.ExecFinish(threadId, isForwardStep);
break;
default:
throw new NotImplementedException();
Expand Down
3 changes: 3 additions & 0 deletions src/MIDebugEngine/MIDebugEngine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@
<Reference Include="Microsoft.VisualStudio.Debugger.Interop.15.0">
<HintPath>$(NuGetPackagesDirectory)/Microsoft.VisualStudio.Debugger.Interop.15.0.15.8.28010/lib/net20/Microsoft.VisualStudio.Debugger.Interop.15.0.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.Debugger.Interop.16.0">
<HintPath>$(NuGetPackagesDirectory)/Microsoft.VisualStudio.Debugger.Interop.16.0.16.7.30328.139/lib/net20/Microsoft.VisualStudio.Debugger.Interop.16.0.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AD7.Definitions\AD7Guids.cs" />
Expand Down
Loading

0 comments on commit 6c1d644

Please sign in to comment.