Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement reverse execution for gdb #1037

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 21 additions & 9 deletions src/MICore/CommandFactories/MICommandFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
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 @@ -212,33 +210,43 @@ public async Task<ValueListValue> StackListVariables(PrintValue printValues, int

#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 @@ -254,9 +262,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 @@ -686,6 +696,8 @@ public virtual bool CanDetach()
return true;
}

abstract public Task<string[]> GetTargetFeatures();

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

/// <summary>
Expand Down
14 changes: 8 additions & 6 deletions src/MICore/CommandFactories/gdb.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
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;

namespace MICore
{
internal class GdbMICommandFactory : MICommandFactory
internal sealed class GdbMICommandFactory : MICommandFactory
{
private int _currentThreadId = 0;
private uint _currentFrameLevel = 0;
Expand Down Expand Up @@ -183,6 +179,12 @@ public override async Task<List<ulong>> StartAddressesForLine(string file, uint
return addresses;
}

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

public override async Task EnableTargetAsyncOption()
{
// Linux attach TODO: GDB will fail this command when attaching. This is worked around
Expand Down
10 changes: 6 additions & 4 deletions src/MICore/CommandFactories/lldb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,15 @@

using System;
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
{
internal class LlldbMICommandFactory : MICommandFactory
internal sealed class LlldbMICommandFactory : MICommandFactory
{
public override string Name
{
Expand Down Expand Up @@ -119,6 +116,11 @@ public override Task EnableTargetAsyncOption()
return Task.FromResult((object)null);
}

public override Task<string[]> GetTargetFeatures()
{
return Task.FromResult(new string[0]);
}

public override string GetTargetArchitectureCommand()
{
return "platform status";
Expand Down
12 changes: 12 additions & 0 deletions src/MICore/Debugger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public class Debugger : ITransportCallback
public event EventHandler ThreadCreatedEvent;
public event EventHandler ThreadExitedEvent;
public event EventHandler ThreadGroupExitedEvent;
public event EventHandler RecordStartedEvent;
public event EventHandler RecordStoppedEvent;
public event EventHandler<ResultEventArgs> TelemetryEvent;
private int _exiting;
public ProcessState ProcessState { get; private set; }
Expand Down Expand Up @@ -1446,6 +1448,16 @@ private void OnNotificationOutput(string cmd)
results = _miResults.ParseResultList(cmd.Substring("thread-exited,".Length));
ThreadExitedEvent(this, new ResultEventArgs(results, 0));
}
else if (cmd.StartsWith("record-started,", StringComparison.Ordinal))
{
results = _miResults.ParseResultList(cmd.Substring("record-started,".Length));
RecordStartedEvent(this, new ResultEventArgs(results, 0));
}
else if (cmd.StartsWith("record-stopped,", StringComparison.Ordinal))
{
results = _miResults.ParseResultList(cmd.Substring("record-stopped,".Length));
RecordStoppedEvent(this, new ResultEventArgs(results, 0));
}
else if (cmd.StartsWith("telemetry,", StringComparison.Ordinal))
{
results = _miResults.ParseResultList(cmd.Substring("telemetry,".Length));
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, IDebugMemoryBytesDAP, IDisposable
sealed public class AD7Engine : IDebugEngine2, IDebugEngineLaunch2, IDebugEngine3, IDebugProgram3, IDebugEngineProgram2, IDebugReversibleEngineProgram160, IDebugMemoryBytes2, IDebugEngine110, IDebugProgramDAP, IDebugMemoryBytesDAP, 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 @@ -171,6 +169,7 @@ internal bool ProgramCreateEventSent
get;
private set;
}
public ExecuteDirection ExecutionDirection { get; private set; }

public string GetAddressDescription(ulong ip)
{
Expand Down Expand Up @@ -778,11 +777,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 @@ -973,7 +972,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 @@ -1061,6 +1060,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
Loading