跳过导航链接 | |
退出打印视图 | |
![]() |
Oracle Solaris Studio 12.3:性能分析器 Oracle Solaris Studio 12.3 Information Library (简体中文) |
运行数据收集的输出是实验,该实验在文件系统中存储为带有各种内部文件和子目录的目录。
所有实验都必须具有以下三个文件:
日志文件 (log.xml),它是一个 XML 文件,包含有关所收集数据、各种组件的版本、目标生存期内各种事件的记录和目标字大小的信息。
映射文件 (map.xml),它是一个 XML 文件,所记录的信息包括将哪些装入对象装入目标的地址空间以及装入或卸载这些对象的具体时间。
概述文件,它是一个二进制文件,包含在实验中的每个抽样点记录的用法信息。
此外,实验还具有表示整个处理过程中的分析事件的二进制数据文件。每个数据文件都具有一系列事件,如下面解释性能度量所述。对于每种类型的数据,都将使用单独的文件,但每个文件都由目标中的所有线程共享。
对于基于时钟的分析或硬件计数器溢出分析,将数据写入时钟周期或计数器溢出调用的信号处理程序中。对于同步跟踪、堆跟踪、MPI 跟踪或 OpenMP 跟踪,从 LD_PRELOAD 环境变量在用户调用的常规例程上插入的 libcollector 例程写入数据。每个这样的插入例程都部分填充数据记录,然后调用用户调用的常规例程,在该例程返回时填充数据记录的其余部分,并将记录写入数据文件。
所有数据文件都按块进行内存映射和写入。以这样的方式填充记录以便始终具有有效的记录结构,这样就可以在写入时读取实验。缓冲区管理策略设计用于最大限度地减少线程之间的争用和序列化。
实验可以选择性地包含文件名为 notes 的 ASCII 文件。使用 collect 命令的 -C comment 参数时会自动创建此文件。创建实验后,可以手动创建或编辑该文件。该文件的内容会置于实验标题之前。
每个实验都具有一个 archives 目录,该目录包含描述 map.xml 文件中引用的每个装入对象的二进制文件。这些文件由 er_archive 实用程序(它在数据收集结束时运行)生成。如果进程异常终止,则可能无法调用 er_archive 实用程序,在这种情况下,归档文件由 er_print 实用程序或分析器在实验上首次调用时写入。
当分析多个进程(例如,跟踪后代进程、收集 MPI 实验或者使用用户进程分析内核)时,将创建子实验。
后续进程将其实验写入创始进程的实验目录内的子目录。对这些新子实验的命名可指示其衍生情况,如下所示:
将下划线附加到创建者的实验名称。
添加以下代码字母之一:f 代表派生,x 代表执行,c 代表其他后续进程。
在代码字母后添加一个表示派生或执行的索引的数字。不管是否成功启动了进程,都会应用此数字。
附加实验后缀 .er 以构成完整的实验名称。
例如,如果创始进程的实验名称为 test.1.er,则其第三个派生创建的子进程的实验为 test.1.er/_f3.er。如果该子进程执行新映像,则对应的实验名称为 test.1.er/_f3_x1.er。后续实验由与父实验相同的文件组成,但是它们没有后续实验(所有后续实验都由创始实验中的子目录表示),而且它们没有归档子目录(所有归档都在创始实验中进行)。
缺省情况下,MPI 程序的数据收集到 test.1.er 中,而 MPI 进程的所有数据都收集到子实验中,每个等级一个子实验。收集器使用 MPI 等级以格式 M_rm.er 构造子实验名称,其中 m 是 MPI 等级。例如,MPI 等级 1 的子实验数据将记录在 test.1.er/M_r1.er 目录中。
缺省情况下,内核上的实验命名为 ktest.1.er 而不是 test.1.er。当同时收集用户进程的数据时,内核实验将包含每个跟随的用户进程所对应的子实验。内核子实验的命名格式为 _ process-name_PID_process-id.1.er。例如,在进程 ID 1264 下运行的 sshd 进程上所运行的实验将命名为 ktest.1.er/_sshd_PID_1264.1.er。
目标创建动态函数的实验在 map.xml 文件中具有描述这些函数的附加记录,还具有一个附加文件 dyntext,该文件包含动态函数的实际指令的副本。生成动态函数的带注释反汇编时需要该副本。
Java 实验在 map.xml 文件中具有附加记录,这两个记录用于 JVM 软件因其内部目的而创建的动态函数和目标 Java 方法的动态编译 (HotSpot) 版本。
此外,Java 实验具有一个 JAVA_CLASSES 文件,该文件包含有关调用的所有用户 Java 类的信息。
使用 JVMTI 代理记录 Java 跟踪数据,该代理是 libcollector.so 的一部分。该代理接收映射到记录的跟踪事件中的事件。该代理还接收类装入和 HotSpot 编译(用于写入 JAVA_CLASSES 文件)的事件以及 map.xml 文件中 Java 编译的方法记录。
您可以按三种不同的方式记录用户模式目标上的实验:
使用 collect 命令
使用 dbx 创建进程
使用 dbx 从正在运行的进程创建实验
分析器 GUI 中的“性能收集”窗口中运行 collect 实验。
使用 collect 命令记录实验时,collect 实用程序会创建实验目录,并设置 LD_PRELOAD 环境变量,以确保将 libcollector.so 及其他 libcollector 模块预装入到目标的地址空间中。然后,该 collect 实用程序设置环境变量,将实验名称和数据收集选项通知 libcollector.so,并执行自己顶部的目标。
libcollector.so 及其相关模块负责写入所有实验文件。
在启用数据收集的情况下使用 dbx 启动进程时,dbx 还会创建实验目录,并确保预装入 libcollector.so。然后 dbx 在其第一个指令前的断点处停止进程,并调用 libcollector.so 中的初始化例程以启动数据收集。
Java 实验不能由 dbx 收集,因为 dbx 使用 Java 虚拟机调试接口 (Java Virtual Machine Debug Interface, JVMDI) 代理进行调试,而该代理无法与数据收集所需的 Java 虚拟机工具接口 (Java Virtual Machine Tools Interface, JVMTI) 代理共存。
在正在运行的进程上使用 dbx 启动实验时,dbx 会创建实验目录,但不能使用 LD_PRELOAD 环境变量。dbx 对目标进行交互式函数调用以打开 libcollector.so,然后调用 libcollector.so 初始化例程,就像它创建进程时那样。与 collect 实验中一样,数据由 libcollector.so 及其模块写入。
由于进程启动时 libcollector.so 不在目标地址空间中,因此取决于插入用户可调用函数(同步跟踪、堆跟踪、MPI 跟踪)的任何数据收集可能都不起作用。通常,符号已经解析为底层函数,因此无法发生插入。此外,以下子孙进程也取决于插入,对于 dbx 在正在运行的进程上创建的实验无法正常工作。
如果在使用 dbx 启动进程之前或者在使 dbx 附加到正在运行的进程之前已显式预装入 libcollector.so,可以收集跟踪数据。