Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions src/OpenDebugAD7/AD7Utils.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
Expand All @@ -20,7 +20,23 @@ public static bool IsAnnotatedFrame(ref FRAMEINFO frameInfo)

public static string GetMemoryReferenceFromIDebugProperty(IDebugProperty2 property)
{
if (property != null && property.GetMemoryContext(out IDebugMemoryContext2 memoryContext) == HRConstants.S_OK)
if (property == null)
{
return null;
}

// Only a pointer or an array holds an address a memoryReference can point at.
// For any other type the value is not an address, so a memoryReference would
// make the client show a memory view that navigates to the value itself. The
// engine's GetMemoryContext still resolves an address for any type, which the
// Visual Studio Memory and Disassembly windows rely on; the restriction here
// applies only to the reference reported over DAP.
if (!IsPointerOrArray(property))
{
return null;
}

if (property.GetMemoryContext(out IDebugMemoryContext2 memoryContext) == HRConstants.S_OK)
{
CONTEXT_INFO[] contextInfo = new CONTEXT_INFO[1];
if (memoryContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, contextInfo) == HRConstants.S_OK)
Expand All @@ -34,5 +50,29 @@ public static string GetMemoryReferenceFromIDebugProperty(IDebugProperty2 proper

return null;
}

private static bool IsPointerOrArray(IDebugProperty2 property)
{
DEBUG_PROPERTY_INFO[] propertyInfo = new DEBUG_PROPERTY_INFO[1];
if (property.GetPropertyInfo(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_TYPE, Constants.EvaluationRadix, Constants.EvaluationTimeout, null, 0, propertyInfo) != HRConstants.S_OK)
{
return false;
}

if (!propertyInfo[0].dwFields.HasFlag(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_TYPE))
{
return false;
}

string typeName = propertyInfo[0].bstrType;
if (string.IsNullOrEmpty(typeName))
{
return false;
}

typeName = typeName.TrimEnd();
return typeName.EndsWith("*", StringComparison.Ordinal) // pointer, e.g. "int *"
|| typeName.EndsWith("]", StringComparison.Ordinal); // array, e.g. "int [10]"
}
}
}
Loading