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

[wasm][debugger] Fix debugger behavior when the type has ToString method overridden #76780

Merged
merged 11 commits into from
Oct 11, 2022
15 changes: 15 additions & 0 deletions src/mono/wasm/debugger/BrowserDebugProxy/JObjectValueCreator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,21 @@ private async Task<JObject> ReadAsObjectValue(MonoBinaryReader retDebuggerCmdRea
return Create(value: className, type: "symbol", description: className);
}
}
var typeInfo = await _sdbAgent.GetTypeInfo(type_id[0], token);
radical marked this conversation as resolved.
Show resolved Hide resolved
if (typeInfo != null && typeInfo.Name != "object")
{
MethodInfo methodInfo = typeInfo.Info.Methods.FirstOrDefault(m => m.Name == "ToString");
if (methodInfo != null)
{
int[] methodIds = await _sdbAgent.GetMethodIdsByName(type_id[0], "ToString", token);
if (methodIds.Length > 0)
{
var toString = await _sdbAgent.InvokeMethod(objectId, methodIds[0], isValueType: false, token);
if (toString["value"]?["value"] != null)
description = toString["value"]?["value"].Value<string>();
}
}
}
return Create<object>(value: null, type: "object", description: description, className: className, objectId: $"dotnet:object:{objectId}");
}

Expand Down
19 changes: 19 additions & 0 deletions src/mono/wasm/debugger/DebuggerTestSuite/CustomViewTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,24 @@ async Task<bool> CheckProperties(JObject pause_location)
Assert.True(task.Result);
}
}

[ConditionalFact(nameof(RunningOnChrome))]
public async Task InspectObjectOfTypeWithToStringOverwritten()
{
var expression = $"{{ invoke_static_method('[debugger-test] ToStringOverwritten:Run'); }}";

await EvaluateAndCheck(
"window.setTimeout(function() {" + expression + "; }, 1);",
"dotnet://debugger-test.dll/debugger-test.cs", 1384, 8,
"ToStringOverwritten.Run",
wait_for_event_fn: async (pause_location) =>
{
var id = pause_location["callFrames"][0]["callFrameId"].Value<string>();
await EvaluateOnCallFrameAndCheck(id,
("a", TObject("ToStringOverwritten", description:"hello"))
);
}
);
}
}
}
2 changes: 1 addition & 1 deletion src/mono/wasm/debugger/DebuggerTestSuite/MiscTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ public async Task PreviousFrameForAReflectedCall() => await CheckInspectLocalsAt

await CheckProps(frame_locals, new
{
mi = TObject("System.Reflection.RuntimeMethodInfo"), //this is what is returned when debugging desktop apps using VS
mi = TObject("System.Reflection.RuntimeMethodInfo", description: "Void SimpleStaticMethod(System.DateTime, System.String)"), //this is what is returned when debugging desktop apps using VS
dt = TDateTime(new DateTime(4210, 3, 4, 5, 6, 7)),
i = TNumber(4),
strings = TArray("string[]", "string[1]"),
Expand Down
13 changes: 13 additions & 0 deletions src/mono/wasm/debugger/tests/debugger-test/debugger-test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1371,4 +1371,17 @@ public static void CheckArguments(ReadOnlySpan<object> parameters)
{
System.Diagnostics.Debugger.Break();
}
}

public class ToStringOverwritten
{
public override string ToString()
{
return "hello";
}
public static void Run()
radical marked this conversation as resolved.
Show resolved Hide resolved
{
var a = new ToStringOverwritten();
System.Diagnostics.Debugger.Break();
}
}