Oracle Solaris Studio 12.2:性能分析器

表达式语法

定义过滤器的表达式和用于计算内存对象索引的表达式使用通用语法。

语法将表达式指定为运算符和操作数的组合。对于过滤器,如果表达式的计算结果为真,则包括包;如果表达式的计算结果为假,则排除包。对于内存对象或索引对象,表达式的计算结果为一个索引,该索引定义包中引用的特定内存对象或索引对象。

表达式中的操作数或者是常量或者是数据记录中的字段,如使用 describe 命令的执行结果所示。这些操作数包括 THRIDLWPIDCPUIDUSTACKXSTACKMSTACKLEAFVIRTPCPHYSPCVADDRPADDRDOBJTSTAMPSAMPLEEXPIDPID 或内存对象的名称。操作数名称不区分大小写。

USTACKXSTACKMSTACK 分别表示用户视图、专家视图和计算机视图中的函数调用堆栈。

仅当为硬件计数器分析或时钟分析指定 "+" 时,VIRTPCPHYSPCVADDRPADDR 都不为零。此外,当无法确定实际虚拟地址时,VADDR 小于 256。如果无法确定 VADDR 或者无法将虚拟地址映射到物理地址,PADDR 为零。同样,如果回溯失败或者未请求回溯, VIRTPC 为零;如果 VIRTPC 为零或者无法将 VIRTPC 映射到物理地址,PHYSPC 为零。

运算符包括常见的逻辑运算符和算术(包括移位)运算符(在 C 表示法中,具有 C 优先级规则),以及用于确定某个元素是否位于集中的运算符 (IN) 或用于确定某组元素中的任一元素或全部元素是否包含在集中的运算符(分别对应 SOME ININ)。附加运算符 ORDERED IN 用于确定左侧操作数中的所有元素是否以相同的顺序出现在右侧操作数中。注意,IN 运算符要求左侧操作数中的所有元素出现在右侧操作数中,但对顺序未作要求。如在 C 中那样指定 If-then-else 结构(使用 ? 和 : 运算符)。使用圆括号以确保正确解析所有表达式。在 er_print 命令行上,不能将表达式拆分为多行。在脚本中或命令行上,如果表达式包含空格,则必须用双引号将其引起来。

过滤表达式的计算结果为布尔值。如果应该包括包,则计算结果为真,如果不应该包括包,则计算结果为假。线程、LWP、CPU、实验 id、进程 pid 和样本过滤基于相应关键字和整数之间的关系表达式,或者使用 IN 运算符和逗号分隔的整数列表。

可通过在 TSTAMP 和时间(以整数纳秒为单位,从将要处理其包的实验开始时算起)之间指定一个或多个关系表达式来使用时间过滤。样本的时间可以使用 overview 命令获得。overview 命令中的时间以秒为单位,必须转换为纳秒以用于时间过滤。时间还可以从分析器中的“时间线”显示获得。

函数过滤可以基于叶函数或栈中的任何函数。按叶函数进行过滤是通过 LEAF 关键字和整型函数 id 之间的关系表达式指定的,或者使用 IN 运算符和结构 FNAME("regexp") 指定,其中 regexp 是正则表达式,如 regexp(5) 手册页中所指定的那样。函数的整个名称(如 name 的当前设置所指定)必须匹配。

可以通过确定构造 FNAME(“regexp ”) 中的任何函数是否位于由关键字 USTACK: (FNAME(“myfunc”) SOME IN USTACK) 表示的函数数组中来指定基于调用堆栈中的任何函数的过滤。

数据对象过滤类似于栈函数过滤,使用 DOBJ 关键字和结构 DNAME("regexp")(括在圆括号中)。

内存对象过滤是使用内存对象的名称(如 mobj_list 命令中所示)和对象的整型索引或对象集的索引来指定的。(<Unknown> 内存对象的索引是 -1。)

索引对象过滤是使用索引对象的名称(如 indxobj_list 命令中所示)和对象的整型索引或对象集的索引来指定的。(<Unknown> 索引对象的索引是 -1。)

数据对象过滤和内存对象过滤仅对具有数据空间数据的硬件计数器包有意义;此类过滤将排除所有其他包。

虚拟地址或物理地址的直接过滤是通过 VADDRPADDR 与地址之间的关系表达式指定的。

内存对象定义(请参见mobj_define mobj_type index_exp)使用其计算结果为整型索引的表达式(使用 VADDR 关键字或 PADDR 关键字)。该定义仅适用于内存计数器和数据空间数据的硬件计数器包。该表达式应该返回整数,对于 <Unknown> 内存对象,则返回 -1。

索引对象定义(请参见indxobj_define indxobj_type index_exp)使用其计算结果为整型索引的表达式。该表达式应该返回整数,对于 <Unknown> 索引对象,则返回 -1。

示例过滤器表达式

本节介绍可通过 er_print -filters 命令以及在分析器过滤对话框中使用的过滤器表达式的示例。

利用 er_print -filters 命令,过滤器表达式用单引号引起来,如下所示:


er_print -filters 'FNAME("myfunc") SOME IN USTACK' -functions test.1.er

示例 5–1 按名称和堆栈过滤函数

从用户函数堆栈过滤名为 myfunc 的函数:

FNAME("myfunc") SOME IN USTACK



示例 5–2 按线程和 CPU 过滤事件

当线程 1 仅在 CPU 2 上运行时,要查看线程 1 中的事件,请使用:

THRID == 1 && CPUID == 2



示例 5–3 按索引对象过滤事件

如果将索引对象 THRCPU 定义为 "CPUID<<16|THRID ",下面的过滤器与上述当线程 1 仅在 CPU 2 上运行时查看线程 1 中的事件等效:

THRCPU == 0x10002



示例 5–4 过滤指定时间段发生的事件

过滤介于第 5 秒和第 9 秒之间的时间段中发生的实验 2 的事件:

EXPID==2 && TSTAMP >= 5000000000 && TSTAMP < 9000000000



示例 5–5 过滤来自特定 Java 类的事件

过滤堆栈中具有特定 Java 类的任何方法的事件(用户视图模式下):

FNAME("myClass.*") SOME IN USTACK



示例 5–6 按内部函数 ID 和调用序列过滤事件

已知函数 ID(如分析器中所示)时,过滤包含计算机调用堆栈中特定调用序列的事件:

(314,272) ORDERED IN MSTACK



示例 5–7 按状态或持续时间过滤事件

如果 describe 命令列出时钟分析实验的以下属性:


MSTATE    UINT32  Thread state
NTICK     UINT32  Duration

可以使用以下过滤器选择处于特定状态的事件:

MSTATE == 1

或者,可以使用以下过滤器选择处于特定状态且其持续时间比 1 个时钟周期长的事件:

MSTATE == 1 && NTICK > 1