Skip to content

Implement natvis 'na' modifier and $T substitution - #1612

Open
SachinM123 wants to merge 7 commits into
microsoft:mainfrom
SachinM123:natvisFormatSpecifierFix
Open

Implement natvis 'na' modifier and $T substitution#1612
SachinM123 wants to merge 7 commits into
microsoft:mainfrom
SachinM123:natvisFormatSpecifierFix

Conversation

@SachinM123

Copy link
Copy Markdown
Collaborator

Add support for the natvis 'na' (no-address) modifier to strip MI's leading address prefix from string values. This requires tracking the format specifier through variable initialization and applying cleanup at value retrieval points.

Also implement template parameter substitution ($T1, $T2, etc.) within natvis brace expressions before format specifier extraction.

Add support for the natvis 'na' (no-address) modifier to strip MI's leading address prefix from string values. This requires tracking the format specifier through variable initialization and applying cleanup at value retrieval points.

Also implement template parameter substitution ($T1, $T2, etc.) within natvis brace expressions before format specifier extraction.
Comment thread src/MIDebugEngine/Engine.Impl/Variables.cs Outdated
Comment thread src/MIDebugEngine/Engine.Impl/Variables.cs Outdated
Comment thread src/MIDebugEngine/Engine.Impl/Variables.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends MIEngine’s NatVis evaluator to (1) support the na (no-address) modifier by stripping MI’s leading 0x... address prefix from certain evaluated values, and (2) perform $T1, $T2, … template-parameter substitution inside NatVis brace expressions before parsing format specifiers.

Changes:

  • Add $Tn macro substitution over full {...} brace expressions in Natvis display-string formatting.
  • Detect and apply na address-prefix stripping during NatVis display-string formatting and during variable evaluation/initialization by tracking an _formatHasNa flag.
  • Update NatVis string “cleanup” helpers and related comments around address-prefix stripping behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
src/MIDebugEngine/Natvis.Impl/Natvis.cs Adds $Tn substitution in brace expressions and introduces na detection/cleanup in display-string formatting; updates format-specifier helpers and string cleanup docs.
src/MIDebugEngine/Engine.Impl/Variables.cs Tracks na in parsed format specifiers and attempts to strip MI’s address prefix at variable construction/evaluation time.

Comment thread src/MIDebugEngine/Natvis.Impl/Natvis.cs Outdated
Comment thread src/MIDebugEngine/Natvis.Impl/Natvis.cs
Comment thread src/MIDebugEngine/Natvis.Impl/Natvis.cs Outdated
Comment thread src/MIDebugEngine/Engine.Impl/Variables.cs
Comment thread src/MIDebugEngine/Engine.Impl/Variables.cs Outdated
Comment thread src/MIDebugEngine/Engine.Impl/Variables.cs Outdated
Comment thread src/MIDebugEngine/Engine.Impl/Variables.cs Outdated
Comment thread src/MIDebugEngine/Natvis.Impl/Natvis.cs Outdated
Comment thread src/MIDebugEngine/Natvis.Impl/Natvis.cs Outdated
Comment thread src/MIDebugEngine/Natvis.Impl/Natvis.cs
Comment thread src/MIDebugEngine/Natvis.Impl/Natvis.cs
Comment thread src/MIDebugEngine/Natvis.Impl/Natvis.cs Outdated
@gregg-miskelly

Copy link
Copy Markdown
Member

Can you add a test for your changes? You may also need to adjust a test baseline for su since the code was doing the wrong thing there.

@SachinM123

Copy link
Copy Markdown
Collaborator Author

Can you add a test for your changes? You may also need to adjust a test baseline for su since the code was doing the wrong thing there.

The test seems to get properly handled via TestDisplayString in NatvisTests to me

Comment thread src/MIDebugEngine/Engine.Impl/Variables.cs Outdated
Comment thread src/MIDebugEngine/Natvis.Impl/Natvis.cs
Comment thread src/MIDebugEngine/Natvis.Impl/Natvis.cs
Comment thread src/MIDebugEngine/Engine.Impl/Variables.cs Outdated
match tests with out param from extractformatspecifier

made VariableInformation.StripLeadingAddress internal static to make public and updated natvis.cs accordingly

changed _formathasna to inherit properly and call stripleadingaddress more strictly
Comment thread src/MIDebugEngine/Engine.Impl/Variables.cs Outdated
Comment thread src/MIDebugEngine/Natvis.Impl/Natvis.cs Outdated
Comment thread src/MIDebugEngine/Natvis.Impl/Natvis.cs
string tail = expression.Substring(commaPos + 1).Trim();
hasNa = tail.IndexOf("na", StringComparison.Ordinal) >= 0;

return expression.Substring(commaPos + 1).Trim()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expression.Substring(commaPos + 1).Trim()

Replace with tail

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Suppressed comments (5)

src/MIDebugEngine/Natvis.Impl/Natvis.cs:1521

  • There is an extra standalone XML <summary> block immediately before CleanUtf16StringValue which results in back-to-back <summary> tags. This will produce malformed/incorrect XML documentation. Either remove the orphaned summary or convert it into a proper doc comment on a real member (or merge it into the existing ExtractFormatSpecifier docs).
        /// <summary>
        /// Returns true if the NatVis expression's trailing format specifier (the part after the
        /// last top-level comma) contains the "na" modifier. This intentionally inspects the
        /// raw specifier text and does not normalize/remove modifiers so callers can detect
        /// whether the original expression asked for the "na" behavior.
        /// </summary>
        /// <summary>
        /// Cleans up the raw value that GDB/LLDB returns for a <c>const char16_t*</c>

src/MIDebugEngine/Natvis.Impl/Natvis.cs:1526

  • The updated doc comment for CleanUtf16StringValue says it does NOT remove surrounding quotes or the u/U prefix, but the method still strips both (it removes the u\"/U\" prefix and the trailing \", then returns the substring). Please update the comment to match the actual behavior, or adjust the implementation if the new behavior is intended.
        /// This method strips the leading address prefix that GDB/LLDB emits ("0x... ").
        /// It does NOT remove surrounding quotes or the leading character-width prefix (u/U).

src/MIDebugEngine/Natvis.Impl/Natvis.cs:1536

  • The updated doc comment for CleanUtf16StringValue says it does NOT remove surrounding quotes or the u/U prefix, but the method still strips both (it removes the u\"/U\" prefix and the trailing \", then returns the substring). Please update the comment to match the actual behavior, or adjust the implementation if the new behavior is intended.
            if (value.Length >= 3 && (value.StartsWith("u\"", StringComparison.Ordinal) || value.StartsWith("U\"", StringComparison.Ordinal)))
            {
                value = value.EndsWith("\"", StringComparison.Ordinal)

src/MIDebugEngine/Natvis.Impl/Natvis.cs:1511

  • The na detection/removal is substring-based (IndexOf(\"na\") / .Replace(\"na\", \"\")), which can create false positives and/or corrupt specifiers that legitimately contain na as part of another token (e.g., a function/identifier containing na). Consider parsing known Natvis modifiers as actual modifiers (e.g., stripping only recognized modifier sequences at the end of the specifier) rather than removing arbitrary na substrings anywhere in the specifier text.
            string tail = expression.Substring(commaPos + 1).Trim();
            hasNa = tail.IndexOf("na", StringComparison.Ordinal) >= 0;

            return expression.Substring(commaPos + 1).Trim()
                .Replace("nvo", "").Replace("na", "").Replace("nr", "").Replace("nd", "");

src/MIDebugEngine/Engine.Impl/Variables.cs:106

  • The new StripLeadingAddress behavior is central to the na modifier, but there’s no unit coverage shown here for typical MI string shapes (e.g., 0x0123 \"Hello\", 0x0123 u\"Hello\", values without an address prefix, and address-only values). Adding focused unit tests for StripLeadingAddress (and at least one integration-style test demonstrating na affecting a formatted Natvis expression) would help prevent regressions.
        internal static string StripLeadingAddress(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return value;
            }

            return s_naPattern.Replace(value, "$1");
        }

Comment thread src/MIDebugEngine/Engine.Impl/Variables.cs
Comment thread src/MIDebugEngine/Natvis.Impl/Natvis.cs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants