Skip to content

Commit b2e7965

Browse files
committed
implement Goto Request
1 parent e1b8dda commit b2e7965

File tree

12 files changed

+236
-36
lines changed

12 files changed

+236
-36
lines changed

src/MICore/CommandFactories/MICommandFactory.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,12 @@ public async Task ExecNextInstruction(int threadId, ResultClass resultClass = Re
246246
await ThreadFrameCmdAsync(command, resultClass, threadId, 0);
247247
}
248248

249+
/// <summary>
250+
/// Jumps to a specified target location
251+
/// </summary>
252+
abstract public Task ExecJump(string filename, int line);
253+
abstract public Task ExecJump(ulong address);
254+
249255
/// <summary>
250256
/// Tells GDB to spawn a target process previous setup with -file-exec-and-symbols or similar
251257
/// </summary>

src/MICore/CommandFactories/clrdbg.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,16 @@ public override Task Catch(string name, bool onlyOnce = false, ResultClass resul
237237
throw new NotImplementedException("clrdbg catch command");
238238
}
239239

240+
public override Task ExecJump(string filename, int line)
241+
{
242+
throw new NotImplementedException("clrdbg jump command");
243+
}
244+
245+
public override Task ExecJump(ulong address)
246+
{
247+
throw new NotImplementedException("clrdbg jump command");
248+
}
249+
240250
public override string GetTargetArchitectureCommand()
241251
{
242252
return null;

src/MICore/CommandFactories/gdb.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ public override async Task<Results> ThreadInfo(uint? threadId = null)
157157

158158
public override async Task<List<ulong>> StartAddressesForLine(string file, uint line)
159159
{
160-
string cmd = "info line " + file + ":" + line;
160+
string cmd = "info line -s " + file + " -li " + line;
161161
var result = await _debugger.ConsoleCmdAsync(cmd, allowWhileRunning: false);
162162
List<ulong> addresses = new List<ulong>();
163163
using (StringReader stringReader = new StringReader(result))
@@ -173,7 +173,7 @@ public override async Task<List<ulong>> StartAddressesForLine(string file, uint
173173
{
174174
ulong address;
175175
string addrStr = resultLine.Substring(pos + 18);
176-
if (MICommandFactory.SpanNextAddr(addrStr, out address) != null)
176+
if (SpanNextAddr(addrStr, out address) != null)
177177
{
178178
addresses.Add(address);
179179
}
@@ -183,6 +183,26 @@ public override async Task<List<ulong>> StartAddressesForLine(string file, uint
183183
return addresses;
184184
}
185185

186+
private async Task JumpInternal(string target)
187+
{
188+
await _debugger.CmdAsync("-break-insert -t " + target, ResultClass.done);
189+
await _debugger.CmdAsync("-exec-jump " + target, ResultClass.running);
190+
}
191+
192+
public override Task ExecJump(string filename, int line)
193+
{
194+
// temporary breakpoint + jump
195+
string target = "--source " + filename + " --line " + line;
196+
return JumpInternal(target);
197+
}
198+
199+
public override Task ExecJump(ulong address)
200+
{
201+
// temporary breakpoint + jump
202+
string target = "*" + string.Format("0x{0:X}", address);
203+
return JumpInternal(target);
204+
}
205+
186206
public override Task EnableTargetAsyncOption()
187207
{
188208
// Linux attach TODO: GDB will fail this command when attaching. This is worked around

src/MICore/CommandFactories/lldb.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,18 @@ public override Task Catch(string name, bool onlyOnce = false, ResultClass resul
177177
throw new NotImplementedException("lldb catch command");
178178
}
179179

180+
public override async Task ExecJump(string filename, int line)
181+
{
182+
string command = "jump " + filename + ":" + line;
183+
await _debugger.CmdAsync(command, ResultClass.running);
184+
}
185+
186+
public override async Task ExecJump(ulong address)
187+
{
188+
string command = "jump *" + string.Format("0x{0:X}", address);
189+
await _debugger.CmdAsync(command, ResultClass.running);
190+
}
191+
180192
/// <summary>
181193
/// Assigns the value of an expression to a variable.
182194
/// Since LLDB only accepts assigning values to variables, the expression may need to be evaluated.

src/MIDebugEngine/AD7.Impl/AD7Engine.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,44 @@ public object GetMetric(string metric)
187187
return _configStore.GetEngineMetric(metric);
188188
}
189189

190+
public int Jump(string filename, int line)
191+
{
192+
try
193+
{
194+
_debuggedProcess.WorkerThread.RunOperation(() => _debuggedProcess.Jump(filename, line));
195+
}
196+
catch (InvalidCoreDumpOperationException)
197+
{
198+
return AD7_HRESULT.E_CRASHDUMP_UNSUPPORTED;
199+
}
200+
catch (Exception e)
201+
{
202+
_engineCallback.OnError(EngineUtils.GetExceptionDescription(e));
203+
return Constants.E_ABORT;
204+
}
205+
206+
return Constants.S_OK;
207+
}
208+
209+
public int Jump(ulong address)
210+
{
211+
try
212+
{
213+
_debuggedProcess.WorkerThread.RunOperation(() => _debuggedProcess.Jump(address));
214+
}
215+
catch (InvalidCoreDumpOperationException)
216+
{
217+
return AD7_HRESULT.E_CRASHDUMP_UNSUPPORTED;
218+
}
219+
catch (Exception e)
220+
{
221+
_engineCallback.OnError(EngineUtils.GetExceptionDescription(e));
222+
return Constants.E_ABORT;
223+
}
224+
225+
return Constants.S_OK;
226+
}
227+
190228
#region IDebugEngine2 Members
191229

192230
// Attach the debug engine to a program.

src/MIDebugEngine/AD7.Impl/AD7MemoryAddress.cs

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,16 @@
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System;
5-
using System.Collections.Generic;
6-
using System.Text;
75
using Microsoft.VisualStudio.Debugger.Interop;
86
using MICore;
9-
using Microsoft.MIDebugEngine.Natvis;
107

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

163-
if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0)
161+
if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0 ||
162+
(dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE) != 0)
164163
{
165164
pinfo[0].bstrAddress = EngineUtils.AsAddr(_address, _engine.DebuggedProcess.Is64BitArch);
166-
pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
165+
pinfo[0].bstrAddressAbsolute = pinfo[0].bstrAddress;
166+
pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS | enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE;
167167
}
168-
169168
// Fields not supported by the sample
170169
if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSOFFSET) != 0) { }
171-
if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE) != 0)
172-
{
173-
pinfo[0].bstrAddressAbsolute = EngineUtils.AsAddr(_address, _engine.DebuggedProcess.Is64BitArch);
174-
pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE;
175-
}
176170
if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0)
177171
{
178172
DebuggedModule module = _engine.DebuggedProcess.ResolveAddress(_address);
@@ -195,7 +189,10 @@ public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
195189
pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION;
196190
}
197191
}
198-
if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTIONOFFSET) != 0) { }
192+
if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTIONOFFSET) != 0)
193+
{
194+
// TODO:
195+
}
199196

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

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

219216
// Subtracts a specified value from the current context's address to create a new context.

src/MIDebugEngine/AD7.Impl/AD7Thread.cs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -276,26 +276,19 @@ int IDebugThread2.Resume(out uint suspendCount)
276276
// Sets the next statement to the given stack frame and code context.
277277
int IDebugThread2.SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext)
278278
{
279-
// CLRDBG TODO: This implementation should be changed to call an MI command
280-
ulong addr = ((AD7MemoryAddress)codeContext).Address;
281-
AD7StackFrame frame = ((AD7StackFrame)stackFrame);
282-
if (frame.ThreadContext.Level != 0 || frame.Thread != this || !frame.ThreadContext.pc.HasValue || _engine.DebuggedProcess.MICommandFactory.Mode == MIMode.Clrdbg)
283-
{
279+
var infos = new CONTEXT_INFO[1];
280+
if (codeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, infos) != Constants.S_OK)
284281
return Constants.S_FALSE;
285-
}
286-
string toFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, addr);
287-
string fromFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, frame.ThreadContext.pc.Value);
288-
if (toFunc != fromFunc)
282+
283+
try
289284
{
290-
return Constants.S_FALSE;
285+
ulong address = Convert.ToUInt64(infos[0].bstrAddress, 16);
286+
return _engine.Jump(address);
291287
}
292-
string result = frame.EvaluateExpression("$pc=" + EngineUtils.AsAddr(addr, _engine.DebuggedProcess.Is64BitArch));
293-
if (result != null)
288+
catch (Exception)
294289
{
295-
_engine.DebuggedProcess.ThreadCache.MarkDirty();
296-
return Constants.S_OK;
290+
return Constants.S_FALSE;
297291
}
298-
return Constants.S_FALSE;
299292
}
300293

301294
// suspend a thread.

src/MIDebugEngine/Engine.Impl/Breakpoints.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ internal static async Task<BindResult> Bind(string documentName, uint line, uint
114114
string compilerSrcName;
115115
if (!process.MapCurrentSrcToCompileTimeSrc(documentName, out compilerSrcName))
116116
{
117-
compilerSrcName = Path.GetFileName(documentName);
117+
compilerSrcName = Path.GetFileName(documentName);
118118
}
119119
return await EvalBindResult(await process.MICommandFactory.BreakInsert(compilerSrcName, process.UseUnixSymbolPaths, line, condition, enabled, checksums, ResultClass.None), pbreak);
120120
}

src/MIDebugEngine/Engine.Impl/DebuggedProcess.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,16 @@ public Task Continue(DebuggedThread thread)
16181618
return Execute(thread);
16191619
}
16201620

1621+
public async Task Jump(string filename, int line)
1622+
{
1623+
await MICommandFactory.ExecJump(filename, line);
1624+
}
1625+
1626+
public async Task Jump(ulong address)
1627+
{
1628+
await MICommandFactory.ExecJump(address);
1629+
}
1630+
16211631
public async Task Step(int threadId, enum_STEPKIND kind, enum_STEPUNIT unit)
16221632
{
16231633
this.VerifyNotDebuggingCoreDump();

0 commit comments

Comments
 (0)