Skip to content

Improve handling of compound format specifiers in Natvis#1523

Merged
gregg-miskelly merged 2 commits into
microsoft:mainfrom
iridinite:bugfix/natvis-format
Sep 23, 2025
Merged

Improve handling of compound format specifiers in Natvis#1523
gregg-miskelly merged 2 commits into
microsoft:mainfrom
iridinite:bugfix/natvis-format

Conversation

@iridinite

@iridinite iridinite commented Sep 17, 2025

Copy link
Copy Markdown
Contributor

(⚠️ Note: This PR requires #1522 to be merged before it can be tested)

These three cases were not recognized by the format specifier parser:

  • The nvo, na, nr and nd specifiers may appear together with another specifier, e.g. nvoXb is a valid format specifier.
  • Arrays with static size specifiers may contain additional format specifiers, e.g. ptr,[10]s8 is a valid expression.
  • Arrays with dynamic size specifiers may contain full C++ expressions in them, e.g. ptr,[mLength-mFree] is valid.

Without this change, the full expression e.g. (foo).bar,nvoXb would be passed to LLDB, which obviously yields a compilation error.

None of these three cases can be implemented easily with the tools we currently have available (as far as I'm aware), but by ensuring we at least recognize and strip such format specifiers, Natvis does not break completely.

Min repro

Say we want to implement a custom UUID type, where we want to use Natvis to render a 16-byte array as a nice string:

struct UUID
{
	union
	{
		unsigned char mData[16];
		unsigned long long mDataWide[2];
	};
};

int main(int argc, char* argv[])
{
	UUID uuid;
	uuid.mDataWide[0] = 0x1234567898765432;
	uuid.mDataWide[1] = 0xABCDEF9FEDCBAF00;

	__builtin_debugtrap();
}

Natvis:

<Type Name="UUID">
	<DisplayString>UUID {mData[0],nvoXb}{mData[1],nvoXb}{mData[2],nvoXb}{mData[3],nvoXb}-{mData[4],nvoXb}{mData[5],nvoXb}-{mData[6],nvoXb}{mData[7],nvoXb}-{mData[8],nvoXb}{mData[9],nvoXb}-{mData[10],nvoXb}{mData[11],nvoXb}{mData[12],nvoXb}{mData[13],nvoXb}{mData[14],nvoXb}{mData[15],nvoXb}</DisplayString>
</Type>

Before

LI6Ez19fQo

After

NOOoQvJfbz

@gregg-miskelly gregg-miskelly left a comment

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.

Thanks for submitting all these! Aside from that this looks good to me.

Comment thread src/MIDebugEngine/Engine.Impl/Variables.cs
Comment thread src/MIDebugEngine/Engine.Impl/Variables.cs Outdated
These three cases were not recognized by the format specifier parser:

- The nvo, na, nr and nd specifiers may appear together with another
  specifier, e.g. 'nvoXb' is a valid format specifier.
- Arrays with static size specifiers may contain additional format
  specifiers, e.g. 'ptr,[10]s8' is a valid expression.
- Arrays with dynamic size specifiers may contain full C++ expressions
  in them, e.g. 'ptr,[mLength-mFree]' is valid.

Without this change, the full expression e.g. '(foo).bar,nvoXb' would be
passed to LLDB, which obviously yields a compilation error.

Neither of these two cases can be implemented easily with the tools we
currently have available, but by ensuring we at least recognize and strip
such format specifiers, Natvis does not break completely.
@gregg-miskelly gregg-miskelly merged commit 8b684ad into microsoft:main Sep 23, 2025
6 checks passed
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.

2 participants