Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'sdks/wasm/DebuggerTestSuite/PointerTests.cs')
-rw-r--r--sdks/wasm/DebuggerTestSuite/PointerTests.cs1060
1 files changed, 549 insertions, 511 deletions
diff --git a/sdks/wasm/DebuggerTestSuite/PointerTests.cs b/sdks/wasm/DebuggerTestSuite/PointerTests.cs
index 932f02a0c80..d18f054d9d7 100644
--- a/sdks/wasm/DebuggerTestSuite/PointerTests.cs
+++ b/sdks/wasm/DebuggerTestSuite/PointerTests.cs
@@ -1,520 +1,558 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
using System;
using System.Linq;
using System.Threading.Tasks;
+using Microsoft.WebAssembly.Diagnostics;
using Newtonsoft.Json.Linq;
using Xunit;
-using WebAssembly.Net.Debugging;
namespace DebuggerTests
{
- public class PointerTests : DebuggerTestBase {
-
- public static TheoryData<string, string, string, int, string, bool> PointersTestData =>
- new TheoryData<string, string, string, int, string, bool> {
- {$"invoke_static_method ('[debugger-test] DebuggerTests.PointerTests:LocalPointers');", "DebuggerTests.PointerTests", "LocalPointers", 32, "LocalPointers", false},
- {$"invoke_static_method ('[debugger-test] DebuggerTests.PointerTests:LocalPointers');", "DebuggerTests.PointerTests", "LocalPointers", 32, "LocalPointers", true},
- {$"invoke_static_method_async ('[debugger-test] DebuggerTests.PointerTests:LocalPointersAsync');", "DebuggerTests.PointerTests", "LocalPointersAsync", 32, "MoveNext", false},
- {$"invoke_static_method_async ('[debugger-test] DebuggerTests.PointerTests:LocalPointersAsync');", "DebuggerTests.PointerTests", "LocalPointersAsync", 32, "MoveNext", true}
- };
-
- [Theory]
- [MemberDataAttribute (nameof (PointersTestData))]
- public async Task InspectLocalPointersToPrimitiveTypes (string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo)
- => await CheckInspectLocalsAtBreakpointSite (
- type, method, line_offset, bp_function_name,
- "window.setTimeout(function() { " + eval_fn + " })",
- use_cfo: use_cfo,
- wait_for_event_fn: async (pause_location) => {
- var locals = await GetProperties (pause_location ["callFrames"][0]["callFrameId"].Value<string>());
-
- var dt = new DateTime (5, 6, 7, 8, 9, 10);
- await CheckProps (locals, new {
- ip = TPointer ("int*"),
- ip_null = TPointer ("int*", is_null: true),
- ipp = TPointer ("int**"),
- ipp_null = TPointer ("int**"),
-
- cvalue0 = TSymbol ("113 'q'"),
- cp = TPointer ("char*"),
-
- vp = TPointer ("void*"),
- vp_null = TPointer ("void*", is_null: true),
- }, "locals", num_fields: 26);
-
- var props = await GetObjectOnLocals (locals, "ip");
- await CheckPointerValue (props, "*ip", TNumber (5), "locals");
-
- {
- var ipp_props = await GetObjectOnLocals (locals, "ipp");
- await CheckPointerValue (ipp_props, "*ipp", TPointer ("int*"));
-
- ipp_props = await GetObjectOnLocals (ipp_props, "*ipp");
- await CheckPointerValue (ipp_props, "**ipp", TNumber (5));
- }
-
- {
- var ipp_props = await GetObjectOnLocals (locals, "ipp_null");
- await CheckPointerValue (ipp_props, "*ipp_null", TPointer ("int*", is_null: true));
- }
-
- // *cp
- props = await GetObjectOnLocals (locals, "cp");
- await CheckPointerValue (props, "*cp", TSymbol ("113 'q'"));
- });
-
- [Theory]
- [MemberDataAttribute (nameof (PointersTestData))]
- public async Task InspectLocalPointerArrays (string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo)
- => await CheckInspectLocalsAtBreakpointSite (
- type, method, line_offset, bp_function_name,
- "window.setTimeout(function() { " + eval_fn + " })",
- use_cfo: use_cfo,
- wait_for_event_fn: async (pause_location) => {
- var locals = await GetProperties (pause_location ["callFrames"][0]["callFrameId"].Value<string>());
-
- var dt = new DateTime (5, 6, 7, 8, 9, 10);
- await CheckProps (locals, new {
- ipa = TArray ("int*[]", 3)
- }, "locals", num_fields: 26);
-
- var ipa_elems = await CompareObjectPropertiesFor (locals, "ipa", new [] {
- TPointer ("int*"),
- TPointer ("int*"),
- TPointer ("int*", is_null: true)
- });
-
- await CheckArrayElements (ipa_elems, new [] {
- TNumber (5),
- TNumber (10),
- null
- });
- });
-
- [Theory]
- [MemberDataAttribute (nameof (PointersTestData))]
- public async Task InspectLocalDoublePointerToPrimitiveTypeArrays (string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo)
- => await CheckInspectLocalsAtBreakpointSite (
- type, method, line_offset, bp_function_name,
- "window.setTimeout(function() { " + eval_fn + " })",
- use_cfo: use_cfo,
- wait_for_event_fn: async (pause_location) => {
- var locals = await GetProperties (pause_location ["callFrames"][0]["callFrameId"].Value<string>());
-
- var dt = new DateTime (5, 6, 7, 8, 9, 10);
- await CheckProps (locals, new {
- ippa = TArray ("int**[]", 5)
- }, "locals", num_fields: 26);
-
- var ippa_elems = await CompareObjectPropertiesFor (locals, "ippa", new [] {
- TPointer ("int**"),
- TPointer ("int**"),
- TPointer ("int**"),
- TPointer ("int**"),
- TPointer ("int**", is_null: true)
- });
-
- {
- var actual_elems = await CheckArrayElements (ippa_elems, new [] {
- TPointer ("int*"),
- TPointer ("int*", is_null: true),
- TPointer ("int*"),
- TPointer ("int*", is_null: true),
- null
- });
-
- var val = await GetObjectOnLocals (actual_elems [0], "*[0]");
- await CheckPointerValue (val, "**[0]", TNumber (5));
-
- val = await GetObjectOnLocals (actual_elems [2], "*[2]");
- await CheckPointerValue (val, "**[2]", TNumber (5));
- }
- });
-
- [Theory]
- [MemberDataAttribute (nameof (PointersTestData))]
- public async Task InspectLocalPointersToValueTypes (string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo)
- => await CheckInspectLocalsAtBreakpointSite (
- type, method, line_offset, bp_function_name,
- "window.setTimeout(function() { " + eval_fn + " })",
- use_cfo: use_cfo,
- wait_for_event_fn: async (pause_location) => {
- var locals = await GetProperties (pause_location ["callFrames"][0]["callFrameId"].Value<string>());
-
- var dt = new DateTime (5, 6, 7, 8, 9, 10);
- await CheckProps (locals, new {
- dt = TValueType ("System.DateTime", dt.ToString ()),
- dtp = TPointer ("System.DateTime*"),
- dtp_null = TPointer ("System.DateTime*", is_null: true),
-
- gsp = TPointer ("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>*"),
- gsp_null = TPointer ("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>*")
- }, "locals", num_fields: 26);
-
- await CheckDateTime (locals, "dt", dt);
-
- // *dtp
- var props = await GetObjectOnLocals (locals, "dtp");
- await CheckDateTime (props, "*dtp", dt);
-
- var gsp_props = await GetObjectOnLocals (locals, "gsp");
- await CheckPointerValue (gsp_props, "*gsp", TValueType ("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>"), "locals#gsp");
-
- {
- var gs_dt = new DateTime (1, 2, 3, 4, 5, 6);
-
- var gsp_deref_props = await GetObjectOnLocals (gsp_props, "*gsp");
- await CheckProps (gsp_deref_props, new {
- Value = TValueType ("System.DateTime", gs_dt.ToString ()),
- IntField = TNumber (4),
- DTPP = TPointer ("System.DateTime**")
- }, "locals#gsp#deref");
- {
- var dtpp_props = await GetObjectOnLocals (gsp_deref_props, "DTPP");
- await CheckPointerValue (dtpp_props, "*DTPP", TPointer ("System.DateTime*"), "locals#*gsp");
-
- var dtpp_deref_props = await GetObjectOnLocals (dtpp_props, "*DTPP");
- await CheckDateTime (dtpp_deref_props, "**DTPP", dt);
- }
- }
-
- // gsp_null
- var gsp_w_n_props = await GetObjectOnLocals (locals, "gsp_null");
- await CheckPointerValue (gsp_w_n_props, "*gsp_null", TValueType ("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>"), "locals#gsp");
-
- {
- var gs_dt = new DateTime (1, 2, 3, 4, 5, 6);
-
- var gsp_deref_props = await GetObjectOnLocals (gsp_w_n_props, "*gsp_null");
- await CheckProps (gsp_deref_props, new {
- Value = TValueType ("System.DateTime", gs_dt.ToString ()),
- IntField = TNumber (4),
- DTPP = TPointer ("System.DateTime**")
- }, "locals#gsp#deref");
- {
- var dtpp_props = await GetObjectOnLocals (gsp_deref_props, "DTPP");
- await CheckPointerValue (dtpp_props, "*DTPP", TPointer ("System.DateTime*", is_null: true), "locals#*gsp");
- }
- }
- });
-
- [Theory]
- [MemberDataAttribute (nameof (PointersTestData))]
- public async Task InspectLocalPointersToValueTypeArrays (string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo)
- => await CheckInspectLocalsAtBreakpointSite (
- type, method, line_offset, bp_function_name,
- "window.setTimeout(function() { " + eval_fn + " })",
- use_cfo: use_cfo,
- wait_for_event_fn: async (pause_location) => {
- var locals = await GetProperties (pause_location ["callFrames"][0]["callFrameId"].Value<string>());
-
- var dt = new DateTime (5, 6, 7, 8, 9, 10);
- await CheckProps (locals, new {
- dtpa = TArray ("System.DateTime*[]", 2)
- }, "locals", num_fields: 26);
-
- // dtpa
- var dtpa_elems = (await CompareObjectPropertiesFor (locals, "dtpa", new [] {
- TPointer ("System.DateTime*"),
- TPointer ("System.DateTime*", is_null: true)
- }));
- {
- var actual_elems = await CheckArrayElements (dtpa_elems, new [] {
- TValueType ("System.DateTime", dt.ToString ()),
- null
- });
-
- await CheckDateTime (actual_elems [0], "*[0]", dt);
- }
- });
-
- [Theory]
- [MemberDataAttribute (nameof (PointersTestData))]
- public async Task InspectLocalPointersToGenericValueTypeArrays (string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo)
- => await CheckInspectLocalsAtBreakpointSite (
- type, method, line_offset, bp_function_name,
- "window.setTimeout(function() { " + eval_fn + " })",
- use_cfo: use_cfo,
- wait_for_event_fn: async (pause_location) => {
- var locals = await GetProperties (pause_location ["callFrames"][0]["callFrameId"].Value<string>());
-
- var dt = new DateTime (5, 6, 7, 8, 9, 10);
- await CheckProps (locals, new {
- gspa = TArray ("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>*[]", 3),
- }, "locals", num_fields: 26);
-
- // dtpa
- var gspa_elems = await CompareObjectPropertiesFor (locals, "gspa", new [] {
- TPointer ("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>*", is_null: true),
- TPointer ("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>*"),
- TPointer ("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>*"),
- });
- {
- var gs_dt = new DateTime (1, 2, 3, 4, 5, 6);
- var actual_elems = await CheckArrayElements (gspa_elems, new [] {
- null,
- TValueType ("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>"),
- TValueType ("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>")
- });
-
- // *[1]
- {
- var gsp_deref_props = await GetObjectOnLocals (actual_elems [1], "*[1]");
- await CheckProps (gsp_deref_props, new {
- Value = TValueType ("System.DateTime", gs_dt.ToString ()),
- IntField = TNumber (4),
- DTPP = TPointer ("System.DateTime**")
- }, "locals#gsp#deref");
- {
- var dtpp_props = await GetObjectOnLocals (gsp_deref_props, "DTPP");
- await CheckPointerValue (dtpp_props, "*DTPP", TPointer ("System.DateTime*"), "locals#*gsp");
-
- dtpp_props = await GetObjectOnLocals (dtpp_props, "*DTPP");
- await CheckDateTime (dtpp_props, "**DTPP", dt);
- }
- }
-
- // *[2]
- {
- var gsp_deref_props = await GetObjectOnLocals (actual_elems [2], "*[2]");
- await CheckProps (gsp_deref_props, new {
- Value = TValueType ("System.DateTime", gs_dt.ToString ()),
- IntField = TNumber (4),
- DTPP = TPointer ("System.DateTime**")
- }, "locals#gsp#deref");
- {
- var dtpp_props = await GetObjectOnLocals (gsp_deref_props, "DTPP");
- await CheckPointerValue (dtpp_props, "*DTPP", TPointer ("System.DateTime*", is_null: true), "locals#*gsp");
- }
- }
- }
- });
-
- [Theory]
- [MemberDataAttribute (nameof (PointersTestData))]
- public async Task InspectLocalDoublePointersToValueTypeArrays (string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo)
- => await CheckInspectLocalsAtBreakpointSite (
- type, method, line_offset, bp_function_name,
- "window.setTimeout(function() { " + eval_fn + " })",
- use_cfo: use_cfo,
- wait_for_event_fn: async (pause_location) => {
- var locals = await GetProperties (pause_location ["callFrames"][0]["callFrameId"].Value<string>());
-
- var dt = new DateTime (5, 6, 7, 8, 9, 10);
- await CheckProps (locals, new {
- dtppa = TArray ("System.DateTime**[]", 3),
- }, "locals", num_fields: 26);
-
- // DateTime**[] dtppa = new DateTime**[] { &dtp, &dtp_null, null };
- var dtppa_elems = (await CompareObjectPropertiesFor (locals, "dtppa", new [] {
- TPointer ("System.DateTime**"),
- TPointer ("System.DateTime**"),
- TPointer ("System.DateTime**", is_null: true)
- }));
-
- var exp_elems = new [] {
- TPointer ("System.DateTime*"),
- TPointer ("System.DateTime*", is_null: true),
- null
- };
-
- var actual_elems = new JToken [exp_elems.Length];
- for (int i = 0; i < exp_elems.Length; i ++) {
- if (exp_elems [i] != null) {
- actual_elems [i] = await GetObjectOnLocals (dtppa_elems, i.ToString ());
- await CheckPointerValue (actual_elems [i], $"*[{i}]", exp_elems [i], $"dtppa->");
- }
- }
- });
-
- [Theory]
- [MemberDataAttribute (nameof (PointersTestData))]
- public async Task InspectLocalPointersInClasses (string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo)
- => await CheckInspectLocalsAtBreakpointSite (
- type, method, line_offset, bp_function_name,
- "window.setTimeout(function() { " + eval_fn + " })",
- use_cfo: use_cfo,
- wait_for_event_fn: async (pause_location) => {
- var locals = await GetProperties (pause_location ["callFrames"][0]["callFrameId"].Value<string>());
-
- var dt = new DateTime (5, 6, 7, 8, 9, 10);
- await CheckProps (locals, new {
- cwp = TObject ("DebuggerTests.GenericClassWithPointers<System.DateTime>"),
- cwp_null = TObject ("DebuggerTests.GenericClassWithPointers<System.DateTime>")
- }, "locals", num_fields: 26);
-
- var cwp_props = await GetObjectOnLocals (locals, "cwp");
- var ptr_props = await GetObjectOnLocals (cwp_props, "Ptr");
- await CheckDateTime (ptr_props, "*Ptr", dt);
- });
-
- public static TheoryData<string, string, string, int, string, bool> PointersAsMethodArgsTestData =>
- new TheoryData<string, string, string, int, string, bool> {
- {$"invoke_static_method ('[debugger-test] DebuggerTests.PointerTests:LocalPointers');", "DebuggerTests.PointerTests", "PointersAsArgsTest", 2, "PointersAsArgsTest", false},
- {$"invoke_static_method ('[debugger-test] DebuggerTests.PointerTests:LocalPointers');", "DebuggerTests.PointerTests", "PointersAsArgsTest", 2, "PointersAsArgsTest", true},
- };
-
- [Theory]
- [MemberDataAttribute (nameof (PointersAsMethodArgsTestData))]
- public async Task InspectPrimitiveTypePointersAsMethodArgs (string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo)
- => await CheckInspectLocalsAtBreakpointSite (
- type, method, line_offset, bp_function_name,
- "window.setTimeout(function() { " + eval_fn + " })",
- use_cfo: use_cfo,
- wait_for_event_fn: async (pause_location) => {
- var locals = await GetProperties (pause_location ["callFrames"][0]["callFrameId"].Value<string>());
-
- var dt = new DateTime (5, 6, 7, 8, 9, 10);
- await CheckProps (locals, new {
- ip = TPointer ("int*"),
- ipp = TPointer ("int**"),
- ipa = TArray ("int*[]", 3),
- ippa = TArray ("int**[]", 5)
- }, "locals", num_fields: 8);
-
- // ip
- var props = await GetObjectOnLocals (locals, "ip");
- await CheckPointerValue (props, "*ip", TNumber (5), "locals");
-
- // ipp
- var ipp_props = await GetObjectOnLocals (locals, "ipp");
- await CheckPointerValue (ipp_props, "*ipp", TPointer ("int*"));
-
- ipp_props = await GetObjectOnLocals (ipp_props, "*ipp");
- await CheckPointerValue (ipp_props, "**ipp", TNumber (5));
-
- // ipa
- var ipa_elems = await CompareObjectPropertiesFor (locals, "ipa", new [] {
- TPointer ("int*"),
- TPointer ("int*"),
- TPointer ("int*", is_null: true)
- });
-
- await CheckArrayElements (ipa_elems, new [] {
- TNumber (5),
- TNumber (10),
- null
- });
-
- // ippa
- var ippa_elems = await CompareObjectPropertiesFor (locals, "ippa", new [] {
- TPointer ("int**"),
- TPointer ("int**"),
- TPointer ("int**"),
- TPointer ("int**"),
- TPointer ("int**", is_null: true)
- });
-
- {
- var actual_elems = await CheckArrayElements (ippa_elems, new [] {
- TPointer ("int*"),
- TPointer ("int*", is_null: true),
- TPointer ("int*"),
- TPointer ("int*", is_null: true),
- null
- });
-
- var val = await GetObjectOnLocals (actual_elems [0], "*[0]");
- await CheckPointerValue (val, "**[0]", TNumber (5));
-
- val = await GetObjectOnLocals (actual_elems [2], "*[2]");
- await CheckPointerValue (val, "**[2]", TNumber (5));
- }
- });
-
- [Theory]
- [MemberDataAttribute (nameof (PointersAsMethodArgsTestData))]
- public async Task InspectValueTypePointersAsMethodArgs (string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo)
- => await CheckInspectLocalsAtBreakpointSite (
- type, method, line_offset, bp_function_name,
- "window.setTimeout(function() { " + eval_fn + " })",
- use_cfo: use_cfo,
- wait_for_event_fn: async (pause_location) => {
- var locals = await GetProperties (pause_location ["callFrames"][0]["callFrameId"].Value<string>());
-
- var dt = new DateTime (5, 6, 7, 8, 9, 10);
- await CheckProps (locals, new {
- dtp = TPointer ("System.DateTime*"),
- dtpp = TPointer ("System.DateTime**"),
- dtpa = TArray ("System.DateTime*[]", 2),
- dtppa = TArray ("System.DateTime**[]", 3)
- }, "locals", num_fields: 8);
-
- // *dtp
- var dtp_props = await GetObjectOnLocals (locals, "dtp");
- await CheckDateTime (dtp_props, "*dtp", dt);
-
- // *dtpp
- var dtpp_props = await GetObjectOnLocals (locals, "dtpp");
- await CheckPointerValue (dtpp_props, "*dtpp", TPointer ("System.DateTime*"), "locals");
-
- dtpp_props = await GetObjectOnLocals (dtpp_props, "*dtpp");
- await CheckDateTime (dtpp_props, "**dtpp", dt);
-
- // dtpa
- var dtpa_elems = (await CompareObjectPropertiesFor (locals, "dtpa", new [] {
- TPointer ("System.DateTime*"),
- TPointer ("System.DateTime*", is_null: true)
- }));
- {
- var actual_elems = await CheckArrayElements (dtpa_elems, new [] {
- TValueType ("System.DateTime", dt.ToString ()),
- null
- });
-
- await CheckDateTime (actual_elems [0], "*[0]", dt);
- }
-
- // dtppa = new DateTime**[] { &dtp, &dtp_null, null };
- var dtppa_elems = (await CompareObjectPropertiesFor (locals, "dtppa", new [] {
- TPointer ("System.DateTime**"),
- TPointer ("System.DateTime**"),
- TPointer ("System.DateTime**", is_null: true)
- }));
-
- var exp_elems = new [] {
- TPointer ("System.DateTime*"),
- TPointer ("System.DateTime*", is_null: true),
- null
- };
-
- await CheckArrayElements (dtppa_elems, exp_elems);
- });
-
- [Theory]
- [InlineData ("invoke_static_method ('[debugger-test] Math:UseComplex', 0, 0);", "Math", "UseComplex", 3, "UseComplex", false)]
- [InlineData ("invoke_static_method ('[debugger-test] Math:UseComplex', 0, 0);", "Math", "UseComplex", 3, "UseComplex", true)]
- public async Task DerefNonPointerObject (string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo)
- => await CheckInspectLocalsAtBreakpointSite (
- type, method, line_offset, bp_function_name,
- "window.setTimeout(function() { " + eval_fn + " })",
- use_cfo: use_cfo,
- wait_for_event_fn: async (pause_location) => {
-
- // this will generate the object ids
- var locals = await GetProperties (pause_location ["callFrames"][0]["callFrameId"].Value<string>());
- var complex = GetAndAssertObjectWithName (locals, "complex");
-
- // try to deref the non-pointer object, as a pointer
- var props = await GetProperties (complex ["value"]["objectId"].Value<string> ().Replace (":object:", ":pointer:"));
- Assert.Empty (props.Values ());
-
- // try to deref an invalid pointer id
- props = await GetProperties ("dotnet:pointer:123897");
- Assert.Empty (props.Values ());
- });
-
- async Task<JToken[]> CheckArrayElements (JToken array, JToken[] exp_elems)
- {
- var actual_elems = new JToken [exp_elems.Length];
- for (int i = 0; i < exp_elems.Length; i ++) {
- if (exp_elems [i] != null) {
- actual_elems [i] = await GetObjectOnLocals (array, i.ToString ());
- await CheckPointerValue (actual_elems [i], $"*[{i}]", exp_elems [i], $"dtppa->");
- }
- }
-
- return actual_elems;
- }
- }
-} \ No newline at end of file
+ public class PointerTests : DebuggerTestBase
+ {
+
+ public static TheoryData<string, string, string, int, string, bool> PointersTestData =>
+ new TheoryData<string, string, string, int, string, bool>
+ { { $"invoke_static_method ('[debugger-test] DebuggerTests.PointerTests:LocalPointers');", "DebuggerTests.PointerTests", "LocalPointers", 32, "LocalPointers", false },
+ { $"invoke_static_method ('[debugger-test] DebuggerTests.PointerTests:LocalPointers');", "DebuggerTests.PointerTests", "LocalPointers", 32, "LocalPointers", true },
+ { $"invoke_static_method_async ('[debugger-test] DebuggerTests.PointerTests:LocalPointersAsync');", "DebuggerTests.PointerTests", "LocalPointersAsync", 32, "MoveNext", false },
+ { $"invoke_static_method_async ('[debugger-test] DebuggerTests.PointerTests:LocalPointersAsync');", "DebuggerTests.PointerTests", "LocalPointersAsync", 32, "MoveNext", true }
+ };
+
+ [Theory]
+ [MemberDataAttribute(nameof(PointersTestData))]
+ public async Task InspectLocalPointersToPrimitiveTypes(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite(
+ type, method, line_offset, bp_function_name,
+ "window.setTimeout(function() { " + eval_fn + " })",
+ use_cfo: use_cfo,
+ wait_for_event_fn: async (pause_location) =>
+ {
+ var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+
+ var dt = new DateTime(5, 6, 7, 8, 9, 10);
+ await CheckProps(locals, new
+ {
+ ip = TPointer("int*"),
+ ip_null = TPointer("int*", is_null: true),
+ ipp = TPointer("int**"),
+ ipp_null = TPointer("int**"),
+
+ cvalue0 = TSymbol("113 'q'"),
+ cp = TPointer("char*"),
+
+ vp = TPointer("void*"),
+ vp_null = TPointer("void*", is_null: true),
+ }, "locals", num_fields: 26);
+
+ var props = await GetObjectOnLocals(locals, "ip");
+ await CheckPointerValue(props, "*ip", TNumber(5), "locals");
+
+ {
+ var ipp_props = await GetObjectOnLocals(locals, "ipp");
+ await CheckPointerValue(ipp_props, "*ipp", TPointer("int*"));
+
+ ipp_props = await GetObjectOnLocals(ipp_props, "*ipp");
+ await CheckPointerValue(ipp_props, "**ipp", TNumber(5));
+ }
+
+ {
+ var ipp_props = await GetObjectOnLocals(locals, "ipp_null");
+ await CheckPointerValue(ipp_props, "*ipp_null", TPointer("int*", is_null: true));
+ }
+
+ // *cp
+ props = await GetObjectOnLocals(locals, "cp");
+ await CheckPointerValue(props, "*cp", TSymbol("113 'q'"));
+ });
+
+ [Theory]
+ [MemberDataAttribute(nameof(PointersTestData))]
+ public async Task InspectLocalPointerArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite(
+ type, method, line_offset, bp_function_name,
+ "window.setTimeout(function() { " + eval_fn + " })",
+ use_cfo: use_cfo,
+ wait_for_event_fn: async (pause_location) =>
+ {
+ var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+
+ var dt = new DateTime(5, 6, 7, 8, 9, 10);
+ await CheckProps(locals, new
+ {
+ ipa = TArray("int*[]", 3)
+ }, "locals", num_fields: 26);
+
+ var ipa_elems = await CompareObjectPropertiesFor(locals, "ipa", new[]
+ {
+ TPointer("int*"),
+ TPointer("int*"),
+ TPointer("int*", is_null : true)
+ });
+
+ await CheckArrayElements(ipa_elems, new[]
+ {
+ TNumber(5),
+ TNumber(10),
+ null
+ });
+ });
+
+ [Theory]
+ [MemberDataAttribute(nameof(PointersTestData))]
+ public async Task InspectLocalDoublePointerToPrimitiveTypeArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite(
+ type, method, line_offset, bp_function_name,
+ "window.setTimeout(function() { " + eval_fn + " })",
+ use_cfo: use_cfo,
+ wait_for_event_fn: async (pause_location) =>
+ {
+ var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+
+ var dt = new DateTime(5, 6, 7, 8, 9, 10);
+ await CheckProps(locals, new
+ {
+ ippa = TArray("int**[]", 5)
+ }, "locals", num_fields: 26);
+
+ var ippa_elems = await CompareObjectPropertiesFor(locals, "ippa", new[]
+ {
+ TPointer("int**"),
+ TPointer("int**"),
+ TPointer("int**"),
+ TPointer("int**"),
+ TPointer("int**", is_null : true)
+ });
+
+ {
+ var actual_elems = await CheckArrayElements(ippa_elems, new[]
+ {
+ TPointer("int*"),
+ TPointer("int*", is_null : true),
+ TPointer("int*"),
+ TPointer("int*", is_null : true),
+ null
+ });
+
+ var val = await GetObjectOnLocals(actual_elems[0], "*[0]");
+ await CheckPointerValue(val, "**[0]", TNumber(5));
+
+ val = await GetObjectOnLocals(actual_elems[2], "*[2]");
+ await CheckPointerValue(val, "**[2]", TNumber(5));
+ }
+ });
+
+ [Theory]
+ [MemberDataAttribute(nameof(PointersTestData))]
+ public async Task InspectLocalPointersToValueTypes(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite(
+ type, method, line_offset, bp_function_name,
+ "window.setTimeout(function() { " + eval_fn + " })",
+ use_cfo: use_cfo,
+ wait_for_event_fn: async (pause_location) =>
+ {
+ var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+
+ var dt = new DateTime(5, 6, 7, 8, 9, 10);
+ await CheckProps(locals, new
+ {
+ dt = TValueType("System.DateTime", dt.ToString()),
+ dtp = TPointer("System.DateTime*"),
+ dtp_null = TPointer("System.DateTime*", is_null: true),
+
+ gsp = TPointer("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>*"),
+ gsp_null = TPointer("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>*")
+ }, "locals", num_fields: 26);
+
+ await CheckDateTime(locals, "dt", dt);
+
+ // *dtp
+ var props = await GetObjectOnLocals(locals, "dtp");
+ await CheckDateTime(props, "*dtp", dt);
+
+ var gsp_props = await GetObjectOnLocals(locals, "gsp");
+ await CheckPointerValue(gsp_props, "*gsp", TValueType("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>"), "locals#gsp");
+
+ {
+ var gs_dt = new DateTime(1, 2, 3, 4, 5, 6);
+
+ var gsp_deref_props = await GetObjectOnLocals(gsp_props, "*gsp");
+ await CheckProps(gsp_deref_props, new
+ {
+ Value = TValueType("System.DateTime", gs_dt.ToString()),
+ IntField = TNumber(4),
+ DTPP = TPointer("System.DateTime**")
+ }, "locals#gsp#deref");
+ {
+ var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP");
+ await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*"), "locals#*gsp");
+
+ var dtpp_deref_props = await GetObjectOnLocals(dtpp_props, "*DTPP");
+ await CheckDateTime(dtpp_deref_props, "**DTPP", dt);
+ }
+ }
+
+ // gsp_null
+ var gsp_w_n_props = await GetObjectOnLocals(locals, "gsp_null");
+ await CheckPointerValue(gsp_w_n_props, "*gsp_null", TValueType("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>"), "locals#gsp");
+
+ {
+ var gs_dt = new DateTime(1, 2, 3, 4, 5, 6);
+
+ var gsp_deref_props = await GetObjectOnLocals(gsp_w_n_props, "*gsp_null");
+ await CheckProps(gsp_deref_props, new
+ {
+ Value = TValueType("System.DateTime", gs_dt.ToString()),
+ IntField = TNumber(4),
+ DTPP = TPointer("System.DateTime**")
+ }, "locals#gsp#deref");
+ {
+ var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP");
+ await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*", is_null: true), "locals#*gsp");
+ }
+ }
+ });
+
+ [Theory]
+ [MemberDataAttribute(nameof(PointersTestData))]
+ public async Task InspectLocalPointersToValueTypeArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite(
+ type, method, line_offset, bp_function_name,
+ "window.setTimeout(function() { " + eval_fn + " })",
+ use_cfo: use_cfo,
+ wait_for_event_fn: async (pause_location) =>
+ {
+ var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+
+ var dt = new DateTime(5, 6, 7, 8, 9, 10);
+ await CheckProps(locals, new
+ {
+ dtpa = TArray("System.DateTime*[]", 2)
+ }, "locals", num_fields: 26);
+
+ // dtpa
+ var dtpa_elems = (await CompareObjectPropertiesFor(locals, "dtpa", new[]
+ {
+ TPointer("System.DateTime*"),
+ TPointer("System.DateTime*", is_null : true)
+ }));
+ {
+ var actual_elems = await CheckArrayElements(dtpa_elems, new[]
+ {
+ TValueType("System.DateTime", dt.ToString()),
+ null
+ });
+
+ await CheckDateTime(actual_elems[0], "*[0]", dt);
+ }
+ });
+
+ [Theory]
+ [MemberDataAttribute(nameof(PointersTestData))]
+ public async Task InspectLocalPointersToGenericValueTypeArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite(
+ type, method, line_offset, bp_function_name,
+ "window.setTimeout(function() { " + eval_fn + " })",
+ use_cfo: use_cfo,
+ wait_for_event_fn: async (pause_location) =>
+ {
+ var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+
+ var dt = new DateTime(5, 6, 7, 8, 9, 10);
+ await CheckProps(locals, new
+ {
+ gspa = TArray("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>*[]", 3),
+ }, "locals", num_fields: 26);
+
+ // dtpa
+ var gspa_elems = await CompareObjectPropertiesFor(locals, "gspa", new[]
+ {
+ TPointer("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>*", is_null : true),
+ TPointer("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>*"),
+ TPointer("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>*"),
+ });
+ {
+ var gs_dt = new DateTime(1, 2, 3, 4, 5, 6);
+ var actual_elems = await CheckArrayElements(gspa_elems, new[]
+ {
+ null,
+ TValueType("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>"),
+ TValueType("DebuggerTests.GenericStructWithUnmanagedT<System.DateTime>")
+ });
+
+ // *[1]
+ {
+ var gsp_deref_props = await GetObjectOnLocals(actual_elems[1], "*[1]");
+ await CheckProps(gsp_deref_props, new
+ {
+ Value = TValueType("System.DateTime", gs_dt.ToString()),
+ IntField = TNumber(4),
+ DTPP = TPointer("System.DateTime**")
+ }, "locals#gsp#deref");
+ {
+ var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP");
+ await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*"), "locals#*gsp");
+
+ dtpp_props = await GetObjectOnLocals(dtpp_props, "*DTPP");
+ await CheckDateTime(dtpp_props, "**DTPP", dt);
+ }
+ }
+
+ // *[2]
+ {
+ var gsp_deref_props = await GetObjectOnLocals(actual_elems[2], "*[2]");
+ await CheckProps(gsp_deref_props, new
+ {
+ Value = TValueType("System.DateTime", gs_dt.ToString()),
+ IntField = TNumber(4),
+ DTPP = TPointer("System.DateTime**")
+ }, "locals#gsp#deref");
+ {
+ var dtpp_props = await GetObjectOnLocals(gsp_deref_props, "DTPP");
+ await CheckPointerValue(dtpp_props, "*DTPP", TPointer("System.DateTime*", is_null: true), "locals#*gsp");
+ }
+ }
+ }
+ });
+
+ [Theory]
+ [MemberDataAttribute(nameof(PointersTestData))]
+ public async Task InspectLocalDoublePointersToValueTypeArrays(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite(
+ type, method, line_offset, bp_function_name,
+ "window.setTimeout(function() { " + eval_fn + " })",
+ use_cfo: use_cfo,
+ wait_for_event_fn: async (pause_location) =>
+ {
+ var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+
+ var dt = new DateTime(5, 6, 7, 8, 9, 10);
+ await CheckProps(locals, new
+ {
+ dtppa = TArray("System.DateTime**[]", 3),
+ }, "locals", num_fields: 26);
+
+ // DateTime**[] dtppa = new DateTime**[] { &dtp, &dtp_null, null };
+ var dtppa_elems = (await CompareObjectPropertiesFor(locals, "dtppa", new[]
+ {
+ TPointer("System.DateTime**"),
+ TPointer("System.DateTime**"),
+ TPointer("System.DateTime**", is_null : true)
+ }));
+
+ var exp_elems = new[]
+ {
+ TPointer("System.DateTime*"),
+ TPointer("System.DateTime*", is_null : true),
+ null
+ };
+
+ var actual_elems = new JToken[exp_elems.Length];
+ for (int i = 0; i < exp_elems.Length; i++)
+ {
+ if (exp_elems[i] != null)
+ {
+ actual_elems[i] = await GetObjectOnLocals(dtppa_elems, i.ToString());
+ await CheckPointerValue(actual_elems[i], $"*[{i}]", exp_elems[i], $"dtppa->");
+ }
+ }
+ });
+
+ [Theory]
+ [MemberDataAttribute(nameof(PointersTestData))]
+ public async Task InspectLocalPointersInClasses(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite(
+ type, method, line_offset, bp_function_name,
+ "window.setTimeout(function() { " + eval_fn + " })",
+ use_cfo: use_cfo,
+ wait_for_event_fn: async (pause_location) =>
+ {
+ var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+
+ var dt = new DateTime(5, 6, 7, 8, 9, 10);
+ await CheckProps(locals, new
+ {
+ cwp = TObject("DebuggerTests.GenericClassWithPointers<System.DateTime>"),
+ cwp_null = TObject("DebuggerTests.GenericClassWithPointers<System.DateTime>")
+ }, "locals", num_fields: 26);
+
+ var cwp_props = await GetObjectOnLocals(locals, "cwp");
+ var ptr_props = await GetObjectOnLocals(cwp_props, "Ptr");
+ await CheckDateTime(ptr_props, "*Ptr", dt);
+ });
+
+ public static TheoryData<string, string, string, int, string, bool> PointersAsMethodArgsTestData =>
+ new TheoryData<string, string, string, int, string, bool>
+ { { $"invoke_static_method ('[debugger-test] DebuggerTests.PointerTests:LocalPointers');", "DebuggerTests.PointerTests", "PointersAsArgsTest", 2, "PointersAsArgsTest", false },
+ { $"invoke_static_method ('[debugger-test] DebuggerTests.PointerTests:LocalPointers');", "DebuggerTests.PointerTests", "PointersAsArgsTest", 2, "PointersAsArgsTest", true },
+ };
+
+ [Theory]
+ [MemberDataAttribute(nameof(PointersAsMethodArgsTestData))]
+ public async Task InspectPrimitiveTypePointersAsMethodArgs(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite(
+ type, method, line_offset, bp_function_name,
+ "window.setTimeout(function() { " + eval_fn + " })",
+ use_cfo: use_cfo,
+ wait_for_event_fn: async (pause_location) =>
+ {
+ var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+
+ var dt = new DateTime(5, 6, 7, 8, 9, 10);
+ await CheckProps(locals, new
+ {
+ ip = TPointer("int*"),
+ ipp = TPointer("int**"),
+ ipa = TArray("int*[]", 3),
+ ippa = TArray("int**[]", 5)
+ }, "locals", num_fields: 8);
+
+ // ip
+ var props = await GetObjectOnLocals(locals, "ip");
+ await CheckPointerValue(props, "*ip", TNumber(5), "locals");
+
+ // ipp
+ var ipp_props = await GetObjectOnLocals(locals, "ipp");
+ await CheckPointerValue(ipp_props, "*ipp", TPointer("int*"));
+
+ ipp_props = await GetObjectOnLocals(ipp_props, "*ipp");
+ await CheckPointerValue(ipp_props, "**ipp", TNumber(5));
+
+ // ipa
+ var ipa_elems = await CompareObjectPropertiesFor(locals, "ipa", new[]
+ {
+ TPointer("int*"),
+ TPointer("int*"),
+ TPointer("int*", is_null : true)
+ });
+
+ await CheckArrayElements(ipa_elems, new[]
+ {
+ TNumber(5),
+ TNumber(10),
+ null
+ });
+
+ // ippa
+ var ippa_elems = await CompareObjectPropertiesFor(locals, "ippa", new[]
+ {
+ TPointer("int**"),
+ TPointer("int**"),
+ TPointer("int**"),
+ TPointer("int**"),
+ TPointer("int**", is_null : true)
+ });
+
+ {
+ var actual_elems = await CheckArrayElements(ippa_elems, new[]
+ {
+ TPointer("int*"),
+ TPointer("int*", is_null : true),
+ TPointer("int*"),
+ TPointer("int*", is_null : true),
+ null
+ });
+
+ var val = await GetObjectOnLocals(actual_elems[0], "*[0]");
+ await CheckPointerValue(val, "**[0]", TNumber(5));
+
+ val = await GetObjectOnLocals(actual_elems[2], "*[2]");
+ await CheckPointerValue(val, "**[2]", TNumber(5));
+ }
+ });
+
+ [Theory]
+ [MemberDataAttribute(nameof(PointersAsMethodArgsTestData))]
+ public async Task InspectValueTypePointersAsMethodArgs(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite(
+ type, method, line_offset, bp_function_name,
+ "window.setTimeout(function() { " + eval_fn + " })",
+ use_cfo: use_cfo,
+ wait_for_event_fn: async (pause_location) =>
+ {
+ var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+
+ var dt = new DateTime(5, 6, 7, 8, 9, 10);
+ await CheckProps(locals, new
+ {
+ dtp = TPointer("System.DateTime*"),
+ dtpp = TPointer("System.DateTime**"),
+ dtpa = TArray("System.DateTime*[]", 2),
+ dtppa = TArray("System.DateTime**[]", 3)
+ }, "locals", num_fields: 8);
+
+ // *dtp
+ var dtp_props = await GetObjectOnLocals(locals, "dtp");
+ await CheckDateTime(dtp_props, "*dtp", dt);
+
+ // *dtpp
+ var dtpp_props = await GetObjectOnLocals(locals, "dtpp");
+ await CheckPointerValue(dtpp_props, "*dtpp", TPointer("System.DateTime*"), "locals");
+
+ dtpp_props = await GetObjectOnLocals(dtpp_props, "*dtpp");
+ await CheckDateTime(dtpp_props, "**dtpp", dt);
+
+ // dtpa
+ var dtpa_elems = (await CompareObjectPropertiesFor(locals, "dtpa", new[]
+ {
+ TPointer("System.DateTime*"),
+ TPointer("System.DateTime*", is_null : true)
+ }));
+ {
+ var actual_elems = await CheckArrayElements(dtpa_elems, new[]
+ {
+ TValueType("System.DateTime", dt.ToString()),
+ null
+ });
+
+ await CheckDateTime(actual_elems[0], "*[0]", dt);
+ }
+
+ // dtppa = new DateTime**[] { &dtp, &dtp_null, null };
+ var dtppa_elems = (await CompareObjectPropertiesFor(locals, "dtppa", new[]
+ {
+ TPointer("System.DateTime**"),
+ TPointer("System.DateTime**"),
+ TPointer("System.DateTime**", is_null : true)
+ }));
+
+ var exp_elems = new[]
+ {
+ TPointer("System.DateTime*"),
+ TPointer("System.DateTime*", is_null : true),
+ null
+ };
+
+ await CheckArrayElements(dtppa_elems, exp_elems);
+ });
+
+ [Theory]
+ [InlineData("invoke_static_method ('[debugger-test] Math:UseComplex', 0, 0);", "Math", "UseComplex", 3, "UseComplex", false)]
+ [InlineData("invoke_static_method ('[debugger-test] Math:UseComplex', 0, 0);", "Math", "UseComplex", 3, "UseComplex", true)]
+ public async Task DerefNonPointerObject(string eval_fn, string type, string method, int line_offset, string bp_function_name, bool use_cfo) => await CheckInspectLocalsAtBreakpointSite(
+ type, method, line_offset, bp_function_name,
+ "window.setTimeout(function() { " + eval_fn + " })",
+ use_cfo: use_cfo,
+ wait_for_event_fn: async (pause_location) =>
+ {
+
+ // this will generate the object ids
+ var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+ var complex = GetAndAssertObjectWithName(locals, "complex");
+
+ // try to deref the non-pointer object, as a pointer
+ await GetProperties(complex["value"]["objectId"].Value<string>().Replace(":object:", ":pointer:"), expect_ok: false);
+
+ // try to deref an invalid pointer id
+ await GetProperties("dotnet:pointer:123897", expect_ok: false);
+ });
+
+ async Task<JToken[]> CheckArrayElements(JToken array, JToken[] exp_elems)
+ {
+ var actual_elems = new JToken[exp_elems.Length];
+ for (int i = 0; i < exp_elems.Length; i++)
+ {
+ if (exp_elems[i] != null)
+ {
+ actual_elems[i] = await GetObjectOnLocals(array, i.ToString());
+ await CheckPointerValue(actual_elems[i], $"*[{i}]", exp_elems[i], $"dtppa->");
+ }
+ }
+
+ return actual_elems;
+ }
+ }
+}