VisualStudio调试器指南---Natvis语法参考

原创
小哥 2年前 (2023-05-24) 阅读数 7 #大杂烩

转自: Visual Studio调试器指南---Natvis 语法参考 - 活虫 - 博客园

AutoVisualizer 元素

MARKDOWN_HASH32491c711cc7f6e93f5ae6e7a1f7217fMARKDOWNHASH 元素是 .natvis_ 文件的根节点,包含命名空间 xmlns: 属性。

XML



.
.

AutoVisualizer 元素可以具有类型 HResult、 UIVisualizer和CustomVisualizer子项。

Type 元素

基本 Type 如以下示例所示:

XML


  [Display value]
  
    ...
  

Type 元素名称:

  1. 应使用可视化对象的类型( Name 特性)。

  2. 这种类型的对象( DisplayString 元素)。

  3. 当用户在变量窗口中展开某个类型时,该类型的成员应以什么形式显示( Expand 节点)。

模板类

Type 元素的 Name 属性接受星号 * 作为可用于模板化类名的通配符。

在以下示例中,无论对象是否 CAtlArray<int> 还是 CAtlArray<float> 它们都使用相同的可视化效果。 如果 CAtlArray<float> 某些特定的可视化项的优先级高于常规项。

XML


    {{Count = {m_nSize}}}

可以使用 $T1 和 $T2 此类宏引用可视化条目中的模板参数。 有关这些宏的示例,请参阅 Visual Studio 随附的 .natvis 文件。

展示台类型匹配

如果无法验证可视化项,则使用下一个可用的可视化效果。

可继承特征

可选的 Inheritable 属性用于指定可视化效果是仅适用于一个基类型,还是应用于一个基类型和所有派生类型。 Inheritable 的默认值为 true

在以下示例中,可视化效果仅适用于 BaseClass 类型:

XML


    {{Count = {m_nSize}}}

优先级特征

如果定义的分析失败,可选 Priority 该属性指定使用替代定义的顺序。 Priority 这些值包括: LowMediumLowMediumMediumHighHigh 。 默认值是 MediumMARKDOWN_HASH502996d9790340c5fd7b86a5b93b1c9fMARKDOWNHASH 仅区分同一属性 .natvis_ 文件中的优先级。

以下示例将首先分析与 2015 STL 匹配的条目。 如果分析失败,则 STL 的 2013 版本的备用条目:

XML



     {_Callee}
    
        _Callee
    




    {*_Ptr}
    
        _Ptr
    

可选特性

你可以将 Optional 放置在任何节点上的属性。 如果对可选节点中的子表达式的分析失败,调试器将忽略该节点,但应用它 Type 其余规则。 在以下类型中, [State] 不是可选的,但 [Exception] 可选。 如果 MyNamespace::MyClass 包含名为 M_exceptionHolder 字段将同时显示 [State] 节点和 [Exception] 节点,但如果它不包括 _M_exceptionHolder 字段将仅显示 [State] 节点。

XML


    
      _M_State
      _M_exceptionHolder
    

条件属性

可选的 Condition 属性可用于许多可视化元素,以指定何时使用可视化规则。 如果条件属性中的表达式解析为 false 不要应用可视化规则。 如果其计算结果为 true 要不 Condition 将应用属性、可视化规则。 您可以使用此属性来可视化 if-else 逻辑。

例如,以下可视对象具有两种智能指针类型 DisplayString 元素。 当 _Myptr 当成员为空时,第一个 DisplayString 元素的条件解析为 true 以显示表单。 如果 _Myptr 如果成员不为空,则条件的计算结果为 false ,第二个 DisplayString 元素显示。

XML


  empty
  auto_ptr {*_Myptr}
  
    _Myptr
  

IncludeView 和 ExcludeView 特性

IncludeViewExcludeView 属性用于指定是否在特定视图中显示元素。 例如,在以下 Natvis std::vector 规范中, simple 视图未显示 [size][capacity] 项。

XML


    {{ size={_Mylast - _Myfirst} }}
    
        _Mylast - _Myfirst
        _Myend - _Myfirst
        
            _Mylast - _Myfirst
            _Myfirst
        
    

可用于类型和单个成员 IncludeViewExcludeView 属性。

Version 元素

Version 该元素用于将可视化项的范围限制为特定模块和版本。 Version 元素有助于避免名称冲突,减少意外的不匹配,并允许在不同类型的版本中使用不同的可视化效果。

如果不同模块使用的公共头文件定义了类型,则仅当类型在指定的模块版本内时,才会显示版本控制的可视化效果。

在以下示例中,可视化效果仅适用于 DirectUI::Border 版本 1.0 到 1.5 中找到的 Windows.UI.Xaml.dll 类型。

XML


  
  {{Name = {*(m_pDO->m_pstrName)}}}
  
    *(CBorder*)(m_pDO)
  

不需要 MinMax 。 它们是可选属性。 不支持通配符。

Name 要素的格式为 filename. ext ,如 hellosome 。 不允许使用路径名。

DisplayString 元素

DisplayString 该元素用于指定要显示为变量值的字符串。 它接受任何混合表达式字符串。 大括号内的所有内容都可以解释为表达式。 例如,以下 DisplayString 条目:

XML


  {{x={x} y={y}}}

表示 CPoint 类型变量的显示如下图所示:

DisplayString 在表达式中,属于 x 成员的 yCPoint 位于大括号内,将计算其值。 此示例还说明了如何使用双大括号 ( { {}} )转义大括号。

备注

DisplayString 该元素是唯一接受任何字符串和大括号语法的元素。 所有其他可视元素仅接受调试器可以计算的表达式。

StringView 元素

StringView 该元素用于定义调试器可以发送到内置文本可视化工具的值。 例如,假设 ATL::CStringT 该类型具有以下可视化效果:

XML


  {m_pszData,su}

CStringT 对象将显示在一个变量窗口中,如以下示例所示:

添加 StringView 该元素将告知调试器它可以将值可视化为文本。

XML


  {m_pszData,su}
  m_pszData,su

在调试期间,可以选择变量旁边的放大镜图标,然后选择 "文本可视化工具" 以显示m_pszData字符串指向。

表达式 {m_pszData,su} 包含一个 C++ 格式规范 su用于将值显示为 Unicode 字符串。 欲了解更多信息,请参阅 C++ 中的格式规范。

Expand 元素

可选的 Expand 节点用于在变量窗口中展开可视化类型的子级时自定义可视化类型的子级。 Expand 节点接受用于定义子元素的子节点列表。

  • 如果未在可视化条目中指定 Expand 节点和子节点将使用默认扩展规则。

  • 如果指定 Expand 如果节点下没有子节点,则无法在调试器窗口中展开类型。

Item 展开

Item 元素是 Expand 节点中最基本和最常见的元素。 Item 定义单个子元素。 例如,包含 CRecttopleftright 字段的 bottom 类具有以下可视条目:

XML


  {{top={top} bottom={bottom} left={left} right={right}}}
  
    right - left
    bottom - top
  

在调试器窗口中, CRect 类型如以下示例所示:

调试器将计算 WidthHeight 然后,元素中指定的表达式将显示在变量窗口的值列中。

调试器将自动为每个自定义部署创建 [Raw View] 节点。 在上面的屏幕截图中 [Raw View] 节点将展开,显示对象的默认原始视图及其 Natvis 视觉效果的差异。 默认扩展将为基类创建一个子树,并将基类的所有数据成员列为子项。

备注

如果项元素的表达式指向复杂类型,则项节点本身是可展开的。

Size

使用 ArrayItems 节点,让 Visual Studio 调试器将类型解释为数组并显示其各种元素。 std::vector 的可视化效果就是一个很好的例子:

XML


  {{size = {_Mylast - _Myfirst}}}
  
    _Mylast - _Myfirst
    (_Myend - _Myfirst)
    
      _Mylast - _Myfirst
      _Myfirst
    
  

std::vector 在变量窗口中展开时显示自己的元素:

ArrayItems 节点必须具有:

  • 用于使调试器知道数组长度 Size 表达式(必须计算为整数)。
  • 一个 ValuePointer 表达式,指向第一个元素(必须为 non void* 指向元素类型的指针)。

数组下限的默认值为 0。 若要修改此值,请使用 MARKDOWN_HASH93673fa92b8c57d1e6739d14f422304dMARKDOWNHASH 元素。 Visual Studio 随附的 .Natvis_ 文件中提供了一个示例。

备注

可以使用 [] 运算符(例如 vector[i] )和任何使用 ArrayItems 一维数组的可视化效果,即使类型本身(如 CATLArray )不允许使用此运算符。

您还可以指定多维数组。 在这种情况下,调试器需要比较详细地显示子元素:

XML


  extent = {_M_extent}
  
    _M_extent
    
      Forward
      $T2
      _M_extent._M_base[$i]
      ($T1*) _M_buffer_descriptor._M_data_ptr
    
  
  • Direction 指定数组是采用行优先级还是列优先级。
  • Rank 指定数组的等级。
  • Size 该元素接受将其替换为维度索引的隐式方法,以查找该维度中数组的长度 $i 参数。 在前面的示例中,表达式 _M_extent.M_base[0] 应为第0指定尺寸的长度, _M_extent._M_base[1] 为1等等。

下面是调试器窗口中的二维显示 Concurrency::array 对象:

IndexListItems 展开

仅在数组元素在内存中连续排列时使用 ArrayItems 展开。 调试器只需递增其指针即可获取下一个元素。 如果需要操作值节点的索引,可以使用 IndexListItems 节点。 下面是 IndexListItems 节点可视化:

XML


  {{size = {_M_vector._M_index}}}
  
    _M_vector._M_index
    
      _M_vector._M_index
      *(_M_vector._M_array[$i])
    
  

ArrayItemsIndexListItems 它们之间的唯一区别是 ValueNode 它期望具有隐式元素 参数的第 i $i 元素的完整表达式。

备注

可以使用 [] 运算符(例如 vector[i] )和任何使用 IndexListItems 一维数组的可视化效果,即使类型本身(如 CATLArray )不允许使用此运算符。

LinkedListItems 展开

如果可视化类型表示链接列表,则调试器可以使用 LinkedListItems 节点显示其子节点。 以下 CAtlList 对类型的视觉效果的使用 LinkedListItems

XML


  {{Count = {m_nElements}}}
  
    m_nElements
    
      m_nElements
      m_pHead
      m_pNext
      m_element
    
  

Size 元素引用的列表的长度。 HeadPointer 指向第一个元素, NextPointer 引用下一个元素,而 ValueNode 引用项的值。

调试器将是 NextPointer 在节点元素(而不是父列表类型)的环境中计算 ValueNodeLinkedListItems 表达式。 在前面的示例中, CAtlList 有一个 CNode 类(位于 atlcoll.h 它是链表中的一个节点。 m_pNextm_elementCNode 类(而不是 CAtlList 类)。

ValueNode 可以留空或使用 this 来引用 LinkedListItems 节点本身。

CustomListItems 展开

CustomListItems 扩展允许编写自定义逻辑来遍历数据结构,例如哈希表。 使用 CustomListItems 可视化可以使用的数据结构 C++ 表达式执行所有操作,但不太合适 ArrayItemsIndexListItemsLinkedListItems 模式。

借助扩展中定义的变量和对象,您可以创建 Exec 在部署中使用 CustomListItems 执行内部代码。 逻辑运算符、算术运算符和赋值运算符可以与 Exec 一起使用。 不能使用 Exec 要计算函数( C++表达式计算器支持的调试器内部函数除外。

下面的 CAtlMap 可视化工具就是一个很好的例子,其中 CustomListItems 它被非常恰当地使用。

XML


    
    
    {{Count = {m_nElements}}}
    
      
        
        
        

        m_nElements
        pBucket = nullptr
        
          
            iBucket++
            iBucketIncrement = __findnonnull(m_ppBins + iBucket, m_nBins - iBucket)
            
            iBucket += iBucketIncrement
            pBucket = m_ppBins[iBucket]
          
          pBucket,na
          pBucket = pBucket->m_pNext
        
      
    

TreeItems 展开

如果可视化类型表示树,则调试器可以使用 TreeItems 节点遍历树并显示其子节点。 以下是用途 TreeItems 节点的 std::map 类型的可视化效果:

XML


  {{size = {_Mysize}}}
  
    _Mysize
    comp
    
      _Mysize
      _Myhead->_Parent
      _Left
      _Right
      _Myval
    
  

语法类似于 LinkedListItems 节点。 LeftPointerRightPointerValueNode 它是在树节点类的上下文中计算的。 ValueNode 可以留空或使用 this 来引用 TreeItems 节点本身。

ExpandedItem 展开

通过将基类或数据成员的属性显示为可视类型的子级, ExpandedItem 该元素生成聚合的子视图。 调试器将计算指定的表达式,并将结果的子节点附加到可视化类型的子列表。

例如,智能指针类型 auto_ptr<vector<int>> 通常显示为:

要查看向量的值,必须遍历变量窗口 _Myptr 成员,向下钻取两个级别。 通过添加 ExpandedItem 可以从层次结构中删除元素 _Myptr 变量和直接查看矢量元素:

XML


  auto_ptr {*_Myptr}
  
    _Myptr
  

下面的示例演示如何将基类的属性聚合到派生类中。 假定 CPanel 类派生自 CFrameworkElementCFrameworkElement 节点的可视化将改变基础 ExpandedItem 将类的属性附加到 CPanel 类,而不是重复这些属性。

XML


  {{Name = {*(m_pstrName)}}}
  
    (bool)m_bItemsHost
    *(CFrameworkElement*)this,nd
  

关闭派生类的视觉对象匹配 nd 格式规范肯定在这。 否则, *(CFrameworkElement*)this 表达式将导致重新应用 CPanel 可视化,因为默认可视化类型匹配规则认为它是最合适的类型。 使用nd格式描述符指示调试器使用基类可视化效果,如果基类没有可视化效果,则使用默认扩展。

Synthetic Item 展开

ExpandedItem 元素通过消除分层结构提供更简单的数据视图, Synthetic 节点恰恰相反。 它允许您创建不是表达式结果的人工子元素。 人工智能元素可以有自己的子元素。 在以下示例中, Concurrency::array 对类型的视觉效果的使用 Synthetic 该节点向用户显示诊断消息:

XML


  extent = {_M_extent}
  
    _M_extent
    
      $T2
      _M_extent._M_base[$i]
      ($T1*) _M_buffer_descriptor._M_data_ptr
    
    
      Array members can be viewed only under the GPU debugger
    
  

HResult 元素

借助 HResult 可以自定义调试器窗口中显示的元素 HRESULT 信息。 HRValue 该元素必须包含 HRESULT 的 32 位值。 HRDescription 该元素包含要在调试器窗口中显示的信息。

XML


  0xABC0123
  No elements in the collection.

UIVisualizer 元素

MARKDOWN_HASHd406106a75d6c1a887d5af056539ba10MARKDOWNHASH 该元素用于向调试器注册图形可视化工具插件。 图形可视化工具创建一个对话框或其他界面,以匹配其数据类型的方式显示变量或对象。 可视化工具插件必须编写为 VSPackage并且必须公开调试器可以使用的服务。 .Natvis_ 该文件包含插件的注册信息,例如名称和公开的服务 GUID 以及它可以直观显示的类型。

下面是 UIVisualizer 元素示例:

XML



    
    
.
.
  • ServiceId - Id 属性对用于标识 UIVisualizerServiceId 它是可视化工具包的公开可用服务 GUID。 如果服务提供多个可视化工具, Id 它是用于区分它们的唯一标识符。 在上面的示例中,同一可视化工具服务提供了两个可视化工具。

  • MenuName 属性用于定义可视化工具名称,该名称将显示在调试器放大镜图标旁边的下拉列表中。 例如:

.natvis 文件中定义的每个类型都必须清楚地列出可以显示它的所有类型 UI 可视化工具。 调试器会将类型条目中的可视化工具引用与注册的可视化工具匹配。 例如,以下 std::vector 类型条目引用 UIVisualizer

XML


  

您可以在图像监视扩展中查看它,以便在内存中查看位图 UIVisualizer 的示例。

CustomVisualizer 元素

CustomVisualizer 是用于指定 VSIX 展开以包括 Visual Studio 控制代码中的可视化效果。 有关编写 VSIX 有关扩展的更多信息,请参阅 Visual Studio SDK。

编写自定义可视化工具比 XML Natvis 定义要复杂得多,但是 Natvis 对支持的限制对您没有影响。 自定义可视化可以访问所有调试器扩展性 API因此,可以查询和修改调试对象进程,以及与 Visual Studio 通信的其他部分。

可以在 Condition 在元素上使用 IncludeViewExcludeViewCustomVisualizer 属性。

限制

Natvis 自定义适用于类和结构,但不能使用 typedef。

Natvis 不支持基元类型的可视化工具(例如 intbool )或指向基元类型的指针。 在此方案中,一种选择是使用适合用例的格式规范。 例如,如果您使用 double* mydoublearray ,您可以使用 "监视" 窗口中使用数组格式规范,如表达式 mydoublearray, [100] 这将显示上一个100个元素。

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除