如何使用Natvis正确显示多个同类型uint32_t*变量?
问题:Natvis配置实现同类型指针变量分别显示
我尝试通过Natvis配置显示两个uint32_t*类型变量pointer_array_1和limit_ptr,但遇到显示异常问题,具体情况如下:
测试代码(sample.cpp)
#include<iostream> int main() { uint32_t foo_array[5] = {5,15,96,8,77}; // 原代码中obj_1未定义,此处保留原结构 // obj_1.pointer_array = foo_array; uint32_t * pointer_array_1 = foo_array; uint32_t limit_array[10]; for(int i = 0; i < 10; i++) { limit_array[i] = i*5; } uint32_t *limit_ptr = limit_array; return 0; }
首次Natvis配置(test_file.natvis)及问题
<?xml version="1.0" encoding="utf-8"?> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> <Type Name="uint32_t *"> <DisplayString>Test IndexListItems</DisplayString> <Expand> <IndexListItems> <Size>5</Size> <ValueNode>pointer_array_1[$i]</ValueNode> </IndexListItems> </Expand> </Type> <Type Name="uint32_t *"> <DisplayString>Would like to observe limited or preferred ranged value</DisplayString> <Expand> <IndexListItems> <Size>10</Size> <ValueNode>limit_ptr[$i]</ValueNode> </IndexListItems> </Expand> </Type> </AutoVisualizer>
- 问题:
limit_ptr显示内容与pointer_array_1完全一致,无法正确展示指向的数组值。原因是Natvis会优先匹配第一个同名的Type节点,所有uint32_t*类型变量都会套用第一个配置。
第二次尝试的Natvis配置及问题
<?xml version="1.0" encoding="utf-8"?> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> <Type Name="uint32_t *"> <DisplayString>Test IndexListItems</DisplayString> <Expand> <IndexListItems> <Size>5</Size> <ValueNode>pointer_array_1[$i]</ValueNode> </IndexListItems> <IndexListItems> <Size>10</Size> <ValueNode>limit_ptr[$i]</ValueNode> </IndexListItems> </Expand> </Type> </AutoVisualizer>
- 问题:两个变量显示内容混合,均同时展示两个数组的内容。因为单个
Type节点下的所有IndexListItems会被应用到所有匹配的类型变量上。
需求
需要limit_ptr正确显示其指向的数组值:0,5,10,15,20,.....,45,同时pointer_array_1显示自身指向的数组值,实现多个同类型变量的分别显示。
解决方案
要实现同类型指针变量的分别显示,不能直接对uint32_t*配置通用规则,可通过以下两种方式实现:
方法1:匹配具体变量名
Natvis支持通过Name属性指定配置仅作用于特定变量,语法为<Type Name="uint32_t *" Name="变量名">:
<?xml version="1.0" encoding="utf-8"?> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> <!-- 匹配变量pointer_array_1 --> <Type Name="uint32_t *" Name="pointer_array_1"> <DisplayString>pointer_array_1 (size:5)</DisplayString> <Expand> <IndexListItems> <Size>5</Size> <!-- $this代表当前指针变量,避免硬编码变量名 --> <ValueNode>*($this + $i)</ValueNode> </IndexListItems> </Expand> </Type> <!-- 匹配变量limit_ptr --> <Type Name="uint32_t *" Name="limit_ptr"> <DisplayString>limit_ptr (size:10)</DisplayString> <Expand> <IndexListItems> <Size>10</Size> <ValueNode>*($this + $i)</ValueNode> </IndexListItems> </Expand> </Type> </AutoVisualizer>
- 关键说明:
Name="变量名"限定配置仅作用于指定变量$this指代当前调试的指针变量,确保取值逻辑正确<ValueNode>*($this + $i)表示取当前指针偏移$i位置的值,符合数组内存布局
方法2:自定义包装类型(推荐,通用性更强)
定义结构体包装指针和数组大小,Natvis直接匹配包装类型,无需依赖变量名:
修改后的测试代码
#include<iostream> // 自定义包装结构体 template<typename T, size_t Size> struct ArrayPtrWrapper { T* ptr; static constexpr size_t size = Size; }; int main() { uint32_t foo_array[5] = {5,15,96,8,77}; ArrayPtrWrapper<uint32_t, 5> pointer_array_1{foo_array}; uint32_t limit_array[10]; for(int i = 0; i < 10; i++) { limit_array[i] = i*5; } ArrayPtrWrapper<uint32_t, 10> limit_ptr{limit_array}; return 0; }
对应的Natvis配置
<?xml version="1.0" encoding="utf-8"?> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> <Type Name="ArrayPtrWrapper<*,*>"> <DisplayString>{ptr} (size:{size})</DisplayString> <Expand> <IndexListItems> <Size>size</Size> <ValueNode>ptr[$i]</ValueNode> </IndexListItems> </Expand> </Type> </AutoVisualizer>
- 优势:无需绑定变量名,只要使用包装类型,就能自动根据模板参数显示对应大小的数组,扩展性更强。
内容的提问来源于stack exchange,提问作者karim
相关产品推荐
相关产品推荐

