当对应于内存操作的硬件计数器事件的 PC 已被处理,可以成功回溯到很可能引发事件的内存引用指令时,分析器将使用编译器在其硬件分析支持信息中提供的指令标识符和描述符派生关联的程序数据对象。
术语“数据对象”用于表示程序常量、变量、数组和聚集(如结构和联合),以及源代码中所述的各种聚集元素。数据对象的类型及其大小随源语言的不同而不同。许多数据对象是在源程序中显式命名的,而其他数据对象可能是未命名的。有些数据对象是从其他(更简单的)数据对象派生或聚集的,从而产生了一组丰富的、通常很复杂的数据对象。
每个数据对象都具有关联的范围,即在其中定义数据对象并可以引用数据对象的源程序区域,该区域可能是全局性的(如装入对象),也可能是特定的编译单元(目标文件)或函数。相同的数据对象可能是使用不同的范围定义的,或者是在不同的范围内以不同的方式引用的特定数据对象。
在启用回溯的情况下为内存操作的硬件计数器事件收集的数据派生度量被归属到关联的程序数据对象类型,并传播到包含数据对象和人工 <Total>(它被视为包含所有数据对象,其中包括 <Unknown> 和 <Scalars>)的任何聚集。<Unknown> 的不同子类型向上传播到 <Unknown> 聚集。下一节将介绍 <Total>、<Scalars> 和 <Unknown> 数据对象。
可以通过数据对象的声明类型和名称的组合来完整描述数据对象。简单的标量数据对象 {int i} 描述名为 i、类型为 int 的变量,而 {const+pointer+int p} 描述类型为 int、名为 p 的常量指针。类型名称中的空格将替换为下划线 (_),未命名的数据对象用短划线 (-) 名称表示,例如:{double_precision_complex -}。
同样,对于 foo_t 类型的结构,将整个聚集表示为 {structure:foo_t}。聚集元素需要其容器的其他规范,例如,{structure:foo_t}.{int i} 表示 foo_t 类型的上一结构的 int 类型的成员 i。聚集本身也可以是(更大)聚集的元素,其对应描述符构造为聚集描述符的串联,并最终成为标量描述符。
虽然并不总是需要使用全限定描述符来消除数据对象的歧义,但是该描述符提供了完整的通用规范以协助标识数据对象。
<Total> 数据对象是一个人工结构,用于将程序的数据对象作为一个整体表示。除了归属到不同数据对象(以及它所属的任何聚集)外,所有性能度量都归属到特殊的数据对象 <Total>。该数据对象出现在数据对象列表的顶部,其数据可以用于为其他数据对象的数据提供透视。
聚集元素将其性能度量另外归属到其关联聚集的度量值,而所有标量常量和变量都将其性能度量另外归属到人工 <Scalars> 数据对象的度量值。
在许多情况下,不能将事件数据映射到特定的数据对象。在这样的情况下,将数据映射到名为 <Unknown> 的特殊数据对象及其元素之一,如下面所述。
带触发 PC 的模块未使用 -xhwcprof 编译
由于对象代码未通过硬件计数器分析支持进行编译,因此未识别任何引发事件的指令或数据对象。
查找有效分支目标的回溯失败
由于在编译对象中提供的硬件分析支持信息不足以验证回溯的有效性,因此未识别任何引发事件的指令。
回溯遍历到一个分支目标
由于回溯遇到了指令流中的控制转移目标,因此未识别任何引发事件的指令或数据对象。
编译器未提供任何标识描述符
回溯已确定很可能引发事件的内存引用指令,但是编译器未指定其关联的数据对象。
无类型信息
回溯已确定很可能引发事件的指令,但是编译器未将该指令识别为内存引用指令。
无法根据编译器提供的符号信息来确定
回溯已确定很可能引发事件的内存引用指令,但是编译器未识别它,因此不可能确定关联的数据对象。编译器临时文件通常是不可识别的。
跳转或调用指令阻止回溯
由于回溯遇到了指令流中的分支或调用指令,因此未识别任何引发事件的指令。
回溯找不到触发 PC
在最大回溯范围内未找到任何引发事件的指令。
无法确定 VA,因为寄存器在触发器指令后发生更改
由于在硬件计数器失控期间寄存器被覆写,因此未确定数据对象的虚拟地址。
内存引用指令未指定有效的 VA
数据对象的虚拟地址看起来无效。