Skip to content
Open
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
e5c9ddc
Natvis: add IncludeView/ExcludeView and view() specifier support
lugerard Jun 4, 2026
973c608
Natvis: implement CustomListItems loop engine
lugerard Jun 10, 2026
8337b7f
Merge branch 'main' into natvis-view-customlistitems
gregg-miskelly Jun 21, 2026
d23e5a4
Natvis: rename CustomListItems loop-body types to match natvis.xsd
lugerard Jun 22, 2026
9507c92
Natvis: warn on unexpected loop-body elements, and warn+stop on faile…
lugerard Jun 24, 2026
f14a055
Natvis: support multi-variable <Exec> and fix <Exec> assignment handling
lugerard Jun 24, 2026
3f171bb
Natvis: share the loop driver between the top-level and nested <Loop>
lugerard Jun 24, 2026
5de0de3
Natvis: fix CustomListItems local variable handling
lugerard Jun 24, 2026
a81b391
Natvis: add end-to-end CustomListItems test
lugerard Jun 30, 2026
27f11f6
Natvis: add end-to-end view-filtering test
lugerard Jul 3, 2026
4e56382
Natvis: support the view() format specifier on watch expressions
lugerard Jul 3, 2026
da46726
Merge remote-tracking branch 'fork/natvis-view-customlistitems' into …
lugerard Jul 3, 2026
3b07336
Merge branch 'microsoft:main' into natvis-view-customlistitems
lugerard Jul 3, 2026
a150bc6
Merge remote-tracking branch 'fork/natvis-view-customlistitems' into …
lugerard Jul 3, 2026
21bea02
Natvis: stop the CustomListItems loop when an <Exec> segment cannot b…
lugerard Jul 7, 2026
1a1fffa
Natvis: store CustomListItems loop variables compactly to keep large …
lugerard Jul 7, 2026
972b00c
Natvis: resume CustomListItems pagination from saved loop state
lugerard Jul 7, 2026
7bba548
Natvis: fall back to Break-driven termination when <Size> cannot be p…
lugerard Jul 10, 2026
8abc0a0
Natvis: compact integer loop variables when the engine radix is 16
lugerard Jul 10, 2026
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
4 changes: 2 additions & 2 deletions src/MIDebugEngine/AD7.Impl/AD7Property.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public DEBUG_PROPERTY_INFO ConstructDebugPropertyInfo(enum_DEBUGPROP_INFO_FLAGS

if ((dwFields & enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE) != 0)
{
(propertyInfo.bstrValue, _uiVisualizers) = _engine.DebuggedProcess.Natvis.FormatDisplayString(variable);
(propertyInfo.bstrValue, _uiVisualizers) = _engine.DebuggedProcess.Natvis.FormatDisplayString(variable, variable.NatvisView);
propertyInfo.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE;
}

Expand Down Expand Up @@ -154,7 +154,7 @@ public int EnumChildren(enum_DEBUGPROP_INFO_FLAGS dwFields, uint dwRadix, ref Gu
try
{
_engine.DebuggedProcess.Natvis.WaitDialog.ShowWaitDialog(_variableInformation.Name);
var children = _engine.DebuggedProcess.Natvis.Expand(_variableInformation);
var children = _engine.DebuggedProcess.Natvis.Expand(_variableInformation, _variableInformation.NatvisView);

// Count number of children that fit filter (results saved in "fitsFilter")
int propertyCount = children.Length;
Expand Down
15 changes: 15 additions & 0 deletions src/MIDebugEngine/Engine.Impl/Variables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ internal interface IVariableInformation : IDisposable
VariableInformation FindChildByName(string name);
string EvalDependentExpression(string expr);
bool IsVisualized { get; }
string NatvisView { get; }
bool IsReadOnly();
bool IsNullPointer();
enum_DEBUGPROP_INFO_FLAGS PropertyInfoFlags { get; set; }
Expand Down Expand Up @@ -375,6 +376,7 @@ public VariableInformation FindChildByName(string name)
private DeferedFormatExpression _deferedFormatExpression;
private IVariableInformation _parent;
private string _format;
private string _natvisView; // view name from a "view(name)" format specifier
private string _strippedName; // "Name" stripped of format specifiers
private string _fullname;

Expand All @@ -392,6 +394,8 @@ public enum NodeType

public NodeType VariableNodeType { get; private set; }

public string NatvisView { get { return _natvisView; } }

private static readonly string[] s_stringTypes = new string[] {
@"^char *\*$",
@"^char *\[[0-9]*\]$",
Expand All @@ -417,6 +421,17 @@ private string ProcessFormatSpecifiers(string exp, out string formatSpecifier)
// Find the format specifier expression
string expFS = exp.Substring(lastComma + 1).Trim();

// A view() specifier (e.g. "obj,view(simple)") selects a named natvis view; it is
// consumed by natvis formatting/expansion rather than the debugger. Handle it before
// the modifier stripping below, which could corrupt a view name that contains one of
// the modifier letter pairs (e.g. "view(second)").
string viewName = Natvis.Natvis.ExtractViewName(expFS);
if (viewName != null)
{
_natvisView = viewName;
return exp.Substring(0, lastComma);
}

// Strip off modifiers that may be included together with another format specifier, e.g. 'nvoXb' is a valid format specifier, but we only care about the 'Xb' part
// This is not quite the right fix -- really the below switch statement should be a series of if statements. But since none of the supported format specifiers
// contain any of these characters we can fix this the simple way and remove them.
Expand Down
826 changes: 800 additions & 26 deletions src/MIDebugEngine/Natvis.Impl/Natvis.cs

Large diffs are not rendered by default.

Loading