Skip to content

Commit 0d25969

Browse files
authored
[wasm][debugger] Tie sdb agent lifetime to the ExecutionContext and simplify the api (#61392)
* Make SMonoSdbHelper part of the execution context
1 parent 66b31ca commit 0d25969

File tree

5 files changed

+544
-569
lines changed

5 files changed

+544
-569
lines changed

src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ public VarInfo(Parameter p, MetadataReader pdbReader)
157157
public override string ToString() => $"(var-info [{Index}] '{Name}')";
158158
}
159159

160-
internal class NewCliLocation
160+
internal class IlLocation
161161
{
162-
public NewCliLocation(MethodInfo method, int offset)
162+
public IlLocation(MethodInfo method, int offset)
163163
{
164164
Method = method;
165165
Offset = offset;
@@ -174,7 +174,7 @@ internal class SourceLocation
174174
private SourceId id;
175175
private int line;
176176
private int column;
177-
private NewCliLocation cliLoc;
177+
private IlLocation ilLocation;
178178

179179
public SourceLocation(SourceId id, int line, int column)
180180
{
@@ -188,13 +188,13 @@ public SourceLocation(MethodInfo mi, SequencePoint sp)
188188
this.id = mi.SourceId;
189189
this.line = sp.StartLine - 1;
190190
this.column = sp.StartColumn - 1;
191-
this.cliLoc = new NewCliLocation(mi, sp.Offset);
191+
this.ilLocation = new IlLocation(mi, sp.Offset);
192192
}
193193

194194
public SourceId Id { get => id; }
195195
public int Line { get => line; }
196196
public int Column { get => column; }
197-
public NewCliLocation CliLocation => this.cliLoc;
197+
public IlLocation IlLocation => this.ilLocation;
198198

199199
public override string ToString() => $"{id}:{Line}:{Column}";
200200

@@ -926,7 +926,7 @@ private class DebugItem
926926
public Task<byte[][]> Data { get; set; }
927927
}
928928

929-
public IEnumerable<MethodInfo> EnC(SessionId sessionId, AssemblyInfo asm, byte[] meta_data, byte[] pdb_data)
929+
public IEnumerable<MethodInfo> EnC(AssemblyInfo asm, byte[] meta_data, byte[] pdb_data)
930930
{
931931
asm.EnC(meta_data, pdb_data);
932932
foreach (var method in asm.Methods)
@@ -936,12 +936,12 @@ public IEnumerable<MethodInfo> EnC(SessionId sessionId, AssemblyInfo asm, byte[]
936936
}
937937
}
938938

939-
public IEnumerable<SourceFile> Add(SessionId sessionId, byte[] assembly_data, byte[] pdb_data)
939+
public IEnumerable<SourceFile> Add(string name, byte[] assembly_data, byte[] pdb_data)
940940
{
941941
AssemblyInfo assembly = null;
942942
try
943943
{
944-
assembly = new AssemblyInfo(sessionId.ToString(), assembly_data, pdb_data);
944+
assembly = new AssemblyInfo(name, assembly_data, pdb_data);
945945
}
946946
catch (Exception e)
947947
{
@@ -965,7 +965,7 @@ public IEnumerable<SourceFile> Add(SessionId sessionId, byte[] assembly_data, by
965965
}
966966
}
967967

968-
public async IAsyncEnumerable<SourceFile> Load(SessionId sessionId, string[] loaded_files, [EnumeratorCancellation] CancellationToken token)
968+
public async IAsyncEnumerable<SourceFile> Load(string[] loaded_files, [EnumeratorCancellation] CancellationToken token)
969969
{
970970
var asm_files = new List<string>();
971971
var pdb_files = new List<string>();

src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,13 @@ internal enum PauseOnExceptionsKind
275275

276276
internal class ExecutionContext
277277
{
278+
public ExecutionContext(MonoSDBHelper sdbAgent, int id, object auxData)
279+
{
280+
Id = id;
281+
AuxData = auxData;
282+
SdbAgent = sdbAgent;
283+
}
284+
278285
public string DebugId { get; set; }
279286
public Dictionary<string, BreakpointRequest> BreakpointRequests { get; } = new Dictionary<string, BreakpointRequest>();
280287

@@ -291,6 +298,7 @@ internal class ExecutionContext
291298

292299
public string[] LoadedFiles { get; set; }
293300
internal DebugStore store;
301+
internal MonoSDBHelper SdbAgent { get; init; }
294302
public TaskCompletionSource<DebugStore> Source { get; } = new TaskCompletionSource<DebugStore>();
295303

296304
private Dictionary<int, PerScopeCache> perScopeCaches { get; } = new Dictionary<int, PerScopeCache>();
@@ -319,6 +327,7 @@ public PerScopeCache GetCacheForScope(int scopeId)
319327
public void ClearState()
320328
{
321329
CallStack = null;
330+
SdbAgent.ClearCache();
322331
perScopeCaches.Clear();
323332
}
324333
}

src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs

Lines changed: 37 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,20 @@ internal class MemberReferenceResolver
1818
private SessionId sessionId;
1919
private int scopeId;
2020
private MonoProxy proxy;
21-
private ExecutionContext ctx;
21+
private ExecutionContext context;
2222
private PerScopeCache scopeCache;
2323
private ILogger logger;
2424
private bool localsFetched;
2525
private int linqTypeId;
26-
private MonoSDBHelper sdbHelper;
2726

2827
public MemberReferenceResolver(MonoProxy proxy, ExecutionContext ctx, SessionId sessionId, int scopeId, ILogger logger)
2928
{
3029
this.sessionId = sessionId;
3130
this.scopeId = scopeId;
3231
this.proxy = proxy;
33-
this.ctx = ctx;
32+
this.context = ctx;
3433
this.logger = logger;
3534
scopeCache = ctx.GetCacheForScope(scopeId);
36-
sdbHelper = proxy.SdbHelper;
3735
linqTypeId = -1;
3836
}
3937

@@ -42,11 +40,10 @@ public MemberReferenceResolver(MonoProxy proxy, ExecutionContext ctx, SessionId
4240
this.sessionId = sessionId;
4341
scopeId = -1;
4442
this.proxy = proxy;
45-
this.ctx = ctx;
43+
this.context = ctx;
4644
this.logger = logger;
4745
scopeCache = new PerScopeCache(objectValues);
4846
localsFetched = true;
49-
sdbHelper = proxy.SdbHelper;
5047
linqTypeId = -1;
5148
}
5249

@@ -56,7 +53,7 @@ public async Task<JObject> GetValueFromObject(JToken objRet, CancellationToken t
5653
{
5754
if (DotnetObjectId.TryParse(objRet?["value"]?["objectId"]?.Value<string>(), out DotnetObjectId objectId))
5855
{
59-
var exceptionObject = await sdbHelper.GetObjectValues(sessionId, int.Parse(objectId.Value), GetObjectCommandOptions.WithProperties | GetObjectCommandOptions.OwnProperties, token);
56+
var exceptionObject = await context.SdbAgent.GetObjectValues(int.Parse(objectId.Value), GetObjectCommandOptions.WithProperties | GetObjectCommandOptions.OwnProperties, token);
6057
var exceptionObjectMessage = exceptionObject.FirstOrDefault(attr => attr["name"].Value<string>().Equals("_message"));
6158
exceptionObjectMessage["value"]["value"] = objRet["value"]?["className"]?.Value<string>() + ": " + exceptionObjectMessage["value"]?["value"]?.Value<string>();
6259
return exceptionObjectMessage["value"]?.Value<JObject>();
@@ -70,10 +67,9 @@ public async Task<JObject> GetValueFromObject(JToken objRet, CancellationToken t
7067
{
7168
if (DotnetObjectId.TryParse(objRet?["get"]?["objectIdValue"]?.Value<string>(), out DotnetObjectId objectId))
7269
{
73-
var commandParams = new MemoryStream();
74-
var commandParamsWriter = new MonoBinaryWriter(commandParams);
75-
commandParamsWriter.WriteObj(objectId, sdbHelper);
76-
var ret = await sdbHelper.InvokeMethod(sessionId, commandParams.ToArray(), objRet["get"]["methodId"].Value<int>(), objRet["name"].Value<string>(), token);
70+
using var commandParamsWriter = new MonoBinaryWriter();
71+
commandParamsWriter.WriteObj(objectId, context.SdbAgent);
72+
var ret = await context.SdbAgent.InvokeMethod(commandParamsWriter.GetParameterBuffer(), objRet["get"]["methodId"].Value<int>(), objRet["name"].Value<string>(), token);
7773
return await GetValueFromObject(ret, token);
7874
}
7975

@@ -93,32 +89,31 @@ public async Task<JObject> TryToRunOnLoadedClasses(string varName, CancellationT
9389
classNameToFind += part.Trim();
9490
if (typeId != -1)
9591
{
96-
var fields = await sdbHelper.GetTypeFields(sessionId, typeId, token);
92+
var fields = await context.SdbAgent.GetTypeFields(typeId, token);
9793
foreach (var field in fields)
9894
{
9995
if (field.Name == part.Trim())
10096
{
101-
var isInitialized = await sdbHelper.TypeIsInitialized(sessionId, typeId, token);
97+
var isInitialized = await context.SdbAgent.TypeIsInitialized(typeId, token);
10298
if (isInitialized == 0)
10399
{
104-
isInitialized = await sdbHelper.TypeInitialize(sessionId, typeId, token);
100+
isInitialized = await context.SdbAgent.TypeInitialize(typeId, token);
105101
}
106-
var valueRet = await sdbHelper.GetFieldValue(sessionId, typeId, field.Id, token);
102+
var valueRet = await context.SdbAgent.GetFieldValue(typeId, field.Id, token);
107103
return await GetValueFromObject(valueRet, token);
108104
}
109105
}
110-
var methodId = await sdbHelper.GetPropertyMethodIdByName(sessionId, typeId, part.Trim(), token);
106+
var methodId = await context.SdbAgent.GetPropertyMethodIdByName(typeId, part.Trim(), token);
111107
if (methodId != -1)
112108
{
113-
var commandParamsObj = new MemoryStream();
114-
var commandParamsObjWriter = new MonoBinaryWriter(commandParamsObj);
109+
using var commandParamsObjWriter = new MonoBinaryWriter();
115110
commandParamsObjWriter.Write(0); //param count
116-
var retMethod = await sdbHelper.InvokeMethod(sessionId, commandParamsObj.ToArray(), methodId, "methodRet", token);
111+
var retMethod = await context.SdbAgent.InvokeMethod(commandParamsObjWriter.GetParameterBuffer(), methodId, "methodRet", token);
117112
return await GetValueFromObject(retMethod, token);
118113
}
119114
}
120115
var store = await proxy.LoadStore(sessionId, token);
121-
var methodInfo = ctx.CallStack.FirstOrDefault(s => s.Id == scopeId)?.Method?.Info;
116+
var methodInfo = context.CallStack.FirstOrDefault(s => s.Id == scopeId)?.Method?.Info;
122117
var classNameToFindWithNamespace =
123118
string.IsNullOrEmpty(methodInfo?.TypeInfo?.Namespace) ?
124119
classNameToFind :
@@ -135,7 +130,7 @@ public async Task<JObject> TryToRunOnLoadedClasses(string varName, CancellationT
135130
var type = assembly.GetTypeByName(typeName);
136131
if (type == null)
137132
return null;
138-
return await sdbHelper.GetTypeIdFromToken(sessionId, assembly.DebugId, type.Token, token);
133+
return await context.SdbAgent.GetTypeIdFromToken(assembly.DebugId, type.Token, token);
139134
}
140135

141136
async Task<int?> TryFindNameInAssembly(List<AssemblyInfo> assemblies, string name)
@@ -290,18 +285,17 @@ public async Task<JObject> Resolve(ElementAccessExpressionSyntax elementAccess,
290285
switch (objectId.Scheme)
291286
{
292287
case "array":
293-
rootObject["value"] = await sdbHelper.GetArrayValues(sessionId, int.Parse(objectId.Value), token);
288+
rootObject["value"] = await context.SdbAgent.GetArrayValues(int.Parse(objectId.Value), token);
294289
return (JObject)rootObject["value"][elementIdx]["value"];
295290
case "object":
296-
var typeIds = await sdbHelper.GetTypeIdFromObject(sessionId, int.Parse(objectId.Value), true, token);
297-
int methodId = await sdbHelper.GetMethodIdByName(sessionId, typeIds[0], "ToArray", token);
298-
var commandParamsObj = new MemoryStream();
299-
var commandParamsObjWriter = new MonoBinaryWriter(commandParamsObj);
300-
commandParamsObjWriter.WriteObj(objectId, sdbHelper);
301-
var toArrayRetMethod = await sdbHelper.InvokeMethod(sessionId, commandParamsObj.ToArray(), methodId, elementAccess.Expression.ToString(), token);
291+
var typeIds = await context.SdbAgent.GetTypeIdFromObject(int.Parse(objectId.Value), true, token);
292+
int methodId = await context.SdbAgent.GetMethodIdByName(typeIds[0], "ToArray", token);
293+
var commandParamsObjWriter = new MonoBinaryWriter();
294+
commandParamsObjWriter.WriteObj(objectId, context.SdbAgent);
295+
var toArrayRetMethod = await context.SdbAgent.InvokeMethod(commandParamsObjWriter.GetParameterBuffer(), methodId, elementAccess.Expression.ToString(), token);
302296
rootObject = await GetValueFromObject(toArrayRetMethod, token);
303297
DotnetObjectId.TryParse(rootObject?["objectId"]?.Value<string>(), out DotnetObjectId arrayObjectId);
304-
rootObject["value"] = await sdbHelper.GetArrayValues(sessionId, int.Parse(arrayObjectId.Value), token);
298+
rootObject["value"] = await context.SdbAgent.GetArrayValues(int.Parse(arrayObjectId.Value), token);
305299
return (JObject)rootObject["value"][elementIdx]["value"];
306300
default:
307301
throw new InvalidOperationException($"Cannot apply indexing with [] to an expression of type '{objectId.Scheme}'");
@@ -340,56 +334,55 @@ public async Task<JObject> Resolve(InvocationExpressionSyntax method, Dictionary
340334
if (rootObject != null)
341335
{
342336
DotnetObjectId.TryParse(rootObject?["objectId"]?.Value<string>(), out DotnetObjectId objectId);
343-
var typeIds = await sdbHelper.GetTypeIdFromObject(sessionId, int.Parse(objectId.Value), true, token);
344-
int methodId = await sdbHelper.GetMethodIdByName(sessionId, typeIds[0], methodName, token);
345-
var className = await sdbHelper.GetTypeNameOriginal(sessionId, typeIds[0], token);
337+
var typeIds = await context.SdbAgent.GetTypeIdFromObject(int.Parse(objectId.Value), true, token);
338+
int methodId = await context.SdbAgent.GetMethodIdByName(typeIds[0], methodName, token);
339+
var className = await context.SdbAgent.GetTypeNameOriginal(typeIds[0], token);
346340
if (methodId == 0) //try to search on System.Linq.Enumerable
347341
{
348342
if (linqTypeId == -1)
349-
linqTypeId = await sdbHelper.GetTypeByName(sessionId, "System.Linq.Enumerable", token);
350-
methodId = await sdbHelper.GetMethodIdByName(sessionId, linqTypeId, methodName, token);
343+
linqTypeId = await context.SdbAgent.GetTypeByName("System.Linq.Enumerable", token);
344+
methodId = await context.SdbAgent.GetMethodIdByName(linqTypeId, methodName, token);
351345
if (methodId != 0)
352346
{
353347
foreach (var typeId in typeIds)
354348
{
355-
var genericTypeArgs = await sdbHelper.GetTypeParamsOrArgsForGenericType(sessionId, typeId, token);
349+
var genericTypeArgs = await context.SdbAgent.GetTypeParamsOrArgsForGenericType(typeId, token);
356350
if (genericTypeArgs.Count > 0)
357351
{
358352
isTryingLinq = 1;
359-
methodId = await sdbHelper.MakeGenericMethod(sessionId, methodId, genericTypeArgs, token);
353+
methodId = await context.SdbAgent.MakeGenericMethod(methodId, genericTypeArgs, token);
360354
break;
361355
}
362356
}
363357
}
364358
}
365359
if (methodId == 0) {
366-
var typeName = await sdbHelper.GetTypeName(sessionId, typeIds[0], token);
360+
var typeName = await context.SdbAgent.GetTypeName(typeIds[0], token);
367361
throw new Exception($"Method '{methodName}' not found in type '{typeName}'");
368362
}
369-
var commandParamsObj = new MemoryStream();
370-
var commandParamsObjWriter = new MonoBinaryWriter(commandParamsObj);
363+
using var commandParamsObjWriter = new MonoBinaryWriter();
371364
if (isTryingLinq == 0)
372-
commandParamsObjWriter.WriteObj(objectId, sdbHelper);
365+
commandParamsObjWriter.WriteObj(objectId, context.SdbAgent);
373366
if (method.ArgumentList != null)
374367
{
375368
commandParamsObjWriter.Write((int)method.ArgumentList.Arguments.Count + isTryingLinq);
376369
if (isTryingLinq == 1)
377-
commandParamsObjWriter.WriteObj(objectId, sdbHelper);
370+
commandParamsObjWriter.WriteObj(objectId, context.SdbAgent);
378371
foreach (var arg in method.ArgumentList.Arguments)
379372
{
380373
if (arg.Expression is LiteralExpressionSyntax)
381374
{
382-
if (!await commandParamsObjWriter.WriteConst(sessionId, arg.Expression as LiteralExpressionSyntax, sdbHelper, token))
375+
if (!await commandParamsObjWriter.WriteConst(arg.Expression as LiteralExpressionSyntax, context.SdbAgent, token))
383376
return null;
384377
}
385378
if (arg.Expression is IdentifierNameSyntax)
386379
{
387380
var argParm = arg.Expression as IdentifierNameSyntax;
388-
if (!await commandParamsObjWriter.WriteJsonValue(sessionId, memberAccessValues[argParm.Identifier.Text], sdbHelper, token))
381+
if (!await commandParamsObjWriter.WriteJsonValue(memberAccessValues[argParm.Identifier.Text], context.SdbAgent, token))
389382
return null;
390383
}
391384
}
392-
var retMethod = await sdbHelper.InvokeMethod(sessionId, commandParamsObj.ToArray(), methodId, "methodRet", token);
385+
var retMethod = await context.SdbAgent.InvokeMethod(commandParamsObjWriter.GetParameterBuffer(), methodId, "methodRet", token);
393386
return await GetValueFromObject(retMethod, token);
394387
}
395388
}

0 commit comments

Comments
 (0)