本文档介绍了用于收集、存储和传输 Fuchsia 跟踪记录的二进制格式。您可以使用本文档搜索有关 Fuchsia 轨迹格式中每个字段的详细信息。
概览
跟踪记录运行时,跟踪记录提供程序使用本文档中所述的二进制格式将记录写入与跟踪记录管理器共享的跟踪缓冲区 VMO。
二进制格式旨在尽量降低在写入跟踪记录时对跟踪对象性能的影响。记录也是按顺序写入的,这样一来,如果跟踪终止(正常或异常),跟踪管理器仍然可以通过读取最后一条格式正确的记录之前的所有内容,恢复已存储在跟踪缓冲区中的部分跟踪数据。
随着跟踪记录的进行,跟踪管理器会汇总来自参与跟踪记录收集的所有跟踪记录提供程序的记录,并将这些记录与一些特殊的元数据记录串联起来,从而形成一个跟踪记录归档。
跟踪记录完成后,trace
命令行程序等工具可以读取跟踪记录归档中的跟踪记录,以直观呈现结果或将其保存到文件中以供日后使用。
功能
- 占用空间小
- 跟踪记录非常紧凑,可将信息打包到少量位中。
- 池化字符串、进程和线程会进一步压缩轨迹数据。
- 内存对齐
- 跟踪记录会在内存中保持 8 字节对齐,以便将其直接写入内存映射 VMO。
- 大小可变的记录
- 总记录大小上限为 32 KB。
- 大型对象可能需要拆分为多条记录。
- 可扩展
- 您可以按需定义新的记录类型。
- 无法识别或格式错误的跟踪记录可以跳过。
对基元进行编码
Fuchsia 跟踪记录格式具有以下编码基元:
Atoms
每条记录都构造为原子序列。
每个 Atom 均采用 8 字节对齐方式编写,并且大小也是 8 字节的倍数,以便保持对齐。
原子有两种:
- 字词:一个 64 位值,可以进一步细分为位字段。 字词按机器字词顺序存储(在当前支持的所有架构上采用小端字节序)。
- 数据流:用零填充到下一个 8 字节边界的字节序列。流按字节顺序存储。系统不会填充长度为 8 个字节的整数倍的数据流(没有零终止符)。
字段是 64 位字的细分,以 [<least significant bit> .. <most significant bit>]
表示,其中首位和最后一个位包含。所有未使用的位都会预留以供将来使用,并且必须设置为 0。
除非记录格式另有指定,否则 Words 和 Fields 会存储无符号整数。
数据流可以存储 UTF-8 字符串或二进制数据,具体由记录格式指定。
记录
轨迹记录是轨迹信息的二进制编码片段,由一系列 Atom 组成。
所有记录都包含一个包含以下基本信息的标题字词:
- 记录类型:一个 4 位字段,用于标识记录的类型及其包含的信息。请参阅记录类型。
- 记录大小:通常是一个 12 位字段,表示记录(包括记录标头本身)中的单词数(8 字节的倍数)。记录的最大可能大小为 4095 个单词(32760 字节)。非常简单的记录可能只有 1 个字(8 个字节)。大型记录使用 32 位大小字段,因此具有更高的大小上限。
记录的长度始终是 8 个字节的倍数,并以 8 字节对齐方式进行存储。
存档
跟踪记录归档是端到端串联的一系列跟踪记录,其中存储了跟踪记录提供程序收集的信息,同时跟踪记录还会与元数据记录一起运行,这些元数据记录用于标识和分隔每个跟踪记录提供程序所生成的跟踪记录的部分内容。
跟踪归档旨在按顺序读取,因为跟踪记录中较早出现的记录可能会影响对跟踪记录中后期出现的记录的解释。轨迹系统提供了一些工具,用于从轨迹归档中提取信息,并将其转换为其他形式,以便直观呈现。
时间戳
时间戳表示为源自硬件计数器的 64 位 tick。 跟踪记录初始化记录描述了实时的每秒 tick 数。
默认情况下,我们假设 1 个基点等于 1 纳秒。
字符串引用
字符串被编码为字符串引用,它是以下形式的 16 位值:
- 空字符串:值为零。
- 编入索引的字符串:最高有效位为零。低 15 位表示之前使用字符串记录分配的字符串表中的索引。
- 内联字符串:最高有效位为 1 位。低 15 位表示字符串的长度(以字节为单位)。该字符串的内容将按照记录格式指定的内嵌方式显示在记录的其他部分中。
为了使跟踪记录更加紧凑,经常引用的字符串(例如事件类别和名称常量),应使用字符串记录注册到字符串表中,然后通过索引进行引用。
字符串表中最多可以包含 32767 个字符串。如果达到此上限,则可以通过替换现有条目或以内嵌方式对字符串进行编码,对其他字符串进行编码。
字符串内容本身以 UTF-8 流的形式存储,无终止状态。
字符串理论上的最大长度为 32767 字节,但在实践中,因存储包含该字符串的记录的其余部分所需的空间而进一步减少了此长度,因此我们保守地设置了 32000 字节的字符串长度上限。
线程引用
线程和进程内核对象 ID (koids) 会编码为线程引用,它们是采用以下格式的 8 位值:
- 内嵌会话:值为零。线程和进程 koid 将按照记录格式指定的内嵌方式显示在记录的其他部分中。
- 编入索引的线程数:值非零。该值表示之前使用线程记录分配的线程表中的索引。
为使跟踪记录更加紧凑,应使用线程记录将经常引用的线程注册到线程表,然后通过索引引用这些线程。
字符串表中最多可以有 255 个线程。如果达到此上限,则可以通过替换现有条目或以内嵌方式对线程进行编码,对其他线程进行编码。
用户空间对象信息
跟踪记录能够以用户空间对象记录的形式包含关于用户空间对象(可使用指针类值引用的任何内容,例如 C++ 或 Dart 对象)的注解。跟踪记录提供程序通常会在创建对象时生成此类记录。
之后,任何引用同一指针的指针参数都将与引用的注解相关联。
这样,您可以轻松地将人类可读的标签和其他信息与稍后出现在跟踪记录中的对象相关联。
内核对象信息
跟踪记录可以包含有关内核对象(可使用 Zircon koid 引用的任何内容,例如进程、通道或事件)形式的内核对象记录的注解。跟踪记录提供程序通常会在创建对象时生成此类记录。
此后,引用同一 koid 的任何内核对象 ID 参数都将与该引用的注解相关联。
这样,您可以轻松地将人类可读的标签和其他信息与稍后出现在跟踪记录中的对象相关联。
具体来说,这是跟踪系统将名称与进程和线程 koid 关联起来的方式。
参数
参数是类型化键值对。
许多记录类型最多允许向记录附加 15 个参数,以提供开发者提供的其他信息。
参数带有大小前缀(就像普通记录一样),以便跳过无法识别的参数类型。
如需了解详情,请参阅参数类型。
扩展格式
轨迹格式可以通过以下方式扩展:
- 定义新的记录类型。
- 将新信息存储在现有记录类型的预留字段中。
- 将新信息附加到现有记录类型(可以通过检查记录的大小和载荷来检测是否存在此信息)。
- 定义新的参数类型。
记录类型
记录类型如下:
- 记录标头
- 大型记录标头
- 元数据记录(记录类型 = 0)
- 初始化记录(记录类型 = 1)
- 字符串记录(记录类型 = 2)
- 线程记录(记录类型 = 3)
- 事件记录(记录类型 = 4)
- Blob 记录(记录类型 = 5)
- 用户空间对象记录(记录类型 = 6)
- 内核对象记录(记录类型 = 7)
- 调度记录(记录类型 = 8)
- 日志记录(记录类型 = 9)
- 大型 BLOB 记录(记录类型 = 15,大类型 = 0)
记录标题
所有记录都包含此标头(用于指定记录的类型和大小)以及 48 位数据(数据使用情况因记录类型而异)。
格式
标题字词
[0 .. 3]
:记录类型[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 63]
:因记录类型而异(如果未使用,则必须为零)
大型记录标头
支持大于 32KB 的记录。大型记录具有 32 位大小字段,而不是常规的 12 位。
标题字词
[0 .. 3]
:记录类型 (15)[4 .. 35]
:记录大小(包括此单词),表示为 8 个字节的倍数[36 .. 39]
:大型记录类型[40 .. 63]
:因大型记录类型而异(如果未使用,则必须为零)
元数据记录(记录类型 = 0)
提供关于后面的轨迹数据的元数据。
此记录类型是预留的,供跟踪管理器在生成跟踪记录归档时使用。它不得由跟踪记录提供程序本身发出。如果跟踪管理器在轨迹提供程序生成的轨迹中遇到元数据记录,就会将其视为垃圾并跳过它。
元数据记录子类型有多种,每个子类型都包含不同的信息。
格式
标题字词
[0 .. 3]
:记录类型 (0)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 19]
:元数据类型[20 .. 63]
:因元数据类型而异(如果未使用,则必须为零)
提供方信息元数据(元数据类型 = 1)
此元数据标识为跟踪记录贡献信息的跟踪记录提供程序。
遇到下一个提供方部分元数据或提供方信息元数据之前的所有数据都必须从同一提供方收集。
格式
标题字词
[0 .. 3]
:记录类型 (0)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 19]
:元数据类型 (1)[20 .. 51]
:提供程序 ID(用于在跟踪记录中标识提供程序的令牌)[52 .. 59]
:名称长度(以字节为单位)[60 .. 63]
:预留(必须为零)
提供方名称流
- UTF-8 字符串,填充有零到 8 字节对齐
提供方部分元数据(元数据类型 = 2)
此元数据划分了从不同提供程序获取的跟踪记录部分。
找到下一个提供方部分元数据或提供方信息元数据之前的所有数据都假定从同一提供方收集。
读取包含来自不同跟踪记录提供程序的跟踪记录累积的跟踪记录时,读取器必须单独维护每个提供程序的跟踪记录(例如初始化数据、字符串表、线程表、用户空间对象表和内核对象表)的状态,并在遇到新的提供程序部分元数据记录时切换上下文。
格式
标题字词
[0 .. 3]
:记录类型 (0)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 19]
:元数据类型 (2)[20 .. 51]
:提供程序 ID(用于在跟踪记录中标识提供程序的令牌)[52 .. 63]
:预留(必须为零)
提供方事件元数据(元数据类型 = 3)
此元数据针对提供程序要报告的事件提供运行通知。
此记录可以出现在输出中的任何位置,并且不会区分其前面或后面的内容。
格式
标题字词
[0 .. 3]
:记录类型 (0)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 19]
:元数据类型 (3)[20 .. 51]
:提供程序 ID(用于在跟踪记录中标识提供程序的令牌)[52 .. 55]
:事件 ID[56 .. 63]
:预留(必须为零)
事件
已定义以下事件。
0
:缓冲区已填满,记录可能已被丢弃
跟踪信息元数据(元数据类型 = 4)
此元数据提供了有关整个跟踪记录的信息。此记录不与特定提供方关联。
格式
标题字词
[0 .. 3]
:记录类型 (0)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 19]
:元数据类型 (4)[20 .. 23]
:跟踪记录信息类型[24 .. 63]
:因跟踪记录信息类型而异(如果未使用,则必须为零)
魔数记录(跟踪信息类型 = 0)
此记录指明二进制数据采用 Fuchsia 跟踪格式。它通常应出现在跟踪记录的开头。而不包含任何其他信息。魔数 0x16547846
是字符串“FxT”后跟一个随机选择的字节。
为了在不关心内部记录结构的情况下将跟踪记录的前 8 个字节视为魔数,此记录类型不可扩展。记录不得包含除标头字词以外的任何单词,并且没有预留字段。整个记录的值为 8 个字节,值为 0x0016547846040010。
请注意,该值的字节顺序以及跟踪记录中的所有其他字词取决于写入跟踪记录的系统的字节顺序。对于小端字节序系统,前八字节为 10 00 04 46 78 54 16 00。在大端字节系统中,结果则相反:00 16 54 78 46 04 00 10。
格式
标题字词
[0 .. 3]
:记录类型 (0)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数 (1)[16 .. 19]
:元数据类型 (4)[20 .. 23]
:跟踪记录信息类型 (0)[24 .. 55]
:魔数 0x16547846[56 .. 63]
:零
初始化记录(记录类型 = 1)
提供解释随后的记录所需的参数。如果没有此记录,读取器可能会假定 1 tick 为 1 纳秒。
格式
标题字词
[0 .. 3]
:记录类型 (1)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 63]
:预留(必须为零)
滴定调节系数字词
[0 .. 63]
:每秒跳动次数
字符串记录(记录类型 = 2)
在字符串表中注册一个字符串,并向其分配 0x0001
到 0x7fff
范围内的字符串索引。在解析后面的记录时,注册会替换给定字符串索引的所有先前注册。
必须忽略尝试为字符串索引 0x0000
设置值的字符串记录,因为该值已被保留以表示空字符串。
必须容忍包含空字符串的字符串记录,但它们没有意义,因为在字符串引用中,空字符串可以简单编码为 0。
格式
标题字词
[0 .. 3]
:记录类型 (2)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 30]
:字符串索引(范围 0x0001 到 0x7fff)[31]
:始终为零 (0)[32 .. 46]
:字符串长度,以字节为单位(范围 0x0000 到 0x7fff)[47]
:始终为零 (0)[48 .. 63]
:预留(必须为零)
字符串值流
- UTF-8 字符串,填充有零到 8 字节对齐
线程记录(记录类型 = 3)
在线程表中注册进程 ID 和线程 ID 对,并向其分配 0x01
到 0xff
范围内的线程索引。在解析随后的记录时,注册将替换给定线程索引的任何先前注册。
线程索引 0x00
已预留,用于表示在线程引用中使用内嵌线程 ID。必须忽略尝试为此值设置值的线程记录。
格式
标题字词
[0 .. 3]
:记录类型 (3)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 23]
:线程索引(绝不会为 0x00)[24 .. 63]
:预留(必须为零)
进程 ID 字词
[0 .. 63]
:进程 koid(内核对象 ID)
会话 ID 字词
[0 .. 63]
:线程 koid(内核对象 ID)
事件记录(记录类型 = 4)
描述带时间戳的事件。
此记录包含有关事件的一些基本信息,包括事件发生的时间和位置,后跟事件参数和事件子类型特定数据。
格式
标题字词
[0 .. 3]
:记录类型 (4)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 19]
:事件类型[20 .. 23]
:参数数量[24 .. 31]
:线程(线程引用)[32 .. 47]
:类别(字符串引用)[48 .. 63]
:名称(字符串引用)
时间戳字词
[0 .. 63]
:刻度线数量
进程 ID 字词(除非线程引用表示内嵌线程,否则请省略)
[0 .. 63]
:进程 koid(内核对象 ID)
thread id word(除非线程引用表示内嵌线程,否则请省略)
[0 .. 63]
:线程 koid(内核对象 ID)
类别流(除非字符串 ref 表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
name stream(除非字符串 ref 表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
参数数据(对每个参数重复)
- (请参见下文)
事件类型特定数据
- 可以是以下任意一项:
即时事件(事件类型 = 0)
在此会话中标记时间。这相当于 Zircon 内核探测。
格式
无需特定于事件类型的数据。
计数器事件(事件类型 = 1)
将每个参数的样本值记录为与计数器的名称和 ID 关联的时间序列中的数据。这些值可以图形方式显示为堆叠面积图。
格式
反语
[0 .. 63]
:计数器 ID
时长开始事件(事件类型 = 2)
标记特定线程上的操作开始。必须与时长结束事件匹配。可以嵌套。
格式
无需特定于事件类型的数据。
持续时间结束事件(事件类型 = 3)
标记特定线程上的操作结束。
格式
无需特定于事件类型的数据。
持续时间完成事件(事件类型 = 4)
标记特定线程中某项操作的开始和结束。
格式
结束时间字词
[0 .. 63]
:结束时间点数
Async begin event (event type = 5)
标记可能跨线程的操作开始。必须与使用同一异步关联 ID 的异步结束事件匹配。
格式
async correlation word
[0 .. 63]
: async correlation id
异步即时事件(事件类型 = 6)
标记某项操作中可能跨线程的时刻。必须出现在使用相同的异步关联 ID 的async begin event和async begin event之间。
格式
async correlation word
[0 .. 63]
: async correlation id
Async end event (event type = 7)
标记可能跨线程的操作的结束。
格式
async correlation word
[0 .. 63]
: async correlation id
流程开始事件(事件类型 = 8)
标记操作的开始,该操作会生成可能跨多个线程或抽象层的一系列操作。必须与使用同一流关联 ID 的流结束事件匹配。这可以想象为时长事件之间的箭头。
流程的开头与此线程的封闭时长事件相关联;它从封闭的时长事件结束处开始。
格式
流相关词
[0 .. 63]
:流关联 ID
流程步骤事件(事件类型 = 9)
标记流内的点。
该步骤与此线程的封闭时长事件相关联;数据流从封闭时长事件开始处恢复,然后在封闭时长事件结束时暂停。
格式
流相关词
[0 .. 63]
:流关联 ID
流程结束事件(事件类型 = 10)
标记流的结束。
流程的结尾与此线程的封闭时长事件相关联;流程将在封闭的时长事件开始时恢复。
格式
流相关词
[0 .. 63]
:流关联 ID
BLOB 记录(记录类型 = 5)
提供要包含在跟踪记录中的未经解读的批量数据。这对于以其他格式嵌入捕获的轨迹数据非常有用。
blob 名称唯一标识跟踪记录中的单独 blob 数据流。通过写入具有相同名称的多个 blob 记录,可以将额外的数据块附加到先前创建的 BLOB。
BLOB 类型表示 BLOB 的内容表示。
格式
标题字词
[0 .. 3]
:记录类型 (5)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 31]
:blob 名称(字符串引用)[32 .. 46]
:blob 载荷大小(以字节为单位,不包括填充)[47 .. 47]
:预留(必须为零)[48 .. 55]
:blob 类型[56 .. 63]
:预留(必须为零)
blob 名称流(除非字符串 ref 表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
载荷流(大小可变)
- 二进制数据,填充 0 到 8 字节对齐
Blob 类型
定义了以下 blob 类型:
TRACE_BLOB_TYPE_DATA
=0x01
:非类型化原始数据。使用方应该知道如何使用它(可能根据上下文)。TRACE_BLOB_TYPE_LAST_BRANCH
=0x02
:Intel Performance Monitor 的最后一个分支记录。 格式由 CPU 性能监视器定义。TRACE_BLOB_TYPE_PERFETTO =
0x03`:blob 包含从 Perfetto 语音组件记录的数据。数据采用 Perfetto 的 Proto 格式进行编码。
用户空间对象记录(记录类型 = 6)
描述用户空间对象,为其分配标签,并视需要将键值对数据作为参数与其关联。对象的相关信息会添加到每个进程的用户空间对象表中。
当轨迹使用方遇到具有指针参数的事件时,其值与进程的对象表中的条目匹配,它可以将该参数的指针值与先前的用户空间对象记录交叉引用,以查找对引用的描述。
格式
标题字词
[0 .. 3]
:记录类型 (6)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 23]
:进程(线程引用)[24 .. 39]
:名称(字符串引用)[40 .. 43]
:参数数量[44 .. 63]
:预留(必须为零)
指针词
[0 .. 63]
:指针值
进程 ID 字词(除非线程引用表示内嵌线程,否则请省略)
[0 .. 63]
:进程 koid(内核对象 ID)
name stream(除非字符串 ref 表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
参数数据(对每个参数重复)
- (请参见下文)
内核对象记录(记录类型 = 7)
描述内核对象,为其分配标签,并视需要将键值对数据作为参数与其关联。系统会将该对象的相关信息添加到一个全局内核对象表中。
当轨迹使用方遇到具有 koid 参数的事件时,其值与内核对象表中的条目相匹配,它可以将该参数的 koid 值与之前的内核对象记录进行交叉引用,以找到对指代的说明。
格式
标题字词
[0 .. 3]
:记录类型 (7)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 23]
:内核对象类型(zircon/syscalls/types.h 中的 ZX_OBJ_TYPE_XXX 常量之一)[24 .. 39]
:名称(字符串引用)[40 .. 43]
:参数数量[44 .. 63]
:预留(必须为零)
内核对象 ID 字词
[0 .. 63]
:koid(内核对象 ID)
name stream(除非字符串 ref 表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
参数数据(对每个参数重复)
- (请参见下文)
参数约定
按照惯例,在写入有关特定类型的对象的内核对象记录时,跟踪记录写入器应包含以下具名实参。这有助于跟踪使用方关联内核对象之间的关系。
"process"
:对于ZX_OBJ_TYPE_THREAD
对象,指定包含线程的进程的 koid
安排记录(记录类型 = 8)
描述调度事件,例如何时唤醒线程,或何时从一个线程切换到另一个线程。
格式
+---------(4)--------------+--------(48)--------+--(8)--+-(4)-+
| scheduling record type | <type specific> | size | 8 |
+--------------------------+--------------------+-------+-----+
标题字词
[0 .. 3]
:记录类型 (8)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 59]
:调度记录类型专属数据[60 .. 63]
:时间安排记录类型
上下文切换记录(调度事件记录类型 = 1)
格式
+-(4)-+----(20)---+--------(4)-------+----(16)---+-------(4)-------+----(8)--+-(4)-+
| 1 | reserved | out thread state | cpu | argument count | size | 8 |
+-----+-----------+------------------+-----------+-----------------+---------+-----+
+---------------------------(64)------------------------------+
| timestamp |
+-------------------------------------------------------------+
+---------------------------(64)------------------------------+
| outgoing thread id |
+-------------------------------------------------------------+
+---------------------------(64)------------------------------+
| incoming thread id |
+-------------------------------------------------------------+
+--------------------------(...)------------------------------+
| argument data |
+-------------------------------------------------------------+
标题字词
[0 .. 3]
:记录类型 (8)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 19]
:参数数量[20 .. 35]
:CPU 编号[36 .. 39]
:传出线程状态[40 .. 59]
:预留[60 .. 63]
:时间安排记录类型 (1)
时间戳字词
[0 .. 63]
:刻度线数量
出站线程 ID
[0 .. 63]
:线程 koid(内核对象 ID)
传入线程 ID
[0 .. 63]
:线程 koid(内核对象 ID)
参数数据(每个参数的重复项)
- (如需了解参数格式,请参阅参数)
参数约定
按照惯例,在写入此记录时,跟踪记录写入器还可以选择包含以下命名参数,以便为跟踪记录使用方提供额外信息。
线程唤醒记录(调度事件记录类型 = 2)
格式
+-(4)-+----(24)---+----(16)---+-------(4)-------+----(8)--+-(4)-+
| 2 | reserved | cpu | argument count | size | 8 |
+-----+-----------+-----------+-----------------+---------+-----+
+---------------------------(64)------------------------------+
| timestamp |
+-------------------------------------------------------------+
+---------------------------(64)------------------------------+
| waking thread id |
+-------------------------------------------------------------+
+--------------------------(...)------------------------------+
| argument data |
+-------------------------------------------------------------+
标题字词
[0 .. 3]
:记录类型 (8)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 19]
:参数数量。[20 .. 35]
:CPU 编号。[60 .. 63]
:时间安排记录类型 (2)
时间戳字词
[0 .. 63]
:刻度线数量
唤醒线程 ID
[0 .. 63]
:线程 koid(内核对象 ID)
参数数据(每个参数的重复项)
- (如需了解参数格式,请参阅参数)
参数约定
按照惯例,在写入此记录时,跟踪记录写入器还可以选择包含以下命名参数,以便为跟踪记录使用方提供额外信息。
"weight"
:Int32
,用于描述唤醒线程的相对权重
旧版上下文切换记录(上下文切换记录类型 = 0)
随着 Fuchsia 时间安排不断演变,此记录不再是有效的上下文切换模型。它仍会保留以确保向后兼容性。
该记录指定上下文切换后传出线程的新状态。根据定义,传入线程的新状态为“正在运行”,因为它刚刚恢复。
格式
[0 .. 3]
:记录类型 (8)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 23]
:CPU 编号[24 .. 27]
:传出线程的状态(以下任何值,“running”除外)[28 .. 35]
:外发会话(会话引用)[36 .. 43]
:传入线程(线程引用)[44 .. 51]
:传出线程优先级[52 .. 59]
:传入线程优先级[60 .. 63]
:时间安排记录类型 (0)
时间戳字词
[0 .. 63]
:刻度线数量
传出进程 ID 字词(除非传出线程引用表示内嵌线程,否则请省略)
[0 .. 63]
:进程 koid(内核对象 ID)
外发话题 ID 字词(除非外发话题引用表示内嵌话题,否则会被省略)
[0 .. 63]
:线程 koid(内核对象 ID)
incoming process id word(除非传入线程引用表示内嵌线程,否则请省略)
[0 .. 63]
:进程 koid(内核对象 ID)
incoming thread id word(除非传入线程引用表示内嵌线程,否则请忽略)
[0 .. 63]
:线程 koid(内核对象 ID)
线程状态
定义了以下线程状态:
0
:新1
:正在运行2
:已暂停3
:已屏蔽4
:即将死亡5
:已终止
这些值与 zircon/syscalls/object.h 中的 ZX_THREAD_STATE_XXX
常量一致。
日志记录(记录类型 = 9)
描述在特定时间点写入日志的消息。
格式
标题字词
[0 .. 3]
:记录类型 (9)[4 .. 15]
:记录大小(包括此单词),表示为 8 个字节的倍数[16 .. 30]
:日志消息长度,以字节为单位(范围 0x0000 到 0x7fff)[31]
:始终为零 (0)[32 .. 39]
:线程(线程引用)[40 .. 63]
:预留(必须为零)
时间戳字词
[0 .. 63]
:刻度线数量
进程 ID 字词(除非线程引用表示内嵌线程,否则请省略)
[0 .. 63]
:进程 koid(内核对象 ID)
thread id word(除非线程引用表示内嵌线程,否则请省略)
[0 .. 63]
:线程 koid(内核对象 ID)
日志消息流
- UTF-8 字符串,填充有零到 8 字节对齐
大型 BLOB 记录(记录类型 = 15,大类型 = 0)
提供要嵌入跟踪记录中的大型二进制 BLOB 数据。它使用较大的记录标头。
大型 BLOB 记录支持多种不同的格式。这些格式可用于记录中包含的各类 BLOB 数据和元数据。
格式
标题字词
[0 .. 3]
:记录类型 (15)[4 .. 35]
:记录大小(包括此单词),表示为 8 个字节的倍数[36 .. 39]
:大型记录类型 (0)[40 .. 43]
:blob 格式类型[44 .. 63]
:预留,必须为零
带元数据的带内大型 Blob 记录(Blob 格式 = 0)
该类型包含 blob 数据和记录本身的元数据。元数据包括时间戳、线程/进程信息和参数,以及类别和名称。
名称应足以识别 blob 中包含的数据类型。
格式
标题字词
[0 .. 3]
:记录类型 (15)[4 .. 35]
:记录大小(包括此单词),表示为 8 个字节的倍数[36 .. 39]
:大型记录类型 (0)[40 .. 43]
:blob 格式类型 (0)[44 .. 63]
:预留,必须为零
格式标题字词
[0 .. 15]
:类别(字符串引用)[16 .. 31]
:名称(字符串引用)[32 .. 35]
:参数数量[36 .. 43]
:线程(线程引用)[44 .. 63]
:预留,必须为零
类别流(除非字符串 ref 表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
name stream(除非字符串 ref 表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
时间戳字词
[0 .. 63]
:刻度线数量
进程 ID 字词(除非线程引用表示内嵌线程,否则请省略)
[0 .. 63]
:进程 koid(内核对象 ID)
thread id word(除非线程引用表示内嵌线程,否则请省略)
[0 .. 63]
:线程 koid(内核对象 ID)
参数数据(对每个参数重复)
- (请参见下文)
blob 大小字词
[0 .. 63]
:blob 载荷大小(以字节为单位,不包括填充)
载荷流(大小可变)
- 二进制数据,填充 0 到 8 字节对齐
带内大型 Blob 记录无元数据(Blob 格式 = 1)
该类型包含记录本身内的 blob 数据,但不包含元数据。该记录仅包含类别和名称。
名称应足以识别 blob 中包含的数据类型。
格式
标题字词
[0 .. 3]
:记录类型 (15)[4 .. 35]
:记录大小(包括此单词),表示为 8 个字节的倍数[36 .. 39]
:大型记录类型 (0)[40 .. 43]
:blob 格式类型 (1)[44 .. 63]
:预留,必须为零
格式标题字词
[0 .. 15]
:类别(字符串引用)[16 .. 31]
:名称(字符串引用)[32 .. 63]
:预留,必须为零
类别流(除非字符串 ref 表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
name stream(除非字符串 ref 表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
blob 大小字词
[0 .. 63]
:blob 载荷大小(以字节为单位,不包括填充)
载荷流(大小可变)
- 二进制数据,填充 0 到 8 字节对齐
参数类型
参数关联了类型化键和值数据记录。它们与事件记录、用户空间对象记录和内核对象记录一起使用。
每个参数都由一个单词标头组成,后跟可变数字的载荷字词。在许多情况下,标头本身足以对参数的内容进行编码。
有以下参数类型:
参数标头
所有参数均包含此标头,用于指定参数的类型、名称和大小,以及 32 位数据,其用法因参数类型而异。
格式
参数标头字词
[0 .. 3]
:参数类型[4 .. 15]
:参数大小(包含此单词),表示为 8 个字节的倍数[16 .. 31]
:参数名称(字符串引用)[32 .. 63]
:各不相同(如果未使用,则必须为零)
参数名称信息流(除非字符串引用表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
Null 参数(参数类型 = 0)
表示仅出现在名称中而不显示值的参数。
格式
参数标头字词
[0 .. 3]
:参数类型 (0)[4 .. 15]
:参数大小(包含此单词),表示为 8 个字节的倍数[16 .. 31]
:参数名称(字符串引用)[32 .. 63]
:预留(必须为零)
参数名称信息流(除非字符串引用表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
32 位有符号整数参数(参数类型 = 1)
表示 32 位有符号整数。
格式
参数标头字词
[0 .. 3]
:参数类型 (1)[4 .. 15]
:参数大小(包含此单词),表示为 8 个字节的倍数[16 .. 31]
:参数名称(字符串引用)[32 .. 63]
:32 位有符号整数
参数名称信息流(除非字符串引用表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
32 位无符号整数参数(参数类型 = 2)
表示 32 位无符号整数。
格式
参数标头字词
[0 .. 3]
:参数类型 (2)[4 .. 15]
:参数大小(包含此单词),表示为 8 个字节的倍数[16 .. 31]
:参数名称(字符串引用)[32 .. 63]
:32 位无符号整数
参数名称信息流(除非字符串引用表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
64 位有符号整数参数(参数类型 = 3)
表示 64 位有符号整数。如果某个值适合 32 位,请改用 32 位有符号整数参数类型。
格式
参数标头字词
[0 .. 3]
:参数类型 (3)[4 .. 15]
:参数大小(包含此单词),表示为 8 个字节的倍数[16 .. 31]
:参数名称(字符串引用)[32 .. 63]
:预留(必须为零)
参数名称信息流(除非字符串引用表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
参数值字词
[0 .. 63]
:64 位有符号整数
64 位无符号整数参数(参数类型 = 4)
表示 64 位无符号整数。如果某个值适合 32 位,请改用 32 位无符号整数参数类型。
格式
参数标头字词
[0 .. 3]
:参数类型 (4)[4 .. 15]
:参数大小(包含此单词),表示为 8 个字节的倍数[16 .. 31]
:参数名称(字符串引用)[32 .. 63]
:预留(必须为零)
参数名称信息流(除非字符串引用表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
参数值字词
[0 .. 63]
:64 位无符号整数
双精度浮点参数(参数类型 = 5)
表示双精度浮点数。
格式
参数标头字词
[0 .. 3]
:参数类型 (5)[4 .. 15]
:参数大小(包含此单词),表示为 8 个字节的倍数[16 .. 31]
:参数名称(字符串引用)[32 .. 63]
:预留(必须为零)
参数名称信息流(除非字符串引用表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
参数值字词
[0 .. 63]
:双精度浮点数
字符串参数(参数类型 = 6)
表示字符串值。
格式
参数标头字词
[0 .. 3]
:参数类型 (6)[4 .. 15]
:参数大小(包含此单词),表示为 8 个字节的倍数[16 .. 31]
:参数名称(字符串引用)[32 .. 47]
:参数值(字符串引用)[48 .. 63]
:预留(必须为零)
参数名称信息流(除非字符串引用表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
参数值数据流(除非字符串引用表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
指针参数(参数类型 = 7)
表示指针值。关于所引用对象的其他信息可以由与同一指针关联的用户空间对象记录提供。
格式
参数标头字词
[0 .. 3]
:参数类型 (7)[4 .. 15]
:参数大小(包含此单词),表示为 8 个字节的倍数[16 .. 31]
:参数名称(字符串引用)[32 .. 63]
:预留(必须为零)
参数名称信息流(除非字符串引用表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
参数值字词
[0 .. 63]
:指针值
内核对象 ID 参数(参数类型 = 8)
表示 koid(内核对象 ID)。关于所引用对象的其他信息可通过与同一 koid 关联的内核对象记录提供。
格式
参数标头字词
[0 .. 3]
:参数类型 (8)[4 .. 15]
:参数大小(包含此单词),表示为 8 个字节的倍数[16 .. 31]
:参数名称(字符串引用)[32 .. 63]
:预留(必须为零)
参数名称信息流(除非字符串引用表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐
参数值字词
[0 .. 63]
:koid(内核对象 ID)
布尔值参数(参数类型 = 9)
表示布尔值。
格式
参数标头字词
[0 .. 3]
:参数类型 (9)[4 .. 15]
:参数大小(包含此单词),表示为 8 个字节的倍数[16 .. 31]
:参数名称(字符串引用)[32 .. 63]
:用零填充的 1 位
参数名称信息流(除非字符串引用表示内嵌字符串,否则请省略)
- UTF-8 字符串,填充有零到 8 字节对齐