Implement source breakpoints

This commit is contained in:
Joshua "Yoshi" Askharoun
2025-12-03 20:42:58 -06:00
parent 4a1381ac56
commit 47a8c25353
3 changed files with 42 additions and 30 deletions
@@ -79,8 +79,8 @@ public class IrisDebugAdapterClient : IDebuggerClient, IRemoteDebuggerState, IDi
; ;
}).ConfigureAwait(false); }).ConfigureAwait(false);
var tcs = new TaskCompletionSource<object>(); // TODO: How to keep the thread alive while the debug adapter is running?
await tcs.Task; await Task.Delay(-1).ConfigureAwait(false);
} }
public void Dispose() public void Dispose()
@@ -1,5 +1,6 @@
using Microsoft.Iris.Debug.Symbols; using Microsoft.Iris.Debug.Symbols;
using OmniSharp.Extensions.DebugAdapter.Protocol.Requests; using OmniSharp.Extensions.DebugAdapter.Protocol.Requests;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -18,7 +19,19 @@ internal class BreakpointHandler(DebugSymbolResolver symbolResolver)
foreach (var requestedBreakpoint in request.Breakpoints) foreach (var requestedBreakpoint in request.Breakpoints)
{ {
var parts = requestedBreakpoint.InstructionReference.Split(['@'], 2);
var loadUri = parts[0];
var offset = Convert.ToUInt32(parts[1], 16);
IrisBreakpoint irisBreakpoint = new(loadUri, offset);
Application.DebugSettings.Breakpoints.Add(irisBreakpoint);
DapBreakpoint dapBreakpoint = new()
{
Id = irisBreakpoint.GetHashCode(),
InstructionReference = requestedBreakpoint.InstructionReference,
};
dapBreakpoints.Add(dapBreakpoint);
} }
SetInstructionBreakpointsResponse response = new() SetInstructionBreakpointsResponse response = new()
+11 -12
View File
@@ -86,30 +86,28 @@ public class DebugCommand : AsyncCommand<DebugCommand.Settings>
if (inputParts.Length >= 3 && inputParts[2].StartsWith("0x")) if (inputParts.Length >= 3 && inputParts[2].StartsWith("0x"))
{ {
breakOffset = uint.Parse(inputParts[2][2..], NumberStyles.HexNumber); breakOffset = Convert.ToUInt32(inputParts[2], 16);
} }
else else
{ {
if (symbolResolver is null) var line = int.Parse(inputParts[2]);
{ var column = int.Parse(inputParts[3]);
AnsiConsole.MarkupLine("[red]Setting breakpoints via source code requires debug symbols. Use the --symbols argument to specify a directory.[/]");
break;
}
var fsym = symbolResolver.GetForFile(fileName); var fsym = symbolResolver?.GetForFile(fileName);
if (fsym is null) if (fsym is null)
{ {
AnsiConsole.MarkupLineInterpolated($"[red]No symbols loaded for '{fileName}'.[/]"); AnsiConsole.MarkupLineInterpolated($"[yellow]No symbols loaded for '{fileName}'.[/]");
client.UpdateBreakpoint(new(path, line, column));
AnsiConsole.MarkupLineInterpolated($"[green]Breakpoint set in '{path}' at line {line}, column {column}.[/]");
break; break;
} }
else
{
if (fsym.OriginalFileName is not null) if (fsym.OriginalFileName is not null)
path = fsym.OriginalFileName; path = fsym.OriginalFileName;
var line = int.Parse(inputParts[2]);
var column = int.Parse(inputParts[3]);
var position = new SourcePosition(line, column); var position = new SourcePosition(line, column);
var location = fsym!.SourceMap.GetLocationFromPosition(position); var location = fsym!.SourceMap.GetLocationFromPosition(position);
if (location is null) if (location is null)
{ {
@@ -125,6 +123,7 @@ public class DebugCommand : AsyncCommand<DebugCommand.Settings>
AnsiConsole.Write(new Panel(sourceCode.EscapeMarkup())); AnsiConsole.Write(new Panel(sourceCode.EscapeMarkup()));
} }
} }
}
client.UpdateBreakpoint(new(path, breakOffset)); client.UpdateBreakpoint(new(path, breakOffset));
AnsiConsole.MarkupLineInterpolated($"[green]Breakpoint set in '{path}' at offset 0x{breakOffset:X4}.[/]"); AnsiConsole.MarkupLineInterpolated($"[green]Breakpoint set in '{path}' at offset 0x{breakOffset:X4}.[/]");