Skip to content

Commit

Permalink
implement Goto Request
Browse files Browse the repository at this point in the history
  • Loading branch information
Trass3r committed Sep 6, 2020
1 parent e1b8dda commit b2e7965
Show file tree
Hide file tree
Showing 12 changed files with 236 additions and 36 deletions.
6 changes: 6 additions & 0 deletions src/MICore/CommandFactories/MICommandFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,12 @@ public async Task ExecNextInstruction(int threadId, ResultClass resultClass = Re
await ThreadFrameCmdAsync(command, resultClass, threadId, 0);
}

/// <summary>
/// Jumps to a specified target location
/// </summary>
abstract public Task ExecJump(string filename, int line);
abstract public Task ExecJump(ulong address);

/// <summary>
/// Tells GDB to spawn a target process previous setup with -file-exec-and-symbols or similar
/// </summary>
Expand Down
10 changes: 10 additions & 0 deletions src/MICore/CommandFactories/clrdbg.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,16 @@ public override Task Catch(string name, bool onlyOnce = false, ResultClass resul
throw new NotImplementedException("clrdbg catch command");
}

public override Task ExecJump(string filename, int line)
{
throw new NotImplementedException("clrdbg jump command");
}

public override Task ExecJump(ulong address)
{
throw new NotImplementedException("clrdbg jump command");
}

public override string GetTargetArchitectureCommand()
{
return null;
Expand Down
24 changes: 22 additions & 2 deletions src/MICore/CommandFactories/gdb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public override async Task<Results> ThreadInfo(uint? threadId = null)

public override async Task<List<ulong>> StartAddressesForLine(string file, uint line)
{
string cmd = "info line " + file + ":" + line;
string cmd = "info line -s " + file + " -li " + line;
var result = await _debugger.ConsoleCmdAsync(cmd, allowWhileRunning: false);
List<ulong> addresses = new List<ulong>();
using (StringReader stringReader = new StringReader(result))
Expand All @@ -173,7 +173,7 @@ public override async Task<List<ulong>> StartAddressesForLine(string file, uint
{
ulong address;
string addrStr = resultLine.Substring(pos + 18);
if (MICommandFactory.SpanNextAddr(addrStr, out address) != null)
if (SpanNextAddr(addrStr, out address) != null)
{
addresses.Add(address);
}
Expand All @@ -183,6 +183,26 @@ public override async Task<List<ulong>> StartAddressesForLine(string file, uint
return addresses;
}

private async Task JumpInternal(string target)
{
await _debugger.CmdAsync("-break-insert -t " + target, ResultClass.done);
await _debugger.CmdAsync("-exec-jump " + target, ResultClass.running);
}

public override Task ExecJump(string filename, int line)
{
// temporary breakpoint + jump
string target = "--source " + filename + " --line " + line;
return JumpInternal(target);
}

public override Task ExecJump(ulong address)
{
// temporary breakpoint + jump
string target = "*" + string.Format("0x{0:X}", address);
return JumpInternal(target);
}

public override Task EnableTargetAsyncOption()
{
// Linux attach TODO: GDB will fail this command when attaching. This is worked around
Expand Down
12 changes: 12 additions & 0 deletions src/MICore/CommandFactories/lldb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,18 @@ public override Task Catch(string name, bool onlyOnce = false, ResultClass resul
throw new NotImplementedException("lldb catch command");
}

public override async Task ExecJump(string filename, int line)
{
string command = "jump " + filename + ":" + line;
await _debugger.CmdAsync(command, ResultClass.running);
}

public override async Task ExecJump(ulong address)
{
string command = "jump *" + string.Format("0x{0:X}", address);
await _debugger.CmdAsync(command, ResultClass.running);
}

/// <summary>
/// Assigns the value of an expression to a variable.
/// Since LLDB only accepts assigning values to variables, the expression may need to be evaluated.
Expand Down
38 changes: 38 additions & 0 deletions src/MIDebugEngine/AD7.Impl/AD7Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,44 @@ public object GetMetric(string metric)
return _configStore.GetEngineMetric(metric);
}

public int Jump(string filename, int line)
{
try
{
_debuggedProcess.WorkerThread.RunOperation(() => _debuggedProcess.Jump(filename, line));
}
catch (InvalidCoreDumpOperationException)
{
return AD7_HRESULT.E_CRASHDUMP_UNSUPPORTED;
}
catch (Exception e)
{
_engineCallback.OnError(EngineUtils.GetExceptionDescription(e));
return Constants.E_ABORT;
}

return Constants.S_OK;
}

public int Jump(ulong address)
{
try
{
_debuggedProcess.WorkerThread.RunOperation(() => _debuggedProcess.Jump(address));
}
catch (InvalidCoreDumpOperationException)
{
return AD7_HRESULT.E_CRASHDUMP_UNSUPPORTED;
}
catch (Exception e)
{
_engineCallback.OnError(EngineUtils.GetExceptionDescription(e));
return Constants.E_ABORT;
}

return Constants.S_OK;
}

#region IDebugEngine2 Members

// Attach the debug engine to a program.
Expand Down
27 changes: 12 additions & 15 deletions src/MIDebugEngine/AD7.Impl/AD7MemoryAddress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.Debugger.Interop;
using MICore;
using Microsoft.MIDebugEngine.Natvis;

namespace Microsoft.MIDebugEngine
{
// And implementation of IDebugCodeContext2 and IDebugMemoryContext2.
// IDebugMemoryContext2 represents a position in the address space of the machine running the program being debugged.
// IDebugCodeContext2 represents the starting position of a code instruction.
// For most run-time architectures today, a code context can be thought of as an address in a program's execution stream.
internal class AD7MemoryAddress : IDebugCodeContext2
internal sealed class AD7MemoryAddress : IDebugCodeContext2
{
private readonly AD7Engine _engine;
private readonly ulong _address;
Expand Down Expand Up @@ -42,6 +39,7 @@ public void SetDocumentContext(IDebugDocumentContext2 docContext)
// Adds a specified value to the current context's address to create a new context.
public int Add(ulong dwCount, out IDebugMemoryContext2 newAddress)
{
// FIXME: this is not correct for IDebugCodeContext2
newAddress = new AD7MemoryAddress(_engine, (uint)dwCount + _address, null);
return Constants.S_OK;
}
Expand Down Expand Up @@ -160,19 +158,15 @@ public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
{
pinfo[0].dwFields = 0;

if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0)
if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0 ||
(dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE) != 0)
{
pinfo[0].bstrAddress = EngineUtils.AsAddr(_address, _engine.DebuggedProcess.Is64BitArch);
pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
pinfo[0].bstrAddressAbsolute = pinfo[0].bstrAddress;
pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS | enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE;
}

// Fields not supported by the sample
if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSOFFSET) != 0) { }
if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE) != 0)
{
pinfo[0].bstrAddressAbsolute = EngineUtils.AsAddr(_address, _engine.DebuggedProcess.Is64BitArch);
pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE;
}
if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0)
{
DebuggedModule module = _engine.DebuggedProcess.ResolveAddress(_address);
Expand All @@ -195,7 +189,10 @@ public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION;
}
}
if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTIONOFFSET) != 0) { }
if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTIONOFFSET) != 0)
{
// TODO:
}

return Constants.S_OK;
}
Expand All @@ -210,10 +207,10 @@ public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
}

// Gets the user-displayable name for this context
// This is not supported by the sample engine.
public int GetName(out string pbstrName)
{
throw new NotImplementedException();
pbstrName = _functionName ?? Engine.GetAddressDescription(_address);
return Constants.S_OK;
}

// Subtracts a specified value from the current context's address to create a new context.
Expand Down
23 changes: 8 additions & 15 deletions src/MIDebugEngine/AD7.Impl/AD7Thread.cs
Original file line number Diff line number Diff line change
Expand Up @@ -276,26 +276,19 @@ int IDebugThread2.Resume(out uint suspendCount)
// Sets the next statement to the given stack frame and code context.
int IDebugThread2.SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext)
{
// CLRDBG TODO: This implementation should be changed to call an MI command
ulong addr = ((AD7MemoryAddress)codeContext).Address;
AD7StackFrame frame = ((AD7StackFrame)stackFrame);
if (frame.ThreadContext.Level != 0 || frame.Thread != this || !frame.ThreadContext.pc.HasValue || _engine.DebuggedProcess.MICommandFactory.Mode == MIMode.Clrdbg)
{
var infos = new CONTEXT_INFO[1];
if (codeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, infos) != Constants.S_OK)
return Constants.S_FALSE;
}
string toFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, addr);
string fromFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, frame.ThreadContext.pc.Value);
if (toFunc != fromFunc)

try
{
return Constants.S_FALSE;
ulong address = Convert.ToUInt64(infos[0].bstrAddress, 16);
return _engine.Jump(address);
}
string result = frame.EvaluateExpression("$pc=" + EngineUtils.AsAddr(addr, _engine.DebuggedProcess.Is64BitArch));
if (result != null)
catch (Exception)
{
_engine.DebuggedProcess.ThreadCache.MarkDirty();
return Constants.S_OK;
return Constants.S_FALSE;
}
return Constants.S_FALSE;
}

// suspend a thread.
Expand Down
2 changes: 1 addition & 1 deletion src/MIDebugEngine/Engine.Impl/Breakpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ internal static async Task<BindResult> Bind(string documentName, uint line, uint
string compilerSrcName;
if (!process.MapCurrentSrcToCompileTimeSrc(documentName, out compilerSrcName))
{
compilerSrcName = Path.GetFileName(documentName);
compilerSrcName = Path.GetFileName(documentName);
}
return await EvalBindResult(await process.MICommandFactory.BreakInsert(compilerSrcName, process.UseUnixSymbolPaths, line, condition, enabled, checksums, ResultClass.None), pbreak);
}
Expand Down
10 changes: 10 additions & 0 deletions src/MIDebugEngine/Engine.Impl/DebuggedProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1618,6 +1618,16 @@ public Task Continue(DebuggedThread thread)
return Execute(thread);
}

public async Task Jump(string filename, int line)
{
await MICommandFactory.ExecJump(filename, line);
}

public async Task Jump(ulong address)
{
await MICommandFactory.ExecJump(address);
}

public async Task Step(int threadId, enum_STEPKIND kind, enum_STEPUNIT unit)
{
this.VerifyNotDebuggingCoreDump();
Expand Down
Loading

0 comments on commit b2e7965

Please sign in to comment.