diff --git a/ide/src/doc/des_tables.html b/ide/src/doc/des_tables.html
index 82879585cca652373870881b3de9970be0fc0a56..db8fe5e1c1ac6a2b3aad842c0fac2ac8f7471d56 100644
--- a/ide/src/doc/des_tables.html
+++ b/ide/src/doc/des_tables.html
@@ -896,6 +896,42 @@
perf_callchain |
@@ -1385,6 +1485,10 @@
native_hook_frame表记录内存申请/释放的调用堆栈。通过callChainId区分一组调用堆栈,depth为堆栈深度,depth为0时,表示当前行为栈顶数据。
+
+ native_hook_statistic表记录内存申请/释放的统计信息。通过callChainId区分一组调用堆栈。每个统计事件将记录当前事件的callChainId,并统计当前调用栈内存分配/释放的总次数和总大小。
+
+
@@ -1395,25 +1499,28 @@
>
-
- 已知callchainid = 0, 查看当前内存变化调用堆栈
- select * from native_hook_frame where callChainId = 0
+ 已知callchainid = 1, 查看当前内存变化调用堆栈
+ select * from native_hook_frame where callchain_id = 1
+
+ -
+ 已知callchainid = 1, 查看当前内存变化调用堆栈对应的统计信息
+ select * from native_hook_statistic where callchain_id = 1
-
-
+ 日志表与进程线程表关系图
log表记录日志信息。可以根据seq字段的连续性,来判断是否存在日志丢失的情况。
-
-
+ 查询举例
-
已知tid = 123,查看当前线程的所有error级别的日志,可以使用如下SQL语句:
select * from log where tid = 123 and level = "error"
- perf表之间关系图
+
+
- perf_report:此表记录Hiperf工具采集数据时的配置信息。
- perf_thread:此表记录hiperf采集到的进程和线程数据。
@@ -1426,7 +1533,8 @@

- 查询举例
+
+
- 帧渲染表之间的关系图
+
+
frame_slice: 记录RS(RenderService)和应用的帧渲染。
gpu_slice: 记录RS的帧对应的gpu渲染时长。
frame_maps:记录应用到RS的帧的映射关系。
- 查询示例
+
+
-
-
-
-
-
-
+ JS内存数据表关系图
+ js_heap_files:记录js内存数据的文件名和文件索引
+ 
+
+ js_heap_nodes:记录js内存类对象数据
+ js_heap_edges:记录js内存类对象的成员数据
+ js_heap_trace_node:记录timeline的调用栈信息
+ js_heap_sample:记录timeline的时间轴信息
+
+
+ TraceStreamer输出数据库表格详细介绍
+ app_name表
+ 表结构
-
-
+ 表描述
记录HiSysevent上报事件中的IDE相关事件中APPNAME的表关联信息。
-
-
+ 字段详细描述
- id:用于与表hisys_event_measure表中的key_id字段做对应
- app_name:对应的事件的信息ID
- app_key:对应的事件的APPNAME字段的信息ID
-
-
-
-
+ args表
+ 表结构
-
-
+ 表描述
记录方法的参数集合。
-
-
+ 字段详细描述
- key:键
- datatype:数据类型
- value:取值
- argset:参数集合
-
-
-
-
+ bio_latency_sample表
+ 表结构
-
-
+ 表描述
记录IO操作相关方法调用,及调用栈数据。
-
-
+ 字段详细描述
- callchain_id:调用栈的唯一标识。与ebpf_callstack表中Callchain_id字段关联
-
@@ -1683,10 +1790,8 @@
- path:路径id
- dur_per_4k:每4k数据的平均延迟
-
-
-
-
+ callstack表
+ 表结构
-
-
+ 表描述
记录调用堆栈和异步调用信息,其中depth,stack_id和parent_stack_id仅在非异步的调用中有效。当cookid不为空时,为异步调用,此时callid为进程唯一号,否则为线程唯一号。
-
-
+ 字段详细描述
- dur:调用时长
- callid:调用者的ID,比如针对线程表里面的id
@@ -1779,10 +1882,8 @@
- flag:C表示分布式调用发送方,S表示接受方
- args:分布式调用函数参数
-
-
-
-
+ clk_event_filter表
+ 表结构
-
-
+ 表描述
记录时钟信息。
-
-
+ 字段详细描述
-
-
-
-
+ clock_event_filter表
+ 表结构
-
-
+ 表描述
此结构用来维护时钟事件,cpu与唯一的ID做关联。
-
-
+ 主要字段描述
-
-
-
-
+ cpu_measure_filter表
+ 表结构
-
-
+ 表描述
将cpu号作为key1,cpu的频率,空闲等状态作为key2,唯一确定一个filter_id。
-
-
+ 主要字段描述
- Id(filterid), cpu:事件名称,cpu号
-
-
-
-
+ cpu_usage表
+ 表结构
-
-
+ 表描述
记录了与CPU使用率相关的数据。
-
-
+ 主要字段描述
- total_load:总负荷
- user_load:用户负载
- system_load:系统负载
- process_num:线程数
-
-
-
-
+ data_dict表
+ 表结构
-
-
+ 表描述
此表记录了一个数据类型ID和字符串的映射。
-
-
+ 主要字段描述
-
-
-
-
+ data_type表
+ 表结构
-
-
+ 表描述
此表记录了一个数据类型ID和数据描述的映射。
-
-
+ 主要字段描述
- typeId::数据类型id
- Desc:数据类型描述
-
-
-
-
+ diskio表
+ 表结构
-
-
+ 表描述
记录了与磁盘读写相关的数据。
-
-
+ 主要字段描述
- rd_sectors_kb:读数据的速度
- wr_sectors_kb:写入数据的速度
- ts:时间戳
-
-
-
-
+ ebpf_callstack表
+ 表结构
-
-
+ 表描述
记录了与磁盘读写相关的数据。
-
-
+ 主要字段描述
- callchain_id:调用栈的唯一标识。与ebpf_callstack表中Callchain_id字段关联
- depth:调用栈深度。取值为零时表示栈顶
@@ -2124,10 +2195,8 @@
- symbols_id:调用栈函数名称, 与data_dict中的id字段关联
- file_path_id:调用栈函数所属文件路径, 与data_dict中的id字段关联
-
-
-
-
+ file_system_sample表
+ 表结构
-
-
+ 表描述
记录了调用栈的相关信息。
-
-
+ 主要字段描述
- callchain_id:调用栈信息ID与file_system_callstack表中call_chain_id字段相关联
- type:对应文件操作open,close,read,write
@@ -2224,10 +2291,8 @@
- third_argument:参数三
- fourth_argument:参数四
-
-
-
-
+ hidump表
+ 表结构
-
-
+ 表描述
此表记录了设备的帧率信息,fps。
-
-
+ 相关字段描述
-
-
-
-
+ hisys_event_measure表
+ 表结构
-
-
+ 表描述
记录所有的system event事件的相关数据,及其相关表的映射信息。
-
-
+ 相关字段描述
- serial:每条数据过来携带唯一一条id作为标识
- name_id:存放事件对应的ID,与data_dict表相关联可以取出对应的字段
@@ -2316,10 +2375,8 @@
- int_value:存放本事件所包含的字段的int型的值
- string_value:存放本事件所包含的字段的string型的值
-
-
-
-
+ instant表
+ 表结构
@@ -2349,28 +2406,412 @@
TEXT |
- value |
- REAL |
+ value |
+ REAL |
+
+
+
+ 表描述
+ 记录了系统中的waking和wakeup事件。
+ 字段描述
+
+ - ts:唤醒时间
+ - name:唤醒事件的名称
+ - ref:索引号
+ - wakeup_from:唤醒当前线程的内部线程号(itid)
+ - ref_type:描述了value字段的类型(一般取值为itid)
+ - value:一般为当前线程的内部线程号取值
+
+ irq表
+ 表结构
+
+
+
+ Columns Name |
+ SQL TYPE |
+
+
+
+
+ id |
+ INT |
+
+
+ ts |
+ INT |
+
+
+ dur |
+ INT |
+
+
+ callid |
+ INT |
+
+
+ cat |
+ TEXT |
+
+
+ name |
+ TEXT |
+
+
+ depth |
+ INT |
+
+
+ cookie |
+ INT |
+
+
+ parent_id |
+ INT |
+
+
+ argsetid |
+ INT |
+
+
+ chainId |
+ TEXT |
+
+
+ spanId |
+ TEXT |
+
+
+ parentSpanId |
+ TEXT |
+
+
+ flag |
+ TEXT |
+
+
+ args |
+ TEXT |
+
+
+
+ 表描述
+ 记录中断相关事件。
+ 相关字段描述
+
+ - dur:调用中断时长
+ - callid:调用中断者的ID,比如针对线程表里面的id
+ - cat:调用栈数据类型(取值范围:irq,softirq...)
+ - name:调用中断的名称
+ - depth:中断调用的深度
+ - parent_id:父调用中断的id
+ - spanId:分布式调用中断关联关系
+
+ js_heap_edges表
+ 表结构
+
+
+
+ Columns Name |
+ SQL TYPE |
+
+
+
+
+ file_id |
+ INT |
+
+
+ edge_index |
+ INT |
+
+
+ type |
+ INT |
+
+
+ name_or_index |
+ INT |
+
+
+ to_node |
+ INT |
+
+
+ from_node_id |
+ INT |
+
+
+ to_node_id |
+ INT |
+
+
+
+ 表描述
+ 记录js内存数据类对象对应的成员的信息。
+ 相关字段描述
+
+ - file_id:文件ID
+ - edge_index:成员的索引号
+ - type:成员的类型,取值范围为js_heap_info表中的edge_types
+ - name_or_index:数据名称,取值为js_heap_string表中的下标索引
+ - to_node:此成员指向的类对象在nodes数组中的索引
+ - from_node_id:类对象ID,该类对象指向此成员数据
+ - to_node_id:此成员指向到的类对象nodes数组中的ID
+
+ js_heap_files表
+ 表结构
+
+
+
+ Columns Name |
+ SQL TYPE |
+
+
+
+
+ id |
+ INT |
+
+
+ file_name |
+ TEXT |
+
+
+ start_time |
+ INT |
+
+
+ end_time |
+ INT |
+
+
+ pid |
+ INT |
+
+
+
+ 表描述
+ 记录了js内存数据的文件名称和时间。
+ 相关字段描述
+
+ - id:文件ID
+ - file_name:文件名称
+ - start_time:数据抓取的起始时间
+ - end_time:数据抓取的终止时间
+ - pid:进程号
+
+ js_heap_info表
+ 表结构
+
+
+
+ Columns Name |
+ SQL TYPE |
+
+
+
+
+ file_id |
+ INT |
+
+
+ key |
+ TEXT |
+
+
+ type |
+ INT |
+
+
+ int_value |
+ INT |
+
+
+ str_value |
+ TEXT |
+
+
+
+ 表描述
+ 记录了js内存数据类型,如nodes和edges的字段类型和数据总数。
+ 相关字段描述
+
+ - file_id:文件ID
+ - key:类型名称
+ - type:数据类型索引
+ - int_value:int类型的数据值,如count类型数据
+ - str_value:string类型的数据值,如typename
+
+ js_heap_location表
+ 表结构
+
+
+
+ Columns Name |
+ SQL TYPE |
+
+
+
+
+ file_id |
+ INT |
+
+
+ object_index |
+ INT |
+
+
+ script_id |
+ INT |
+
+
+ line |
+ INT |
+
+
+ column |
+ INT |
+
+
+
+ 表描述
+ 记录了js内存location节点相关数据,此表目前无抓取到的数据。
+ 相关字段描述
+
+ - file_id:文件ID
+ - object_index:与location关联的类对象的索引,取值为js_heap_nodes的下标索引
+ - script_id:关联到的类对象所在文件的绝对路径ID
+ - line:在类对象所在的文件中的行号
+ - column:在类对象所在的文件中的列号
+
+ js_heap_nodes表
+ 表结构
+
+
+
+ Columns Name |
+ SQL TYPE |
+
+
+
+
+ file_id |
+ INT |
+
+
+ node_index |
+ TEXT |
+
+
+ type |
+ INT |
+
+
+ name |
+ INT |
+
+
+ id |
+ TEXT |
+
+
+ self_size |
+ INT |
+
+
+ edge_count |
+ INT |
+
+
+ trace_node_id |
+ INT |
+
+
+ detachedness |
+ INT |
+
+
+
+ 表描述
+ 记录了js内存数据中类对象的数据。
+ 相关字段描述
+
+ - file_id:文件ID
+ - node_index:类对象的索引
+ - type:类对象的类型
+ - name:类对象的名称
+ - id:类对象的唯一ID
+ - self_size:该类对象所有成员的大小(以字节为单位)
+ - edge_count:该类对象指向的类成员的个数
+ - trace_node_id:该类对象关联到js_heap_trace_node表中的调用栈ID
+ - detachedness:是否可以从window全局对象访问此节点,0表示是,1表示否
+
+ js_heap_sample表
+ 表结构
+
+
+
+ Columns Name |
+ SQL TYPE |
+
+
+
+
+ file_id |
+ INT |
+
+
+ timestamp_us |
+ INT |
+
+
+ last_assigned_id |
+ INT |
+
+
+
+ 表描述
+ 记录了timeline模式下的时间轴信息。
+ 相关字段描述
+
+ - file_id:文件ID
+ - timestamp_us:时间信息
+ - last_assigned_id:当前时间点的id
+
+ js_heap_string表
+ 表结构
+
+
+
+ Columns Name |
+ SQL TYPE |
+
+
+
+
+ file_id |
+ INT |
+
+
+ file_index |
+ INT |
+
+
+ string |
+ TEXT |
-
-
- 记录了系统中的waking和wakeup事件。
-
-
+ 表描述
+ 记录了js内存数据中的字符串。
+ 相关字段描述
- - ts:唤醒时间
- - name:唤醒事件的名称
- - ref:索引号
- - wakeup_from:唤醒当前线程的内部线程号(itid)
- - ref_type:描述了value字段的类型(一般取值为itid)
- - value:一般为当前线程的内部线程号取值
+ - file_id:文件ID
+ - file_index:索引
+ - string:对应的字符串信息
-
-
-
-
+ js_heap_trace_function_info表
+ 表结构
@@ -2380,85 +2821,101 @@
- id |
+ file_id |
INT |
- ts |
+ function_index |
INT |
- dur |
+ function_id |
INT |
- callid |
+ name |
INT |
- cat |
- TEXT |
+ script_name |
+ INT |
- name |
- TEXT |
+ script_id |
+ INT |
- depth |
+ line |
INT |
- cookie |
+ column |
INT |
+
+
+ 表描述
+ 记录了timeline模式下的调用栈的每个函数信息。
+ 相关字段描述
+
+ - file_id:文件ID
+ - function_index:函数索引
+ - function_id:函数ID
+ - name:函数名称
+ - script_name:关联到的类对象所在文件的绝对路径名称
+ - script_id:关联到的类对象所在文件的绝对路径ID
+ - line:在类对象所在的文件中的行号
+ - column:在类对象所在的文件中的列号
+
+ js_heap_trace_node表
+ 表结构
+
+
- parent_id |
- INT |
+ Columns Name |
+ SQL TYPE |
+
+
- argsetid |
+ file_id |
INT |
- chainId |
- TEXT |
+ id |
+ INT |
- spanId |
- TEXT |
+ function_info_index |
+ INT |
- parentSpanId |
- TEXT |
+ count |
+ INT |
- flag |
- TEXT |
+ size |
+ INT |
- args |
- TEXT |
+ parent_id |
+ INT |
-
-
- 记录中断相关事件。
-
-
+ 表描述
+ 记录了timeline模式下的调用栈的信息。
+ 相关字段描述
- - dur:调用中断时长
- - callid:调用中断者的ID,比如针对线程表里面的id
- - cat:调用栈数据类型(取值范围:irq,softirq...)
- - name:调用中断的名称
- - depth:中断调用的深度
- - parent_id:父调用中断的id
- - spanId:分布式调用中断关联关系
+ - file_id:文件ID
+ - id:调用栈节点索引
+ - function_info_index:函数信息索引
+ - count:调用栈个数
+ - size:调用栈大小
+ - parent_id:调用栈父节点
-
-
-
-
+ live_process表
+ 表结构
-
-
+ 表描述
记录了一些实时的进程中执行的一些数据(Monitor)。
-
-
+ 主要字段描述
- process_id:进程id
- process_name:进程名
@@ -2538,10 +2993,8 @@
- disk_writes:磁盘写量
- disk_reads:磁盘读量
-
-
-
-
+ log表
+ 表结构
-
-
+ 表描述
记录日志信息。
-
-
+ 关键字段描述
- Seq:日志序号,保证日志解析的准确性
- Ts:打印日志时间
@@ -2598,10 +3049,8 @@
- Tag:日志标签
- Context:日志内容
-
-
-
-
+ measure表
+ 表结构
-
-
+ 表描述
记录所有的计量值。
-
-
+ 关键字段描述
- type:固定字段(measure)
- ts:事件时间
@@ -2644,10 +3091,8 @@
- value:数值
- filter_id:对应filter表中的ID
-
-
-
-
+ measure_filter表
+ 表结构
-
-
+ 表描述
记录一个递增的filterid队列,所有其他的filter类型在获取过程中,均从此数据列表中获取下一个可用的filter_id并做记录。
-
-
+ 字段详细描述
过滤分类(type),过滤名称(key2),数据ID(key1)。
数据ID在process_measure_filter, sys_event_filter中作为id。
-
-
-
-
+ meta表
+ 表结构
-
-
+ 表描述
此表记录了数据解析或导出时的一些现场数据,比如使用的TraceStreamer版本,
工具的发布时间,数据解析的时间,数据的持续时长,以及原始数据的格式。
-
-
+ 主要字段描述
- Name:指定元数据的key
- Value:指定元数据的value
-
-
-
-
+ native_hook表
+ 表结构
-
-
+ 表描述
记录native_hook抓取的某个进程的堆内存,内存映射相关数据。
-
-
+ 关键字段描述
- callChainId:唯一标识一条native_hook数据
- event_type:事件类型取值范围(AllocEvent,FreeEvent,MmapEvent, MunmapEvent)
@@ -2810,10 +3245,8 @@
- current_size_dur:表示当前活跃内存总量的持续时间
- last_lib_id:函数调用栈他最后一个函数所属的文件路径,除了文件名中带musl和libc++
-
-
-
-
+ native_hook_frame表
+ 表结构
-
-
+ 表描述
记录了内存的申请和释放的堆栈。
-
-
+ 相关字段描述
- callchain_id:标识一组调用堆栈
- depth:调用栈深度
- symbol_id:函数名
- file_id:函数所属文件
-
-
-
-
+ native_hook_statistic表
+ 表结构
+
+
+
+ Columns Name |
+ SQL TYPE |
+
+
+
+
+ id |
+ INT |
+
+
+ callchain_id |
+ INT |
+
+
+ ipid |
+ INT |
+
+
+ ts |
+ INT |
+
+
+ type |
+ INT |
+
+
+ apply_count |
+ INT |
+
+
+ release_count |
+ INT |
+
+
+ apply_size |
+ INT |
+
+
+ release_size |
+ INT |
+
+
+
+ 表描述
+ 该表记录了内存申请/释放的统计信息。
+ 关键字段描述
+
+ - callchain_id:内存分配的回调链id
+ - ipid:进程id
+ - ts:统计数据上报时间
+ - type:事件类型,0代表malloc事件,1代表mmap事件
+ - apply_count:当前调用栈内存分配总次数
+ - release_count:当前调用栈内存释放总次数
+ - apply_size:当前调用栈累计分配总大小
+ - release_size:当前调用栈累计释放总大小
+
+ network表
+ 表结构
-
-
+ 表描述
记录了网络数据传输相关的信息。
-
-
+ 主要字段描述
- tv_sec:时间,秒为单位
- tv_nsec:时间,纳秒为单位
- tx_bytes:网络数据的写入量
- rx_bytes:网络数据的读取量
-
-
-
-
+ paged_memory_sample表
+ 表结构
-
-
+ 表描述
记录了网络数据传输相关的信息。
-
-
+ 主要字段描述
- callchain_id: 取值相同的一组数据,表示一个完整的调用栈
- type:事件类型
@@ -3001,10 +3485,8 @@
- size:操作页数
- itid:TS内部线程号
-
-
-
-
+ perf_callchain表
+ 表结构
-
-
+ 表描述
记录了Hiperf采样数据的调用栈信息。
-
-
+ 主要字段描述
- callchain_id:标识一组调用堆栈
- depth:调用栈深度
@@ -3056,10 +3536,8 @@
- symbol_id:与PerfFiles中的symbol_id相关联
- name:函数名
-
-
-
-
+ perf_files表
+ 表结构
-
-
+ 表描述
记录Hiperf工具采集到的函数符号表和文件名。
-
-
+ 主要字段描述
- file_id:文件编号
- serial_id:一个文件中可能有多个函数,serial_id表示函数的编号
- symbol:函数名
- path:文件路径
-
-
-
-
+ perf_report表
+ 表结构
-
-
+ 表描述
记录Hiperf工具采集数据时的配置信息。包括:抓取的事件类型,抓取数据的命令, 抓数据时指定的进程名称。
-
-
+ 主要字段描述
-
report_type:数据类型。取值只有三种类型:config_name(事件类型), workload(抓取的进程名),
@@ -3141,10 +3613,8 @@
- report_value:对应类型的取值
-
-
-
-
+ perf_sample表
+ 表结构
-
-
+ 表描述
记录Hiperf工具的采样信息。
-
-
+ 主要字段描述
- timestamp:未进行时钟源同步的时间戳
- thread_id:线程号
@@ -3207,10 +3675,8 @@
thread_state:线程状态。采样对应Sched_Waking事件时,为Runing;对应Sched_Switch事件时,为Suspend。其余事件类型,为“-”
-
-
-
-
+ perf_thread表
+ 表结构
-
-
+ 表描述
记录Hiperf工具采集到的进程和线程数据。
-
-
+ 主要字段描述
- thread_id:线程号
- process_id:进程号
- thread_name:线程名
-
-
-
-
+ process表
+ 表结构
-
-
+ 表描述
记录了进程相关数据。
-
-
+ 关键字段描述
- id:进程在数据库重新重新定义的id,从0开始序列增长
- ipid:TS内部进程id
@@ -3318,10 +3778,8 @@
- slice_count:进程内有多个线程有slice数据
- mem_count:进程是否有内存数据
-
-
-
-
+ process_filter表
+ 表结构
-
-
+ 表描述
将进程ID作为key1,进程的内存,界面刷新,屏幕亮度等信息作为key2,唯一确定一个filter_id,
filter_id同时被记录在filter表中。
-
-
+ 主要字段描述
- id:进程id
- type:固定取值:process_filter
- name:进程名
- ipid:该进程表中的id与process表中的id相关联
-
-
-
-
+ process_measure表
+ 表结构
-
-
+ 表描述
保存进程的内存,堆栈值等所有计量值信息。
-
-
+ 字段详细描述
- ts:事件时间
- value:数值
- filter_id:对应process_measure_filter表中的ID
-
-
-
-
+ process_measure_filter表
+ 表结构
-
-
+ 表描述
将进程ID作为key1,进程的内存,界面刷新,屏幕亮度等信息作为key2,唯一确定一个filter_id,
filter_id同时被记录在measure_filter表中。
-
-
+ 字段详细描述
- type:固定取值:process_measure_filter
- name:cpu状态名
- ipid:进程内部编号
-
-
-
-
+ raw表
+ 表结构
-
-
+ 表描述
记录了系统中的waking、wakup、cpu_idel、cpu_frequency数据。
-
-
+ 相关字段描述
- type:固定字段(raw)
- name:调度名称(取值:cpu_idle,sched_wakeup,sched_waking)
- cpu:事件发生在哪个CPU
- itid:时间对应哪个utid
-
-
-
-
+ sched_slice表
+ 表结构
-
-
+ 表描述
此数据结构主要作为ThreadState的上下文使用,这张表是sched_switch事件的原始记录。
-
-
+ 主要字段描述
- ts:事件发生事件
- type:固定字段(sched_slice)
@@ -3558,10 +3998,8 @@
- itid:事件对应哪个utid
- end_state:线程的终结状态
-
-
-
-
+ smaps表
+ 表结构
-
-
+ 表描述
记录进程的内存消耗的相关信息采样。
-
-
+ 主要字段描述
- id:状态持续时长
- timestamp:事件发生事件
@@ -3639,10 +4075,8 @@
- protection_id:内存段的权限id与表data_dict的id字段相关联
- path_id:如果区域是从文件映射的,则这是文件的名称对应的id序号与表data_dict的id字段相关联
-
-
-
-
+ stat表
+ 表结构
-
-
+ 表描述
此结果用来统计数据解析中各类数据的数据条数,数据和合法性,数据的匹配程度(begin-end),数据的损失等,查看此结构对应的表,可对数据源有基本的了解。
-
-
+ 主要字段描述
- event_name:数据类型
- stat_type:数据状态
@@ -3687,10 +4119,8 @@
- severity:严重级别
- source:数据来源
-
-
-
-
+ symbols表
+ 表结构
-
-
+ 表描述
此表记录了被调用函数与其地址的映射关系。
-
-
+ 相关字段描述
- funcname:系统调用名称
- adr:系统调用地址
-
-
-
-
+ syscall表
+ 表结构
-
-
+ 表描述
记录用户空间函数与内核空间函数相互调用记录。
-
-
+ 相关字段描述
- syscall_num:系统调用的序号
- type:固定取值:enter或者exit
@@ -3768,10 +4192,8 @@
- ts:时间戳
- ret:返回值,在type为exit时有效
-
-
-
-
+ sys_event_filter表
+ 表结构
-
-
+ 表描述
记录所有的filter。
-
-
+ 相关字段描述
-
-
-
-
+ sys_mem_measure表
+ 表结构
-
-
+ 表描述
记录系统内存与系统虚拟内存。
-
-
+ 相关字段描述
- ts:事件时间
- value:数值
- filter_id:对应filter表中的ID
-
-
-
-
+ thread表
+ 表结构
-
-
+ 表描述
记录了线程相关数据。
-
-
+ 字段详细描述
- id:线程在数据库重新重新定义的id,从0开始序列增长
- itid:TS内部线程id
@@ -3914,10 +4326,8 @@
- is_main_thread:是否主线程,主线程即该线程实际就是进程本身
- switch_count:当前线程的切换次数
-
-
-
-
+ thread_filter表
+ 表结构
-
-
+ 表描述
将线程ID作为key1,线程的内存,界面刷新,屏幕亮度等信息作为key2,唯一确定一个filter_id,
filter_id同时被记录在filter表中。
-
-
+ 主要字段描述
- id:线程id
- type:线程类型
- name:线程名称
- itid:该表中的tid与thread表中的tid相关联
-
-
-
-
+ thread_state表
+ 表结构
-
-
+ 表描述
记录了线程状态相关的数据。
-
-
+ 字段详细描述
- id:线程状态在数据库中的id,从0开始序列增长
- ts:该线程状态的起始时间
@@ -4027,22 +4431,27 @@
data-role="codeBlock"
data-info=""
class="fontColor light smartperf-">'R', Runnable状态
-'S', interruptible sleep
-'D', uninterruptible sleep
-'T', Stoped
-'t', Traced
-'X', ExitedDead
-'Z', ExitZombie
-'x', TaskDead
-'I', TaskDead
-'K', WakeKill
-'P', Parked
-'N', NoLoad
+"S", interruptible sleep
+"D", uninterruptible sleep
+"D-IO", uninterruptible io
+"D-NIO", uninterruptible nio
+"Runing", Runing状态
+"I", interrupted
+"T", Traced
+"X", ExitedDead
+"Z", Zombie
+"I", CloneThread
+"I", TaskKilled
+"DK",
+"DK-IO",
+"DK-NIO",
+"TK", TracedKill
+"R", WakeKill
+"P", Parked
+"R+", ForeGround
-
-
-
-
+ clock_snapshot表
+ 表结构
-
-
+ 表描述
时钟号和时间,时钟名的映射表。
-
-
+ 关键字段描述
- clock_id:时钟号
- ts:时钟快照报的时间
@@ -4080,10 +4487,8 @@
则时钟号为2 的250,转换为时钟号1的时间后,为150
-
-
-
-
+ datasource_clockid表
+ 表结构
-
-
+ 表描述
数据源和时钟号的映射表。
-
-
+ 关键字段描述
- data_source_name:数据源的名称,和数据源的插件名保持一致
-
@@ -4114,10 +4517,8 @@
这个表是用来告诉IDE,不同的事件源的事件,原始时钟号是多少,在数据库中保存的事件,通常是转换为boottime后的时间,但有些情况下,IDE仍然需要知道原始的时钟号是怎样的
-
-
-
-
+ frame_slice表
+ 表结构
-
-
+ 表描述
应用的实际渲染帧和期望渲染帧的开始时间,持续时长,以及RenderService和App之间的关联关系。
-
-
+ 关键字段描述
- callstack_id:该帧数据对应着callstack表的调用栈所在的行数
- dur:该帧渲染时长(当数据不完整时,改行数据为空)
@@ -4194,10 +4593,8 @@
- depth:预留
- frame_no:预留
-
-
-
-
+ frame_maps表
+ 表结构
-
-
+ 表描述
该表记录了app到RenderService的帧的映射关系,同frame_slice表中的src映射到dst的关系。
-
-
+ 关键字段描述
- src_row:frame_slice表中app的帧所在的行
- dst_row:frame_slice表中RenderService的帧所在的行
-
-
-
-
+ gpu_slice表
+ 表结构
-
-
+ 表描述
该表记录了每一帧数据在GPU上的渲染时长。
-
-
+ 关键字段描述
- frame_row:frame_slice表中渲染帧所在的行
- dur:帧渲染时长
-
-
-
-
+ trace_range表
+ 表结构
-
-
- 记录解析解析开始时间以及结束时间。
-
-
+ 表描述
+ 该表记录了解析开始时间以及结束时间。
+ 关键字段描述
- start_ts:trace的开始时间,纳秒为单位
- end_ts:trace的结束时间,纳秒为单位
diff --git a/ide/src/doc/md/des_tables.md b/ide/src/doc/md/des_tables.md
new file mode 100644
index 0000000000000000000000000000000000000000..4b17ec0c2f7dbb5d7d3b3aceff29be84c4940848
--- /dev/null
+++ b/ide/src/doc/md/des_tables.md
@@ -0,0 +1,1474 @@
+# TraceStreamer数据表概述
+TraceStreamer可以将trace数据源转化为易于理解和使用的数据库。用户可以通过SmartPerf界面直观的研究系统跟踪数据,也可在理解TraceStreamer生成的数据库的基础上,在TraceStreamer的交互模式或者Smartperf的数据库查询模式下,使用SQL查询语句自由组装查看用户关心的数据。下文将对TraceStreamer生成的数据库进行详细描述,给用户使用SQL查询系统跟踪数据提供帮助。
+
+## TraceStreamer输出的数据表分类
+* 常规泳道图数据表
+
+* native memory数据源相关表
+
+* perf相关数据表
+
+* hisysevent相关数据表
+
+## TraceStreamer输出数据库包含以下表格
+| 表名称 |作用|
+| ---- |---- |
+| app_name | 记录HiSysEvent事件的事件名与IDE部分事件的字段名为APPNAME中存放的相关信息的映射关系 |
+| args | 记录方法参数集合|
+| bio_latency_sample | 记录IO操作相关方法调用,及调用栈数据|
+| callstack | 记录调用堆栈和异步调用信息,其中depth,stack_id和parent_stack_id仅在非异步调用中有效。当cookid不为空时,为异步调用,此时callid为进程唯一号,否则为线程唯一号|
+| clk_event_filter | 记录时钟相关的信息|
+| clock_event_filter | 此结构用来维护时钟事件,cpu与唯一的ID做关联|
+| cpu_measure_filter | cpu事件过滤器表|
+| cpu_usage | 记录CPU使用率事件|
+| data_dict | 记录常用的字符串,将字符串和索引关联,降低程序运行的内存占用,用作辅助数据|
+| data_type | 记录数据类型和typeId的关联关系|
+| diskio | 记录磁盘读写数据事件|
+| ebpf_callstack | 记录了采样相关信息|
+| file_system_samp | 记录了调用栈的相关信息|
+| hidump | 记录FPS(Frame Per Second)数据|
+| hisys_event_measure | 记录了HiSysEvent事件相关数据,目前HiSysEvent事件包括了异常事件,IDE事件,器件状态事件 |
+| instant | 记录Sched_waking, sched_wakeup事件, 用作ThreadState表的上下文使用 |
+| irq | 记录中断相关事件|
+| js_heap_edges | 记录了js内存数据类对象对应的成员的信息|
+| js_heap_files | 记录了js内存数据的名称和时间|
+| js_heap_info | 记录了js内存数据类型,如nodes和edges的字段类型和数据总数|
+| js_heap_location | 记录了js内存location节点相关数据|
+| js_heap_nodes | 记录了js内存类对象和其成员的对应关系|
+| js_heap_sample | 记录了timeline模式下的时间轴信息|
+| js_heap_string | 记录了js内存数据中的字符串|
+| js_heap_trace_function_info | 记录了timeline模式下的调用栈的每个函数信息|
+| js_heap_trace_node | 记录了timeline模式下的调用栈信息|
+| live_process | 记录了一些实时的进程中执行的一些数据|
+| log | 记录hilog打印日志数据|
+| measure_filter | 记录一个递增的filterid队列,所有其他的filter类型在获取过程中,均从此数据列表中获取下一个可用的filter_id并做记录|
+| meta | 记录执行解析操作相关的基本信息|
+| native_hook | 记录堆内存申请与释放相关的数据|
+| native_hook_frame | 记录堆内存申请与释放相关的调用栈|
+| native_hook_statistic | 记录堆内存申请与释放相关的统计信息|
+| network | 抓取网络信息传输时产生的一些相关信息|
+| paged_memory_sample | 记录内存操作相关方法调用,及调用栈数据|
+| perf_callchain | 记录Hiperf采样数据的调用栈信息|
+| perf_files | 记录Hiperf工具采集到的函数符号表和文件名|
+| perf_report | 记录Hiperf工具采集数据时的配置信息。包括|抓取的事件类型,抓取数据的命令, 抓数据时指定的进程名称|
+| perf_sample | 记录Hiperf工具的采样信息|
+| perf_thread | 记录Hiperf工具采集到的进程和线程数据|
+| process | 记录所有的进程信息|
+| process_filter | 过滤进程|
+| process_measure | 保存进程的所有计量值|
+| process_measure_filter | 将进程ID作为key1,进程的内存,界面刷新,屏幕亮度等信息作为key2,唯一确定一个filter_id|
+| raw | 此数据结构主要作为ThreadState的上下文使用,这张表是sched_waking,sched_wakup, cpu_idle事件的原始记录|
+| sched_slice | 此数据结构主要作为ThreadState的上下文使用,这张表是sched_switch事件的原始记录|
+| smaps | 记录进程的内存消耗的相关信息采样|
+| stat | 此结果用来统计数据解析中各类数据的数据条数,数据和合法性,数据的匹配程度(begin-end),数据的损失等,查看此结构对应的表,可对数据源有基本的了解|
+| symbols | 记录系统调用名称和其函数指针的对应关系,trace中用addr来映射function_name来节省存储空间|
+| syscall | 记录用户空间函数与内核空间函数相互调用记录|
+| sys_event_filter | 记录所有的filter|
+| sys_mem_measure | 记录了所有的系统内存相关的测量信息|
+| thread | 记录所有的线程信息|
+| thread_filter | 过滤线程|
+| thread_state | 记录线程状态信息|
+| trace_range | 记录ftrace数据与其他类型数据的时间交集,供前端展示数据时使用|
+| clock_snapshot | 时钟号和时间,时钟名的映射表|
+| datasource_clockid | 数据源和时钟号的映射表|
+## 表与事件来源
+| 表名称 | 事件源 | 插件名 | 备注 |
+| ---- | ---- | ---- | ---- |
+|app_name | - |hisysevent-plugin |JSON数据源 |
+|args | - |ftrace-plugin |配合callstack使用 |
+|callstack | - |ftrace-plugin |异步或非异步的调用 |
+|cpu_measure_filter | - |ftrace-plugin |cpu跟踪器,cpu频率等 |
+|cpu_usage | - |cpu-plugin |cpu使用率 |
+|data_dict | 通用的 | - |所有字符串的记录 |
+|data_type | 通用的 | - |辅助表 |
+|file_system_callstack | - | - |ebpf文件系统 |
+|file_system_sample | - | - |ebpf文件系统 |
+|frame_maps | - |ftrace-plugin |帧渲染数据,app到RS的映射 |
+|frame_slice | - |ftrace-plugin |帧渲染数据 |
+|gpu_slice | - |ftrace-plugin |gpu渲染时长 |
+|hidump | - |hidump-plugin |FPS数据 |
+|hisys_event_measure | - |hisysevent-plugin |JSON数据源 |
+|instant | - |ftrace-plugin |waking和wakeup事件 |
+|irq | - |ftrace-plugin |记录中断事件 |
+| js_heap_edges | - |arkts-plugin | js内存数据 |
+| js_heap_files | - |arkts-plugin | js内存数据 |
+| js_heap_info | - |arkts-plugin | js内存数据 |
+| js_heap_location | - |arkts-plugin | js内存数据 |
+| js_heap_nodes | - |arkts-plugin | js内存数据 |
+| js_heap_sample | - |arkts-plugin | js内存数据 |
+| js_heap_string | - |arkts-plugin | js内存数据 |
+| js_heap_trace_function_info | - |arkts-plugin | js内存数据 |
+| js_heap_trace_node | - |arkts-plugin | js内存数据 |
+|live_process | - |process-plugin |Monitor数据 |
+|network | - |network-plugin |Monitor数据 |
+|diskio | - |diskio-plugin |Monitor数据 |
+|log | - |hilog-plugin |系统日志 |
+|measure | 通用的 | - |系统中的计量值(数值型)|
+|measure_filter | 通用的 | - |计量值的查询辅助表 |
+|meta | 通用的 | - |记录解析现场数据(解析时间,数据类型,解析工具等)|
+|native_hook | - |nativehook/hookdaemon |malloc && mmap内存数据 |
+|native_hook_frame | - |nativehook/hookdaemon |native_hook调用栈数据 |
+|native_hook_statistic | - |nativehook/hookdaemon |malloc && mmap统计数据 |
+|perf_callchain | - |perf-plugin |perf数据(非插件模式) |
+|perf_files | - | - |perf数据(非插件模式) |
+|perf_report | - | - |perf数据(非插件模式) |
+|perf_sample | - | - |perf数据(非插件模式) |
+|perf_thread | - | - |perf数据(非插件模式) |
+|process | - |ftrace-plugin |进程信息 |
+|process_filter | - |ftrace-plugin |进程计量表的辅助表 |
+|process_measure | - |ftrace-plugin |进程内存 |
+|process_measure_filter| - |ftrace-plugin |process_measure的辅助表|
+|raw | - |ftrace-plugin |线程唤醒信息 |
+|sched_slice | - |ftrace-plugin |配合现场状态表使用,dsched_switch的原始数据|
+|smaps | - |memory-plugin |进程的内存消耗 |
+|stat | 通用的 | - |记录不同种类数据的数据量|
+|symbols | - |ftrace-plugin |符号表(地址到字符串的映射)|
+|syscall | - |ftrace-plugin |系统调用 sys_enter/exit|
+|sys_event_filter | - |ftrace-plugin | |
+|sys_mem_measure | - |memory-plugin |系统内存 |
+|thread | 通用的 | - |线程信息(常用) |
+|thread_state | 通用的 |ftrace-plugin |线程调度图(常用) |
+|trace_range | 通用的 | - |trace数据的时长 |
+|thread_filter | 通用的 |ftrace-plugin |线程计量跟踪表(比较少用)|
+|clock_snapshot | 通用的 |通用的 |时钟号和时间,时钟名的映射表|
+|datasource_clockid | 通用的 |通用的 |数据源和时钟号的映射表|
+
+## ___表格关系图___
+---
+### 进程表与线程表关系
+当一个进程或者线程结束后,系统可能再次将该进程号或者线程号分配给其他进程或者线程,造成一个进程号或线程号代表多个进程或线程的情况。
+Process和Thread表中的id字段可以唯一标识进程和线程。process表中的id在其他表中用作ipid字段。thread表中的id在其他表中用作itid字段。
+thread表通过ipid字段关联process表的id字段,可以查询线程归属进程。
+
+### 查询举例
+- 已知pid = 123,查看当前进程下的所有线程信息,可以使用如下SQL语句:
+```select thread.* from thread, process where process.pid = 123 and thread.ipid = process.id```
+
+### 线程表与线程运行状态表关系图
+thread_state表记录所有线程的运行状态信息,包含ts(状态起始时间),dur(状态持续时间),cpu, itid, state(线程状态)。 thread表的id字段与thread_state表的itid字段相关联。
+
+### 查询举例
+- 已知tid = 123, 查看当前线程的所有运行状态信息,可以使用如下SQL语句:
+```select thread_state.* from thread, thread_state where thread.tid = 123 and thread.id = thread_state.itid```
+
+### 堆内存数据变化表关系图
+native_hook表记录堆内存申请(AllocEvent)和释放(FreeEvent)数据。native_hook表通过ipid和itid字段分别与process和thread表的id字段关联,通过callChainId与native_hook_frame表的callChainId字段相关联。
+native_hook表字段解释如下:
+- callChainId:唯一标识一次堆内存申请或释放, 通过与native_hook_frame表关联可以拿到当前申请或释放的函数调用堆栈。
+- addr:堆内存申请/释放的地址。
+- native_hook_size:堆内存申请/释放的大小。
+
+native_hook_frame表记录内存申请/释放的调用堆栈。通过callChainId区分一组调用堆栈,depth为堆栈深度,depth为0时,表示当前行为栈顶数据。
+
+
+native_hook_statistic表记录内存申请/释放的统计信息。通过callChainId区分一组调用堆栈。每个统计事件将记录当前事件的callChainId,并统计当前调用栈内存分配/释放的总次数和总大小。
+
+
+### 查询举例
+- 已知tid = 123,查看当前线程的所有堆内存变化信息,可以使用如下SQL语句:
+```select native_hook.* from thread, native_hook where thread.tid = 123 and thread.id = native_hook.itid```
+- 已知callchainid = 1, 查看当前内存变化调用堆栈
+```select * from native_hook_frame where callchain_id = 1```
+- 已知callchainid = 1, 查看当前内存变化调用堆栈对应的统计信息
+```select * from native_hook_statistic where callchain_id = 1```
+
+### 日志表与进程线程表关系图
+log表记录日志信息。可以根据seq字段的连续性,来判断是否存在日志丢失的情况。
+
+### 查询举例
+- 已知tid = 123,查看当前线程的所有error级别的日志,可以使用如下SQL语句:
+```select * from log where tid = 123 and level = "error"```
+
+### perf表之间关系图
+- perf_report:此表记录Hiperf工具采集数据时的配置信息。
+- perf_thread:此表记录hiperf采集到的进程和线程数据。
+- perf_sample:此表中记录Hiperf工具的采样信息。sample_id唯一表识一次采样记录,与perf_callchain表中的sample_id字段相关联。thread_id为线程号。与perf_thread表中的thread_id字段相关联。event_type_id为当前采样的事件类型id,与perf_report表中的id字段相关联。
+- perf_callchain:此表格记录的是调用栈信息。
+- Perf_files:此表格主要存放着获取到的函数符号表和文件信息。file_id唯一表识一个文件,与perf_callchain表中的file_id字段相关联。
+
+
+### 查询举例
+- 已知同步后的时间戳为28463134340470,查询采样数据
+```select * from perf_sample where timestamp_trace = 28463134340470```
+
+- 已知同步后的时间戳为28463134340470,查询采样数据对应的的调用栈信息
+```select A.* from perf_callchain as A, perf_sample as B where B.timestamp_trace = 28463134340470 and A.sample_id = B.sample_id```
+
+- 已知同步后的时间戳为28463134277762,查询采样数据的函数名及文件路径
+```select A.*, B.name, C.path from perf_sample as A, perf_callchain as B, perf_files as C where A.timestamp_trace = 28463134277762 and B.sample_id = A.sample_id and B.callchain_id = 0 and B.file_id = C.file_id and C.serial_id = 0```
+
+- 已知线程号为6700,查询所有的采样记录
+```select * from perf_sample where thread_id = 6700```
+
+- 已知进程号为7863,查询所有的采样记录
+```select A.* from perf_sample as A, perf_thread as B where B.process_id = 7863 and A.thread_id = B.thread_id```
+
+- 查询所有采样对应的事件类型
+```select A.*, B.report_value from perf_sample as A, perf_report as B where A.event_type_id = B.id```
+
+### 帧渲染表之间的关系图
+frame_slice: 记录RS(RenderService)和应用的帧渲染。
+gpu_slice: 记录RS的帧对应的gpu渲染时长。
+frame_maps:记录应用到RS的帧的映射关系。
+
+### 查询示例
+- 已知进程,查询进程对应的实际渲染帧
+```select * from frame_slice where ipid = 1```
+
+- 已知进程的实际渲染帧的dst为12,求其对应的RS进程的渲染帧
+```select * from frame_slice where id = 12 ```
+
+- 已知RS的渲染帧在frame_slice中所在行是14,求其对应的GPU渲染时长
+```select * from gpu_slice where frame_row = 14```
+
+### JS内存数据表关系图
+
+js_heap_files:记录js内存数据的文件名和文件索引
+
+
+
+js_heap_nodes:记录js内存类对象数据
+js_heap_edges:记录js内存类对象的成员数据
+js_heap_trace_node:记录timeline的调用栈信息
+js_heap_sample:记录timeline的时间轴信息
+
+## TraceStreamer输出数据库表格详细介绍
+### app_name表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|flag |INT |
+|app_name |INT |
+|app_key |INT |
+#### 表描述
+记录HiSysevent上报事件中的IDE相关事件中APPNAME的表关联信息。
+#### 字段详细描述
+- id:用于与表hisys_event_measure表中的key_id字段做对应
+- app_name:对应的事件的信息ID
+- app_key:对应的事件的APPNAME字段的信息ID
+
+### args表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|key |INT |
+|datatype |INT |
+|value |INT |
+|argset |INT |
+#### 表描述
+记录方法的参数集合。
+#### 字段详细描述
+- key:键
+- datatype:数据类型
+- value:取值
+- argset:参数集合
+
+### bio_latency_sample表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|callchain_id |INT |
+|datatype |INT |
+|type |INT |
+|ipid |INT |
+|itid |INT |
+|start_ts |INT |
+|end_ts |INT |
+|latency_dur |INT |
+|tier |INT |
+|size |INT |
+|block_number |TEXT |
+|path |TEXT |
+|dur_per_4k |INT |
+#### 表描述
+记录IO操作相关方法调用,及调用栈数据。
+#### 字段详细描述
+- callchain_id:调用栈的唯一标识。与ebpf_callstack表中Callchain_id字段关联
+- type:事件类型其取值为枚举类型(DATA_READ,DATA_WRITE,METADATA_READ,- METADATA_WRITE,PAGE_IN,PAGE_OUT)
+- ipid:TS内部进程号
+- itid:TS内部线程号
+- start_ts:开始时间
+- end_ts:结束时间
+- latency_dur:总延迟
+- tier:优先级
+- size:文件大小
+- block_number:数据量大小(一般为4K)
+- path:路径id
+- dur_per_4k:每4k数据的平均延迟
+
+### callstack表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|ts |INT |
+|dur |INT |
+|callid |INT |
+|cat |TEXT |
+|identify |INT |
+|name |TEXT |
+|depth |INT |
+|cookie |INT |
+|parent_id |INT |
+|argsetid |INT |
+|chainId |TEXT |
+|spanId |TEXT |
+|parentSpanId |TEXT |
+|flag |TEXT |
+|args |TEXT |
+#### 表描述
+记录调用堆栈和异步调用信息,其中depth,stack_id和parent_stack_id仅在非异步的调用中有效。当cookid不为空时,为异步调用,此时callid为进程唯一号,否则为线程唯一号。
+#### 字段详细描述
+- dur:调用时长
+- callid:调用者的ID,比如针对线程表里面的id
+- identify:调用栈的名字,与表dataDict相关联能够取出其string值
+- name:调用名称
+- depth:调用深度
+- parent_id:父调用的id
+- spanId:分布式调用关联关系
+- flag:C表示分布式调用发送方,S表示接受方
+- args:分布式调用函数参数
+
+### clk_event_filter表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|type |TEXT |
+|name |TEXT |
+|cpu |INT |
+#### 表描述
+记录时钟信息。
+#### 字段详细描述
+- Type:时钟事件类型
+- Name:时钟事件名称
+
+### clock_event_filter表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|type |TEXT |
+|name |TEXT |
+|cpu |INT |
+#### 表描述
+此结构用来维护时钟事件,cpu与唯一的ID做关联。
+#### 主要字段描述
+- Type:时钟事件类型
+- Name:时钟事件名称
+
+### cpu_measure_filter表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|type |TEXT |
+|name |TEXT |
+|cpu |INT |
+#### 表描述
+将cpu号作为key1,cpu的频率,空闲等状态作为key2,唯一确定一个filter_id。
+#### 主要字段描述
+- Id(filterid), cpu:事件名称,cpu号
+
+### cpu_usage表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|ts |INT |
+|dur |INT |
+|total_load |REAL |
+|user_load |REAL |
+|system_load |REAL |
+|process_num |INT |
+#### 表描述
+记录了与CPU使用率相关的数据。
+#### 主要字段描述
+- total_load:总负荷
+- user_load:用户负载
+- system_load:系统负载
+- process_num:线程数
+
+### data_dict表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|data |TEXT |
+#### 表描述
+此表记录了一个数据类型ID和字符串的映射。
+#### 主要字段描述
+- id:索引值
+- data:字符串
+
+### data_type表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|typeId |INT |
+|desc |TEXT |
+#### 表描述
+此表记录了一个数据类型ID和数据描述的映射。
+#### 主要字段描述
+- typeId::数据类型id
+- Desc:数据类型描述
+
+### diskio表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|ts |INT |
+|dur |INT |
+|rd |INT |
+|wr |INT |
+|rd_speed |REAL |
+|wr_speed |REAL |
+|rd_count |INT |
+|wr_count |INT |
+|rd_count_speed |REAL |
+|wr_count_speed |REAL |
+#### 表描述
+记录了与磁盘读写相关的数据。
+#### 主要字段描述
+- rd_sectors_kb:读数据的速度
+- wr_sectors_kb:写入数据的速度
+- ts:时间戳
+
+### ebpf_callstack表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|callchain_id |INT |
+|depth |TEXT |
+|ip |TEXT |
+|symbols_id |INT |
+|file_path_id |INT |
+#### 表描述
+记录了与磁盘读写相关的数据。
+#### 主要字段描述
+- callchain_id:调用栈的唯一标识。与ebpf_callstack表中Callchain_id字段关联
+- depth:调用栈深度。取值为零时表示栈顶
+- ip:调用栈ip
+- symbols_id:调用栈函数名称, 与data_dict中的id字段关联
+- file_path_id:调用栈函数所属文件路径, 与data_dict中的id字段关联
+
+### file_system_sample表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|callchain_id |INT |
+|type |INT |
+|ipid |INT |
+|itid |INT |
+|start_ts |INT |
+|end_ts |INT |
+|dur |INT |
+|return_value |TEXT |
+|error_code |TEXT |
+|fd |INT |
+|file_id |INT |
+|size |INT |
+|first_argument |TEXT |
+|second_argument |TEXT |
+|third_argument |TEXT |
+|fourth_argument |TEXT |
+#### 表描述
+记录了调用栈的相关信息。
+#### 主要字段描述
+- callchain_id:调用栈信息ID与file_system_callstack表中call_chain_id字段相关联
+- type:对应文件操作open,close,read,write
+- ipid:线程所属的进程ID
+- start_ts:开始时间
+- end_ts:结束时间
+- dur:耗时
+- return_value:文件操作的返回值
+- error_code:文件操作发生错误时的错误码
+- fd:文件描述符fd
+- file_id:当type为open,close时为其操作的文件路径,当type为read,write时为固定字段(null)
+- size:在type为read,write时对应的文件的读或者写的大小
+- first_argument:参数一
+- second_argument:参数二
+- third_argument:参数三
+- fourth_argument:参数四
+
+### hidump表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|ts |INT |
+|fps |INT |
+#### 表描述
+此表记录了设备的帧率信息,fps。
+#### 相关字段描述
+- fps:帧率值
+
+### hisys_event_measure表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|serial |INT |
+|ts |INT |
+|name_id |INT |
+|key_id |INT |
+|type |INT |
+|int_value |REAL |
+|string_value |TEXT |
+#### 表描述
+记录所有的system event事件的相关数据,及其相关表的映射信息。
+#### 相关字段描述
+- serial:每条数据过来携带唯一一条id作为标识
+- name_id:存放事件对应的ID,与data_dict表相关联可以取出对应的字段
+- key_id:存放事件包含的字段的ID,与表app_name的id字段相关联,找到app_name表的 id字段对应行的app_key字段与表data_dict表相关联取出对应的字段
+- type:存放事件所包含的字段的值所属的类型为int型还是string(0为int,1为string)
+- int_value:存放本事件所包含的字段的int型的值
+- string_value:存放本事件所包含的字段的string型的值
+
+### instant表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|ts |INT |
+|name |TEXT |
+|ref |INT |
+|wakeup_from |INT |
+|ref_type |TEXT |
+|value |REAL |
+#### 表描述
+记录了系统中的waking和wakeup事件。
+#### 字段描述
+- ts:唤醒时间
+- name:唤醒事件的名称
+- ref:索引号
+- wakeup_from:唤醒当前线程的内部线程号(itid)
+- ref_type:描述了value字段的类型(一般取值为itid)
+- value:一般为当前线程的内部线程号取值
+
+### irq表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|ts |INT |
+|dur |INT |
+|callid |INT |
+|cat |TEXT |
+|name |TEXT |
+|depth |INT |
+|cookie |INT |
+|parent_id |INT |
+|argsetid |INT |
+|chainId |TEXT |
+|spanId |TEXT |
+|parentSpanId |TEXT |
+|flag |TEXT |
+|args |TEXT |
+#### 表描述
+记录中断相关事件。
+#### 相关字段描述
+- dur:调用中断时长
+- callid:调用中断者的ID,比如针对线程表里面的id
+- cat:调用栈数据类型(取值范围:irq,softirq...)
+- name:调用中断的名称
+- depth:中断调用的深度
+- parent_id:父调用中断的id
+- spanId:分布式调用中断关联关系
+
+### js_heap_edges表
+#### 表结构
+| Columns Name | SQL TYPE |
+| ------------- | -------- |
+| file_id | INT |
+| edge_index | INT |
+| type | INT |
+| name_or_index | INT |
+| to_node | INT |
+| from_node_id | INT |
+| to_node_id | INT |
+#### 表描述
+记录js内存数据类对象对应的成员的信息。
+#### 相关字段描述
+- file_id:文件ID
+- edge_index:成员的索引号
+- type:成员的类型,取值范围为js_heap_info表中的edge_types
+- name_or_index:数据名称,取值为js_heap_string表中的下标索引
+- to_node:此成员指向的类对象在nodes数组中的索引
+- from_node_id:类对象ID,该类对象指向此成员数据
+- to_node_id:此成员指向到的类对象nodes数组中的ID
+
+### js_heap_files表
+#### 表结构
+| Columns Name | SQL TYPE |
+| ------------ | -------- |
+| id | INT |
+| file_name | TEXT |
+| start_time | INT |
+| end_time | INT |
+| pid | INT |
+#### 表描述
+记录了js内存数据的文件名称和时间。
+#### 相关字段描述
+- id:文件ID
+- file_name:文件名称
+- start_time:数据抓取的起始时间
+- end_time:数据抓取的终止时间
+- pid:进程号
+
+### js_heap_info表
+#### 表结构
+| Columns Name | SQL TYPE |
+| ------------ | -------- |
+| file_id | INT |
+| key | TEXT |
+| type | INT |
+| int_value | INT |
+| str_value | TEXT |
+#### 表描述
+记录了js内存数据类型,如nodes和edges的字段类型和数据总数。
+#### 相关字段描述
+- file_id:文件ID
+- key:类型名称
+- type:数据类型索引
+- int_value:int类型的数据值,如count类型数据
+- str_value:string类型的数据值,如typename
+
+### js_heap_location表
+#### 表结构
+| Columns Name | SQL TYPE |
+| ------------ | -------- |
+| file_id | INT |
+| object_index | INT |
+| script_id | INT |
+| line | INT |
+| column | INT |
+#### 表描述
+记录了js内存location节点相关数据,此表目前无抓取到的数据。
+#### 相关字段描述
+- file_id:文件ID
+- object_index:与location关联的类对象的索引,取值为js_heap_nodes的下标索引
+- script_id:关联到的类对象所在文件的绝对路径ID
+- line:在类对象所在的文件中的行号
+- column:在类对象所在的文件中的列号
+
+### js_heap_nodes表
+#### 表结构
+| Columns Name | SQL TYPE |
+| ------------- | -------- |
+| file_id | INT |
+| node_index | TEXT |
+| type | INT |
+| name | INT |
+| id | TEXT |
+| self_size | INT |
+| edge_count | INT |
+| trace_node_id | INT |
+| detachedness | INT |
+#### 表描述
+记录了js内存数据中类对象的数据。
+#### 相关字段描述
+- file_id:文件ID
+- node_index:类对象的索引
+- type:类对象的类型
+- name:类对象的名称
+- id:类对象的唯一ID
+- self_size:该类对象所有成员的大小(以字节为单位)
+- edge_count:该类对象指向的类成员的个数
+- trace_node_id:该类对象关联到js_heap_trace_node表中的调用栈ID
+- detachedness:是否可以从window全局对象访问此节点,0表示是,1表示否
+
+### js_heap_sample表
+#### 表结构
+| Columns Name | SQL TYPE |
+| ---------------- | -------- |
+| file_id | INT |
+| timestamp_us | INT |
+| last_assigned_id | INT |
+#### 表描述
+记录了timeline模式下的时间轴信息。
+#### 相关字段描述
+- file_id:文件ID
+- timestamp_us:时间信息
+- last_assigned_id:当前时间点的id
+
+### js_heap_string表
+#### 表结构
+| Columns Name | SQL TYPE |
+| ------------ | -------- |
+| file_id | INT |
+| file_index | INT |
+| string | TEXT |
+#### 表描述
+记录了js内存数据中的字符串。
+#### 相关字段描述
+- file_id:文件ID
+- file_index:索引
+- string:对应的字符串信息
+
+### js_heap_trace_function_info表
+#### 表结构
+| Columns Name | SQL TYPE |
+| -------------- | -------- |
+| file_id | INT |
+| function_index | INT |
+| function_id | INT |
+| name | INT |
+| script_name | INT |
+| script_id | INT |
+| line | INT |
+| column | INT |
+#### 表描述
+记录了timeline模式下的调用栈的每个函数信息。
+#### 相关字段描述
+- file_id:文件ID
+- function_index:函数索引
+- function_id:函数ID
+- name:函数名称
+- script_name:关联到的类对象所在文件的绝对路径名称
+- script_id:关联到的类对象所在文件的绝对路径ID
+- line:在类对象所在的文件中的行号
+- column:在类对象所在的文件中的列号
+
+### js_heap_trace_node表
+#### 表结构
+| Columns Name | SQL TYPE |
+| ------------------- | -------- |
+| file_id | INT |
+| id | INT |
+| function_info_index | INT |
+| count | INT |
+| size | INT |
+| parent_id | INT |
+#### 表描述
+记录了timeline模式下的调用栈的信息。
+#### 相关字段描述
+- file_id:文件ID
+- id:调用栈节点索引
+- function_info_index:函数信息索引
+- count:调用栈个数
+- size:调用栈大小
+- parent_id:调用栈父节点
+
+### live_process表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|ts |INT |
+|dur |INT |
+|cpu_time |INT |
+|process_id |INT |
+|process_name |TEXT |
+|parent_process_id |INT |
+|uid |INT |
+|user_name |TEXT |
+|cpu_usage |REAL |
+|pss_info |INT |
+|thread_num |INT |
+|disk_writes |INT |
+|disk_reads |INT |
+#### 表描述
+记录了一些实时的进程中执行的一些数据(Monitor)。
+#### 主要字段描述
+- process_id:进程id
+- process_name:进程名
+- parent_process_id:父进程的id
+- uid:用户id
+- user_name:用户名
+- cpu_usage:cpu使用率
+- pss_info:进程信息
+- thread_num:线程数量
+- disk_writes:磁盘写量
+- disk_reads:磁盘读量
+
+### log表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|seq |INT |
+|ts |INT |
+|pid |INT |
+|tid |INT |
+|level |TEXT |
+|tag |TEXT |
+|context |TEXT |
+|origints |INT |
+#### 表描述
+记录日志信息。
+#### 关键字段描述
+- Seq:日志序号,保证日志解析的准确性
+- Ts:打印日志时间
+- Pid:日志的进程号
+- Tid:日志的线程号
+- Level:日志级别
+- Tag:日志标签
+- Context:日志内容
+
+### measure表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|type |TEXT |
+|ts |INT |
+|dur |INT |
+|value |INT |
+|filter_id |INT |
+#### 表描述
+记录所有的计量值。
+#### 关键字段描述
+- type:固定字段(measure)
+- ts:事件时间
+- dur:该值持续的时长
+- value:数值
+- filter_id:对应filter表中的ID
+
+### measure_filter表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|type |TEXT |
+|name |TEXT |
+|source_arg_set_id |INT |
+#### 表描述
+记录一个递增的filterid队列,所有其他的filter类型在获取过程中,均从此数据列表中获取下一个可用的filter_id并做记录。
+#### 字段详细描述
+过滤分类(type),过滤名称(key2),数据ID(key1)。
+数据ID在process_measure_filter, sys_event_filter中作为id。
+
+### meta表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|name |TEXT |
+|value |TEXT |
+#### 表描述
+此表记录了数据解析或导出时的一些现场数据,比如使用的TraceStreamer版本, 工具的发布时间,数据解析的时间,数据的持续时长,以及原始数据的格式。
+#### 主要字段描述
+- Name:指定元数据的key
+- Value:指定元数据的value
+
+### native_hook表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|callChainId |INT |
+|ipid |INT |
+|itid |INT |
+|event_type |TEXT |
+|sub_type_id |NUM |
+|start_ts |INT |
+|end_ts |INT |
+|dur |INT |
+|addr |INT |
+|heap_size |INT |
+|all_heap_size |INT |
+|current_size_dur |INT |
+|last_lib_id |INT |
+#### 表描述
+记录native_hook抓取的某个进程的堆内存,内存映射相关数据。
+#### 关键字段描述
+- callChainId:唯一标识一条native_hook数据
+- event_type:事件类型取值范围(AllocEvent,FreeEvent,MmapEvent, MunmapEvent)
+- sub_type_id:子事件类型(只有sub_type字段为MmapEvent时,该字段才会有值)
+- start_ts:申请内存开始时间
+- end_ts:释放内存时间
+- Dur:申请内存活跃时间
+- Addr:申请内存地址
+- mem_size:申请或释放内存大小
+- all_mem_size:从采集数据开始到当前时刻,申请并活跃的内存总量。 event_type为AllocEvent或者FreeEvent时,表示活跃的堆内存总量。当event_type为MmapEvent或者MunmapEvent时,表示活跃的映射内存总量
+- current_size_dur:表示当前活跃内存总量的持续时间
+- last_lib_id:函数调用栈他最后一个函数所属的文件路径,除了文件名中带musl和libc++
+
+### native_hook_frame表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|callchain_id |INT |
+|depth |INT |
+|symbol_id |INT |
+|file_id |INT |
+|offset |INT |
+|symbol_offset |INT |
+#### 表描述
+记录了内存的申请和释放的堆栈。
+#### 相关字段描述
+- callchain_id:标识一组调用堆栈
+- depth:调用栈深度
+- symbol_id:函数名
+- file_id:函数所属文件
+
+### native_hook_statistic表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|callchain_id |INT |
+|ipid |INT |
+|ts |INT |
+|type |INT |
+|apply_count |INT |
+|release_count |INT |
+|apply_size |INT |
+|release_size |INT |
+
+#### 表描述
+该表记录了内存申请/释放的统计信息。
+#### 关键字段描述
+- callchain_id:内存分配的回调链id
+- ipid:进程id
+- ts:统计数据上报时间
+- type:事件类型,0代表malloc事件,1代表mmap事件
+- apply_count:当前调用栈内存分配总次数
+- release_count:当前调用栈内存释放总次数
+- apply_size:当前调用栈累计分配总大小
+- release_size:当前调用栈累计释放总大小
+
+### network表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|ts |INT |
+|dur |INT |
+|tx |INT |
+|rx |INT |
+|tx_speed |REAL |
+|rx_speed |REAL |
+|packet_in |INT |
+|packet_in_sec |REAL |
+|packet_out |INT |
+|packet_out_sec |REAL |
+|net_type |TEXT |
+#### 表描述
+记录了网络数据传输相关的信息。
+#### 主要字段描述
+- tv_sec:时间,秒为单位
+- tv_nsec:时间,纳秒为单位
+- tx_bytes:网络数据的写入量
+- rx_bytes:网络数据的读取量
+
+### paged_memory_sample表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|callchain_id |INT |
+|type |INT |
+|ipid |INT |
+|start_ts |INT |
+|end_ts |INT |
+|dur |INT |
+|size |INT |
+|addr |TEXT |
+|itid |INT |
+#### 表描述
+记录了网络数据传输相关的信息。
+#### 主要字段描述
+- callchain_id: 取值相同的一组数据,表示一个完整的调用栈
+- type:事件类型
+- ipid:TS内部进程号
+- start_ts:开始时间
+- end_ts:结束时间
+- dur:持续时间
+- size:操作页数
+- itid:TS内部线程号
+
+### perf_callchain表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|callchain_id |INT |
+|depth |INT |
+|vaddr_in_file |INT |
+|file_id |INT |
+|symbol_id |INT |
+|name |TEXT |
+#### 表描述
+记录了Hiperf采样数据的调用栈信息。
+#### 主要字段描述
+- callchain_id:标识一组调用堆栈
+- depth:调用栈深度
+- vaddr_in_file:函数在文件中的虚拟地址
+- file_id:与PerfFiles中的file_id字段相关联
+- symbol_id:与PerfFiles中的symbol_id相关联
+- name:函数名
+
+### perf_files表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|file_id |INT |
+|serial_id |INT |
+|symbol |TEXT |
+|path |TEXT |
+#### 表描述
+记录Hiperf工具采集到的函数符号表和文件名。
+#### 主要字段描述
+- file_id:文件编号
+- serial_id:一个文件中可能有多个函数,serial_id表示函数的编号
+- symbol:函数名
+- path:文件路径
+
+### perf_report表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|report_type |TEXT |
+|report_value |TEXT |
+#### 表描述
+记录Hiperf工具采集数据时的配置信息。包括:抓取的事件类型,抓取数据的命令, 抓数据时指定的进程名称。
+#### 主要字段描述
+- report_type:数据类型。取值只有三种类型:config_name(事件类型), workload(抓取的进程名), cmdline(抓取命令)
+- report_value:对应类型的取值
+
+### perf_sample表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|callchain_id |INT |
+|timestamp |INT |
+|thread_id |INT |
+|event_count |INT |
+|event_type_id |INT |
+|timestamp_trace |INT |
+|cpu_id |INT |
+|thread_state |TEXT |
+#### 表描述
+记录Hiperf工具的采样信息。
+#### 主要字段描述
+- timestamp:未进行时钟源同步的时间戳
+- thread_id:线程号
+- event_count:采样统计
+- event_type_id:事件类型编号。与PerfReport表的id字段相关联
+- timestamp_trace:时钟源同步后的时间戳
+- cpu_id:cpu核编号
+- thread_state:线程状态。采样对应Sched_Waking事件时,为Runing;对应Sched_Switch事件时,为Suspend。其余事件类型,为“-”
+
+### perf_thread表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|thread_id |INT |
+|process_id |INT |
+|thread_name |TEXT |
+#### 表描述
+记录Hiperf工具采集到的进程和线程数据。
+#### 主要字段描述
+- thread_id:线程号
+- process_id:进程号
+- thread_name:线程名
+
+### process表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|ipid |INT |
+|type |TEXT |
+|pid |INT |
+|name |TEXT |
+|start_ts |INT |
+|switch_count |INT |
+|thread_count |INT |
+|slice_count |INT |
+|mem_count |INT |
+#### 表描述
+记录了进程相关数据。
+#### 关键字段描述
+- id:进程在数据库重新重新定义的id,从0开始序列增长
+- ipid:TS内部进程id
+- type:固定取值:process
+- pid:进程的真实id
+- name:进程名字
+- start_ts:开始时间
+- switch_count:统计内部有多少个线程有切换
+- thread_count:统计其线程个数
+- slice_count:进程内有多个线程有slice数据
+- mem_count:进程是否有内存数据
+
+### process_filter表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|type |TEXT |
+|name |TEXT |
+|ipid |INT |
+#### 表描述
+将进程ID作为key1,进程的内存,界面刷新,屏幕亮度等信息作为key2,唯一确定一个filter_id, filter_id同时被记录在filter表中。
+#### 主要字段描述
+- id:进程id
+- type:固定取值:process_filter
+- name:进程名
+- ipid:该进程表中的id与process表中的id相关联
+
+### process_measure表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|type |TEXT |
+|ts |INT |
+|value |NUM |
+|filter_id |INT |
+#### 表描述
+保存进程的内存,堆栈值等所有计量值信息。
+#### 字段详细描述
+- ts:事件时间
+- value:数值
+- filter_id:对应process_measure_filter表中的ID
+
+### process_measure_filter表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|type |TEXT |
+|name |TEXT |
+|ipid |INT |
+#### 表描述
+将进程ID作为key1,进程的内存,界面刷新,屏幕亮度等信息作为key2,唯一确定一个filter_id, filter_id同时被记录在measure_filter表中。
+#### 字段详细描述
+- type:固定取值:process_measure_filter
+- name:cpu状态名
+- ipid:进程内部编号
+
+### raw表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|type |TEXT |
+|ts |INT |
+|name |TEXT |
+|cpu |INT |
+|itid |INT |
+#### 表描述
+记录了系统中的waking、wakup、cpu_idel、cpu_frequency数据。
+#### 相关字段描述
+- type:固定字段(raw)
+- name:调度名称(取值:cpu_idle,sched_wakeup,sched_waking)
+- cpu:事件发生在哪个CPU
+- itid:时间对应哪个utid
+
+### sched_slice表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|type |TEXT |
+|ts |INT |
+|dur |INT |
+|ts_end |INT |
+|cpu |INT |
+|itid |INT |
+|end_state |TEXT |
+|priority |INT |
+#### 表描述
+此数据结构主要作为ThreadState的上下文使用,这张表是sched_switch事件的原始记录。
+#### 主要字段描述
+- ts:事件发生事件
+- type:固定字段(sched_slice)
+- dur:状态持续时长
+- ts_end:状态结束时长
+- cpu:事件发生在哪个cpu
+- itid:事件对应哪个utid
+- end_state:线程的终结状态
+
+### smaps表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|timestamp |INT |
+|start_addr |TEXT |
+|end_addr |TEXT |
+|dirty |INT |
+|swapper |INT |
+|resident_size |INT |
+|pss |INT |
+|virtaul_size |INT |
+|reside |REAL |
+|protection_id |INT |
+|path_id |INT |
+#### 表描述
+记录进程的内存消耗的相关信息采样。
+#### 主要字段描述
+- id:状态持续时长
+- timestamp:事件发生事件
+- start_addr:内存段地址的起始位置
+- end_addr:内存段地址的结束位置
+- dirty:其他进程共享的被写的页的大小 + 已被改写的私有页面的大小
+- swapper:存在于交换分区的数据大小
+- resident_size:实际分配的内存大小
+- pss:平摊计算后的实际物理使用内存
+- virtaul_size:虚拟内存空间的大小
+- reside:实际分配的内存大小与虚拟内存空间的大小的比
+- protection_id:内存段的权限id与表data_dict的id字段相关联
+- path_id:如果区域是从文件映射的,则这是文件的名称对应的id序号与表data_dict的id字段相关联
+
+### stat表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|event_name |TEXT |
+|stat_type |TEXT |
+|count |INT |
+|serverity |TEXT |
+|source |TEXT |
+#### 表描述
+此结果用来统计数据解析中各类数据的数据条数,数据和合法性,数据的匹配程度(begin-end),数据的损失等,查看此结构对应的表,可对数据源有基本的了解。
+#### 主要字段描述
+- event_name:数据类型
+- stat_type:数据状态
+- count:数据条数
+- severity:严重级别
+- source:数据来源
+
+### symbols表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|funcname |TEXT |
+|addr |INT |
+#### 表描述
+此表记录了被调用函数与其地址的映射关系。
+#### 相关字段描述
+- funcname:系统调用名称
+- adr:系统调用地址
+
+### syscall表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|syscall_num |INT |
+|type |TEXT |
+|ipid |INT |
+|ts |INT |
+|ret |INT |
+#### 表描述
+记录用户空间函数与内核空间函数相互调用记录。
+#### 相关字段描述
+- syscall_num:系统调用的序号
+- type:固定取值:enter或者exit
+- ipid:线程所属的进程ID
+- ts:时间戳
+- ret:返回值,在type为exit时有效
+
+### sys_event_filter表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|type |TEXT |
+|name |TEXT |
+#### 表描述
+记录所有的filter。
+#### 相关字段描述
+- type:文件类型
+- name:文件名
+
+### sys_mem_measure表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|type |TEXT |
+|ts |INT |
+|value |INT |
+|filter_id |INT |
+#### 表描述
+记录系统内存与系统虚拟内存。
+#### 相关字段描述
+- ts:事件时间
+- value:数值
+- filter_id:对应filter表中的ID
+
+### thread表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|itid |INT |
+|type |TEXT |
+|tid |INT |
+|name |TEXT |
+|start_ts |INT |
+|end_ts |INT |
+|ipid |INT |
+|is_main_thread|INT |
+|switch_count |INT |
+#### 表描述
+记录了线程相关数据。
+#### 字段详细描述
+- id:线程在数据库重新重新定义的id,从0开始序列增长
+- itid:TS内部线程id
+- type:固定字段(thread)
+- tid:线程号
+- name:线程名
+- start_ts:开始时间
+- end_ts:结束时间
+- ipid:线程所属的进程id, 关联process表中的ID
+- is_main_thread:是否主线程,主线程即该线程实际就是进程本身
+- switch_count:当前线程的切换次数
+
+### thread_filter表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|type |TEXT |
+|name |TEXT |
+|itid |INT |
+#### 表描述
+将线程ID作为key1,线程的内存,界面刷新,屏幕亮度等信息作为key2,唯一确定一个filter_id, filter_id同时被记录在filter表中。
+#### 主要字段描述
+- id:线程id
+- type:线程类型
+- name:线程名称
+- itid:该表中的tid与thread表中的tid相关联
+
+### thread_state表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|id |INT |
+|type |TEXT |
+|ts |INT |
+|dur |INT |
+|cpu |INT |
+|itid |INT |
+|tid |INT |
+|pid |INT |
+|state |TEXT |
+#### 表描述
+记录了线程状态相关的数据。
+#### 字段详细描述
+- id:线程状态在数据库中的id,从0开始序列增长
+- ts:该线程状态的起始时间
+- dur:该线程状态的持续时间
+- cpu:该线程在哪个cpu上执行(针对running状态的线程)
+- itid:该状态所属的线程id, 关联线程表中的id
+- tid:线程号
+- pid:进程号
+- state:线程实际的的状态值
+```
+'R', Runnable状态
+"S", interruptible sleep
+"D", uninterruptible sleep
+"D-IO", uninterruptible io
+"D-NIO", uninterruptible nio
+"Runing", Runing状态
+"I", interrupted
+"T", Traced
+"X", ExitedDead
+"Z", Zombie
+"I", CloneThread
+"I", TaskKilled
+"DK",
+"DK-IO",
+"DK-NIO",
+"TK", TracedKill
+"R", WakeKill
+"P", Parked
+"R+", ForeGround
+```
+
+### clock_snapshot表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|clock_id |INT |
+|ts |INT |
+|clock_name |TEXT |
+#### 表描述
+时钟号和时间,时钟名的映射表。
+#### 关键字段描述
+- clock_id:时钟号
+- ts:时钟快照报的时间
+- clock_name:时钟号对应的时钟名字
+时钟快照是用来对齐不同时钟号的时间
+比如,时钟号1的时间100,和时钟号2的时间200对齐
+则时钟号为2 的250,转换为时钟号1的时间后,为150
+
+### datasource_clockid表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|data_source_name |TEXT |
+|clock_id |INT |
+#### 表描述
+数据源和时钟号的映射表。
+#### 关键字段描述
+- data_source_name:数据源的名称,和数据源的插件名保持一致
+- clock_id:时钟号,对应clock_snapshot中的时钟号
+这个表是用来告诉IDE,不同的事件源的事件,原始时钟号是多少,在数据库中保存的事件,通常是转换为boottime后的时间,但有些情况下,IDE仍然需要知道原始的时钟号是怎样的
+### frame_slice表
+### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|ts |INT |
+|vsync |INT |
+|ipid |INT |
+|itid |INT |
+|callstack_id |INT |
+|dur |INT |
+|src |TEXT |
+|dst |INT |
+|type |INT |
+|flag |INT |
+|depth |INT |
+|frame_no |INT|
+#### 表描述
+应用的实际渲染帧和期望渲染帧的开始时间,持续时长,以及RenderService和App之间的关联关系。
+#### 关键字段描述
+- callstack_id:该帧数据对应着callstack表的调用栈所在的行数
+- dur:该帧渲染时长(当数据不完整时,改行数据为空)
+- src:该帧是被哪一帧(该表中对应的行数)触发的,有多个值时,用逗号分割
+- dst:该帧对应的渲染帧是哪一行
+- type: 0 说明该行数据是实际渲染帧, 1 说明该行数据是期望渲染帧
+- flag: 空时,为不完整的数据;0 表示实际渲染帧不卡帧, 1 表示实际渲染帧卡帧, 2 表示数据不需要绘制(没有frameNum信息)
+- depth:预留
+- frame_no:预留
+### frame_maps表
+### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|ts |INT |
+|src_row |INT |
+|dst_row |INT |
+#### 表描述
+该表记录了app到RenderService的帧的映射关系,同frame_slice表中的src映射到dst的关系。
+#### 关键字段描述
+- src_row:frame_slice表中app的帧所在的行
+- dst_row:frame_slice表中RenderService的帧所在的行
+### gpu_slice表
+### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|frame_row |INT |
+|dur |INT |
+#### 表描述
+该表记录了每一帧数据在GPU上的渲染时长。
+#### 关键字段描述
+- frame_row:frame_slice表中渲染帧所在的行
+- dur:帧渲染时长
+### trace_range表
+#### 表结构
+| Columns Name | SQL TYPE |
+|---- |---- |
+|start_ts |INT |
+|end_ts |INT |
+#### 表描述
+该表记录了解析开始时间以及结束时间。
+#### 关键字段描述
+- start_ts:trace的开始时间,纳秒为单位
+- end_ts:trace的结束时间,纳秒为单位
\ No newline at end of file
diff --git a/ide/src/figures/traceStreamer/js_heap_files.png b/ide/src/figures/traceStreamer/js_heap_files.png
new file mode 100644
index 0000000000000000000000000000000000000000..8f50acb397072e022d1cbb4663dfbf33a8912a6a
Binary files /dev/null and b/ide/src/figures/traceStreamer/js_heap_files.png differ
diff --git a/ide/src/figures/traceStreamer/js_heap_nodes.png b/ide/src/figures/traceStreamer/js_heap_nodes.png
new file mode 100644
index 0000000000000000000000000000000000000000..9111a357521303e2f6fa6cb3438c67a3dd839dd8
Binary files /dev/null and b/ide/src/figures/traceStreamer/js_heap_nodes.png differ
diff --git a/ide/src/trace/bean/BoxSelection.ts b/ide/src/trace/bean/BoxSelection.ts
index 080ba368b065bf53cf336ebe2da99b63b50ad43e..d97a448df8868bc6c69252aa44b78c12a5f1623c 100644
--- a/ide/src/trace/bean/BoxSelection.ts
+++ b/ide/src/trace/bean/BoxSelection.ts
@@ -32,6 +32,8 @@ export class SelectionParam {
fsCount: number = 0;
vmCount: number = 0;
isCurrentPane: boolean = false;
+ startup: boolean = false;
+ staticInit: boolean = false;
cpus: Array = [];
cpuStateFilterIds: Array = [];
diff --git a/ide/src/trace/component/SpSystemTrace.ts b/ide/src/trace/component/SpSystemTrace.ts
index 5a7cd590f37075d4d798ed978a119804e9d4c760..db1dd58dff7cc7754b1317eb8518285d058d3134 100644
--- a/ide/src/trace/component/SpSystemTrace.ts
+++ b/ide/src/trace/component/SpSystemTrace.ts
@@ -78,6 +78,8 @@ import { SpJsMemoryChart } from './chart/SpJsMemoryChart.js';
import { TraceRowConfig } from './trace/base/TraceRowConfig.js';
import { HeapTimelineStruct } from '../database/ui-worker/ProcedureWorkerHeapTimeline.js';
import { TabPaneCurrentSelection } from './trace/sheet/TabPaneCurrentSelection.js';
+import { AppStartupStruct } from '../database/ui-worker/ProcedureWorkerAppStartup.js';
+import { SoStruct } from '../database/ui-worker/ProcedureWorkerSoInit.js';
function dpr() {
return window.devicePixelRatio || 1;
@@ -452,6 +454,12 @@ export class SpSystemTrace extends BaseElement {
selection.cpuFreqLimitDatas.push(it.dataList!);
} else if (it.rowType == TraceRow.ROW_TYPE_PROCESS) {
this.pushPidToSelection(selection, it.rowId!);
+ if (it.getAttribute('hasStartup') === 'true') {
+ selection.startup = true;
+ }
+ if (it.getAttribute('hasStaticInit') === 'true') {
+ selection.staticInit = true;
+ }
let processChildRows: Array> = [
...this.shadowRoot!.querySelectorAll>(`trace-row[row-parent-id='${it.rowId}']`),
];
@@ -495,6 +503,14 @@ export class SpSystemTrace extends BaseElement {
}
});
info('load nativeMemory traceRow id is : ', it.rowId);
+ } else if (it.rowType == TraceRow.ROW_TYPE_STATIC_INIT) {
+ selection.staticInit = true;
+ this.pushPidToSelection(selection, it.rowParentId!);
+ info('load thread traceRow id is : ', it.rowId);
+ } else if (it.rowType == TraceRow.ROW_TYPE_APP_STARTUP) {
+ selection.startup = true;
+ this.pushPidToSelection(selection, it.rowParentId!);
+ info('load thread traceRow id is : ', it.rowId);
} else if (it.rowType == TraceRow.ROW_TYPE_THREAD) {
this.pushPidToSelection(selection, it.rowParentId!);
selection.threadIds.push(parseInt(it.rowId!));
@@ -1392,6 +1408,20 @@ export class SpSystemTrace extends BaseElement {
(JankStruct.selectJankStruct.dur || 0),
shiftKey
);
+ } else if (AppStartupStruct.selectStartupStruct) {
+ this.slicestime = this.timerShaftEL?.setSlicesMark(
+ AppStartupStruct.selectStartupStruct.startTs || 0,
+ (AppStartupStruct.selectStartupStruct.startTs || 0) +
+ (AppStartupStruct.selectStartupStruct.dur || 0),
+ shiftKey
+ );
+ } else if (SoStruct.selectSoStruct) {
+ this.slicestime = this.timerShaftEL?.setSlicesMark(
+ SoStruct.selectSoStruct.startTs || 0,
+ (SoStruct.selectSoStruct.startTs || 0) +
+ (SoStruct.selectSoStruct.dur || 0),
+ shiftKey
+ );
} else {
this.slicestime = this.timerShaftEL?.setSlicesMark();
}
@@ -1566,6 +1596,8 @@ export class SpSystemTrace extends BaseElement {
IrqStruct.hoverIrqStruct = undefined;
HeapStruct.hoverHeapStruct = undefined;
JankStruct.hoverJankStruct = undefined;
+ AppStartupStruct.hoverStartupStruct = undefined;
+ SoStruct.hoverSoStruct = undefined;
HeapSnapshotStruct.hoverSnapshotStruct = undefined;
}
@@ -1582,6 +1614,8 @@ export class SpSystemTrace extends BaseElement {
IrqStruct.selectIrqStruct = undefined;
JankStruct.selectJankStruct = undefined;
HeapStruct.selectHeapStruct = undefined;
+ AppStartupStruct.selectStartupStruct = undefined;
+ SoStruct.selectSoStruct = undefined;
HeapSnapshotStruct.selectSnapshotStruct = undefined;
}
@@ -1679,6 +1713,8 @@ export class SpSystemTrace extends BaseElement {
() => ClockStruct.hoverClockStruct !== null && ClockStruct.hoverClockStruct !== undefined,
],
[TraceRow.ROW_TYPE_IRQ, () => IrqStruct.hoverIrqStruct !== null && IrqStruct.hoverIrqStruct !== undefined],
+ [TraceRow.ROW_TYPE_APP_STARTUP, () => AppStartupStruct.hoverStartupStruct !== null && AppStartupStruct.hoverStartupStruct !== undefined],
+ [TraceRow.ROW_TYPE_STATIC_INIT, () => SoStruct.hoverSoStruct !== null && SoStruct.hoverSoStruct !== undefined],
[TraceRow.ROW_TYPE_JANK, () => JankStruct.hoverJankStruct !== null && JankStruct.hoverJankStruct !== undefined],
[TraceRow.ROW_TYPE_HEAP, () => HeapStruct.hoverHeapStruct !== null && HeapStruct.hoverHeapStruct !== undefined],
[
@@ -1701,6 +1737,7 @@ export class SpSystemTrace extends BaseElement {
let cpuClickHandler: any;
let jankClickHandler: any;
let snapshotClickHandler: any;
+ let scrollToFuncHandler: any;
threadClickHandler = (d: ThreadStruct) => {
this.observerScrollHeightEnable = false;
this.scrollToProcess(`${d.cpu}`, '', 'cpu-data', true);
@@ -1836,6 +1873,12 @@ export class SpSystemTrace extends BaseElement {
task();
};
+ scrollToFuncHandler = (funcStract: any) => {
+ this.observerScrollHeightEnable = true;
+ this.moveRangeToCenter(funcStract.startTime!, funcStract.dur!);
+ this.scrollToActFunc(funcStract, false);
+ }
+
snapshotClickHandler = (d: HeapSnapshotStruct) => {
this.observerScrollHeightEnable = true;
let snapshotRow = this.shadowRoot?.querySelector>(
@@ -1881,11 +1924,7 @@ export class SpSystemTrace extends BaseElement {
let hoverFuncStruct = FuncStruct.hoverFuncStruct;
this.timerShaftEL?.drawTriangle(FuncStruct.selectFuncStruct!.startTs || 0, 'inverted');
FuncStruct.selectFuncStruct = hoverFuncStruct;
- this.traceSheetEL?.displayFuncData(FuncStruct.selectFuncStruct, (funcStract: any) => {
- this.observerScrollHeightEnable = true;
- this.moveRangeToCenter(funcStract.startTime!, funcStract.dur!);
- this.scrollToActFunc(funcStract, false);
- });
+ this.traceSheetEL?.displayFuncData(FuncStruct.selectFuncStruct, scrollToFuncHandler);
this.timerShaftEL?.modifyFlagList(undefined);
} else if (clickRowType === TraceRow.ROW_TYPE_CPU_FREQ && CpuFreqStruct.hoverCpuFreqStruct) {
CpuFreqStruct.selectCpuFreqStruct = CpuFreqStruct.hoverCpuFreqStruct;
@@ -1948,6 +1987,14 @@ export class SpSystemTrace extends BaseElement {
snapshotRow!.dataList,
snapshotClickHandler
);
+ } else if (clickRowType === TraceRow.ROW_TYPE_APP_STARTUP && AppStartupStruct.hoverStartupStruct) {
+ AppStartupStruct.selectStartupStruct = AppStartupStruct.hoverStartupStruct;
+ this.traceSheetEL?.displayStartupData(AppStartupStruct.selectStartupStruct, scrollToFuncHandler);
+ this.timerShaftEL?.modifyFlagList(undefined);
+ } else if (clickRowType === TraceRow.ROW_TYPE_STATIC_INIT && SoStruct.hoverSoStruct) {
+ SoStruct.selectSoStruct = SoStruct.hoverSoStruct;
+ this.traceSheetEL?.displayStaticInitData(SoStruct.selectSoStruct, scrollToFuncHandler);
+ this.timerShaftEL?.modifyFlagList(undefined);
} else {
if (!JankStruct.hoverJankStruct && JankStruct.delJankLineFlag) {
this.clearPointPair();
@@ -2701,13 +2748,15 @@ export class SpSystemTrace extends BaseElement {
scrollToActFunc(funcStract: any, highlight: boolean) {
const toTargetDepth = (entry: any) => {
- this.hoverStructNull();
- this.selectStructNull();
- this.wakeupListNull();
- FuncStruct.hoverFuncStruct = entry;
- FuncStruct.selectFuncStruct = entry;
- this.onClickHandler(TraceRow.ROW_TYPE_FUNC);
- this.scrollToDepth(`${funcRowID}`, `${funcStract.pid}`, funcStract.type, true, funcStract.depth || 0);
+ if (entry) {
+ this.hoverStructNull();
+ this.selectStructNull();
+ this.wakeupListNull();
+ FuncStruct.hoverFuncStruct = entry;
+ FuncStruct.selectFuncStruct = entry;
+ this.onClickHandler(TraceRow.ROW_TYPE_FUNC);
+ this.scrollToDepth(`${funcRowID}`, `${funcStract.pid}`, funcStract.type, true, entry.depth || 0);
+ }
};
let funcRowID = funcStract.cookie == null ? funcStract.tid : `${funcStract.funName}-${funcStract.pid}`;
let targetRow = this.favoriteRowsEL!.querySelector>(
@@ -2734,7 +2783,9 @@ export class SpSystemTrace extends BaseElement {
}
}
filterRow!.highlight = highlight;
- this.closeAllExpandRows(funcStract.pid);
+ if (funcStract.keepOpen !== true) {
+ this.closeAllExpandRows(funcStract.pid);
+ }
let row = this.shadowRoot!.querySelector>(`trace-row[row-id='${funcStract.pid}'][folder]`);
if (row && !row.expansion) {
row.expansion = true;
diff --git a/ide/src/trace/component/chart/FrameChart.ts b/ide/src/trace/component/chart/FrameChart.ts
index e00285d8aaf8b03e2f0d575fd4b45359a7e9a707..f2e1a6c32d4fbaa55d7c18926a0d27db06f4bdf5 100644
--- a/ide/src/trace/component/chart/FrameChart.ts
+++ b/ide/src/trace/component/chart/FrameChart.ts
@@ -18,6 +18,7 @@ import { Rect } from '../trace/timer-shaft/Rect.js';
import { ChartMode, ChartStruct, draw, setFuncFrame } from '../../bean/FrameChartStruct.js';
import { SpApplication } from '../../SpApplication.js';
import { Utils } from '../trace/base/Utils.js';
+import { SpHiPerf } from './SpHiPerf.js';
const TAG: string = 'FrameChart';
const scaleHeight = 30;
@@ -381,7 +382,9 @@ export class FrameChart extends BaseElement {
scale = Utils.getByteWithUnit(((this.currentSize * sizeRatio) / 10) * i);
break;
case ChartMode.Count:
- scale = (((this.currentCount * sizeRatio) / 10) * i).toFixed(0) + '';
+ scale = Utils.timeMsFormat2p(
+ (((this.currentCount * (SpHiPerf.stringResult?.fValue || 1)) * sizeRatio) / 10) * i
+ );
break;
case ChartMode.Duration:
scale = Utils.getProbablyTime(((this.currentDuration * sizeRatio) / 10) * i);
@@ -730,11 +733,15 @@ export class FrameChart extends BaseElement {
break;
case ChartMode.Count:
let count = ChartStruct.hoverFuncStruct!.count;
+ const dur = Utils.timeMsFormat2p(count * (SpHiPerf.stringResult?.fValue || 1));
this.hintContent = `
Name: ${name}
Lib: ${ChartStruct.hoverFuncStruct?.lib}
- Addr: ${ChartStruct.hoverFuncStruct?.addr}
+ Addr: ${ChartStruct.hoverFuncStruct?.addr}
+
+ Dur: ${dur}
+
Count: ${count}`;
break;
case ChartMode.Duration:
diff --git a/ide/src/trace/component/chart/SpHiPerf.ts b/ide/src/trace/component/chart/SpHiPerf.ts
index 97dff67205ee377c6816a8a2e236ada7f56d8767..5cc0b9e91e512ae575d99bba2b8d2746973894d3 100644
--- a/ide/src/trace/component/chart/SpHiPerf.ts
+++ b/ide/src/trace/component/chart/SpHiPerf.ts
@@ -37,10 +37,9 @@ import { info } from '../../../log/Log.js';
import { HiperfEventRender, HiPerfEventStruct } from '../../database/ui-worker/ProcedureWorkerHiPerfEvent.js';
import { perfDataQuery } from './PerfDataQuery.js';
import { renders } from '../../database/ui-worker/ProcedureWorker.js';
-import { CpuRender, EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js';
+import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js';
import { HiperfReportRender, HiPerfReportStruct } from '../../database/ui-worker/ProcedureWorkerHiPerfReport.js';
-import { BaseStruct } from '../../database/ui-worker/ProcedureWorkerCommon.js';
-import { ProcessRender } from '../../database/ui-worker/ProcedureWorkerProcess.js';
+
export interface ResultData {
existA: boolean | null | undefined;
@@ -92,7 +91,7 @@ export class SpHiPerf {
SpHiPerf.stringResult = {
existA: sA !== -1,
existF: sF !== -1,
- fValue: Number((1000 / (sF !== -1 ? parseInt(list[sF + 1]) : 1000)).toFixed(1)),
+ fValue: Number((1000 / (sF !== -1 ? parseInt(list[sF + 1]) : 1000)).toFixed(2)),
};
}
diff --git a/ide/src/trace/component/chart/SpHiSysEventChart.ts b/ide/src/trace/component/chart/SpHiSysEventChart.ts
index 3b25805fa17a1ceae9419658881b80e436d9fac8..70e6a43f48ea67d9e9f6fd68fec1635f8700307b 100644
--- a/ide/src/trace/component/chart/SpHiSysEventChart.ts
+++ b/ide/src/trace/component/chart/SpHiSysEventChart.ts
@@ -575,7 +575,7 @@ export class SpHiSysEventChart {
let stateTraceRow = TraceRow.skeleton();
stateTraceRow.rowParentId = `energy`;
stateTraceRow.rowHidden = true;
- stateTraceRow.rowId = 'energy-state';
+ stateTraceRow.rowId = `energy-state-${stateList[index]}`;
stateTraceRow.rowType = TraceRow.ROW_TYPE_STATE_ENERGY;
stateTraceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
stateTraceRow.selectChangeHandler = this.trace.selectChangeHandler;
diff --git a/ide/src/trace/component/chart/SpNativeMemoryChart.ts b/ide/src/trace/component/chart/SpNativeMemoryChart.ts
index 990412d9a0be83932fb91af80e4ba19f2425fcd3..856e9d4f388690bffa298104806b9cb67a192fe3 100644
--- a/ide/src/trace/component/chart/SpNativeMemoryChart.ts
+++ b/ide/src/trace/component/chart/SpNativeMemoryChart.ts
@@ -206,7 +206,7 @@ export class SpNativeMemoryChart {
procedurePool.submitWithName(
'logic1',
'native-memory-init',
- { isRealtime, realTimeDif },
+ { isRealtime, realTimeDif, dataDict: SpSystemTrace.DATA_DICT },
undefined,
(res: any) => {
resolve(res);
diff --git a/ide/src/trace/component/chart/SpProcessChart.ts b/ide/src/trace/component/chart/SpProcessChart.ts
index 8fbf784afa964dc8a1387f0f869c03f93165d9b4..e428958ad638139a6b9c53e0e0c2adbee0fd82e1 100644
--- a/ide/src/trace/component/chart/SpProcessChart.ts
+++ b/ide/src/trace/component/chart/SpProcessChart.ts
@@ -29,8 +29,12 @@ import {
queryProcessData,
queryProcessMem,
queryProcessMemData,
+ queryProcessSoInitData,
+ queryProcessSoMaxDepth,
+ queryProcessStartup,
queryProcessThreads,
queryProcessThreadsByTable,
+ queryStartupPidArray,
queryThreadData,
} from '../../database/SqlLite.js';
import { Utils } from '../trace/base/Utils.js';
@@ -44,6 +48,8 @@ import { MemRender, ProcessMemStruct } from '../../database/ui-worker/ProcedureW
import { FolderSupplier, FolderThreadHandler } from './SpChartManager.js';
import { JankRender, JankStruct } from '../../database/ui-worker/ProcedureWorkerJank.js';
import { ns2xByTimeShaft } from '../../database/ui-worker/ProcedureWorkerCommon.js';
+import { AppStartupRender, AppStartupStruct } from '../../database/ui-worker/ProcedureWorkerAppStartup.js';
+import { SoRender, SoStruct } from '../../database/ui-worker/ProcedureWorkerSoInit.js';
export class SpProcessChart {
private readonly trace: SpSystemTrace;
@@ -58,6 +64,8 @@ export class SpProcessChart {
private processFuncDataCountMap: Map = new Map();
private processMemDataCountMap: Map = new Map();
private threadFuncMaxDepthMap: Map = new Map();
+ private startupProcessArr: { pid: number }[] = [];
+ private processSoMaxDepth: { pid: number; maxDepth: number }[] = [];
constructor(trace: SpSystemTrace) {
this.trace = trace;
@@ -167,6 +175,8 @@ export class SpProcessChart {
this.processAsyncEvent = await getAsyncEvents();
info('The amount of initialized process Event data is : ', this.processAsyncEvent!.length);
this.processMem = await queryProcessMem();
+ this.startupProcessArr = await queryStartupPidArray();
+ this.processSoMaxDepth = await queryProcessSoMaxDepth();
info('The amount of initialized process memory data is : ', this.processMem!.length);
let eventCountList: Array = await queryEventCountMap();
this.eventCountMap = eventCountList.reduce((pre, current) => {
@@ -237,6 +247,15 @@ export class SpProcessChart {
processRow.canvasRestore(this.trace.canvasPanelCtx!);
};
this.trace.rowsEL?.appendChild(processRow);
+ let startupRow: TraceRow | undefined = undefined;
+ let soRow: TraceRow | undefined = undefined;
+ if (this.startupProcessArr.find((sp) => sp.pid === it.pid)) {
+ startupRow = this.addStartUpRow(processRow);
+ }
+ let maxSoDepth = this.processSoMaxDepth.find((md) => md.pid === it.pid);
+ if (maxSoDepth) {
+ soRow = this.addSoInitRow(processRow, maxSoDepth.maxDepth);
+ }
/**
* Janks Frames
*/
@@ -624,6 +643,10 @@ export class SpProcessChart {
processRow.addChildTraceRowAfter(threadRow, actualRow);
} else if (expectedRow != null) {
processRow.addChildTraceRowAfter(threadRow, expectedRow);
+ } else if (soRow) {
+ processRow.addChildTraceRowAfter(threadRow, soRow);
+ } else if (startupRow) {
+ processRow.addChildTraceRowAfter(threadRow, startupRow);
} else {
processRow.addChildTraceRowSpecifyLocation(threadRow, 0);
}
@@ -692,6 +715,97 @@ export class SpProcessChart {
info('The time to load the Process data is: ', durTime);
}
+ addStartUpRow(processRow: TraceRow) {
+ processRow.setAttribute('hasStartup','true');
+ let startupRow: TraceRow = TraceRow.skeleton();
+ startupRow.rowId = `app-start-${processRow.rowId}`;
+ startupRow.rowType = TraceRow.ROW_TYPE_APP_STARTUP;
+ startupRow.rowParentId = `${processRow.rowId}`;
+ startupRow.rowHidden = !processRow.expansion;
+ startupRow.index = 0;
+ startupRow.style.height = '30px';
+ startupRow.style.width = `100%`;
+ startupRow.name = `App Startups`;
+ startupRow.setAttribute('children', '');
+ startupRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
+ startupRow.selectChangeHandler = this.trace.selectChangeHandler;
+ startupRow.supplier = () =>
+ queryProcessStartup(parseInt(processRow.rowId!)).then((res) => {
+ if (res.length <= 0) {
+ startupRow.rowDiscard = true;
+ this.trace.refreshCanvas(true);
+ }
+ for (let i = 0; i < res.length; i++) {
+ if (res[i].startName! < 4 && i < res.length - 1) {
+ res[i].endItid = res[i + 1].itid;
+ }
+ }
+ return res;
+ });
+ startupRow.focusHandler = (ev) => {};
+ startupRow.onThreadHandler = (useCache) => {
+ let context = startupRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
+ startupRow.canvasSave(context);
+ (renders['app-start-up'] as AppStartupRender).renderMainThread(
+ {
+ context: context,
+ useCache: useCache,
+ type: `app-startup ${processRow.rowId}`,
+ },
+ startupRow
+ );
+ startupRow.canvasRestore(context);
+ };
+ processRow.addChildTraceRow(startupRow);
+ return startupRow;
+ }
+
+ addSoInitRow(processRow: TraceRow, maxDepth: number) {
+ processRow.setAttribute('hasStaticInit','true');
+ let maxHeight = (maxDepth + 1) * 20;
+ let soRow: TraceRow = TraceRow.skeleton();
+ soRow.rowId = `app-start-${processRow.rowId}`;
+ soRow.rowType = TraceRow.ROW_TYPE_STATIC_INIT;
+ soRow.rowParentId = `${processRow.rowId}`;
+ soRow.rowHidden = !processRow.expansion;
+ soRow.index = 0;
+ soRow.style.height = `${maxHeight}px`;
+ soRow.style.width = `100%`;
+ soRow.name = `Static Initialization`;
+ soRow.setAttribute('children', '');
+ soRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
+ soRow.selectChangeHandler = this.trace.selectChangeHandler;
+ soRow.supplier = () =>
+ queryProcessSoInitData(parseInt(processRow.rowId!)).then((res) => {
+ if (res.length <= 0) {
+ soRow.rowDiscard = true;
+ this.trace.refreshCanvas(true);
+ }
+ res.forEach(so => {
+ if (so.soName) {
+ so.soName = so.soName.replace('dlopen: ', '');
+ }
+ })
+ return res;
+ });
+ soRow.focusHandler = (ev) => {};
+ soRow.onThreadHandler = (useCache) => {
+ let context = soRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
+ soRow.canvasSave(context);
+ (renders['app-so-init'] as SoRender).renderMainThread(
+ {
+ context: context,
+ useCache: useCache,
+ type: `static-init ${processRow.rowId}`,
+ },
+ soRow
+ );
+ soRow.canvasRestore(context);
+ };
+ processRow.addChildTraceRow(soRow);
+ return soRow;
+ }
+
insertAfter(newEl: HTMLElement, targetEl: HTMLElement) {
let parentEl = targetEl.parentNode;
if (parentEl!.lastChild == targetEl) {
diff --git a/ide/src/trace/component/setting/SpProbesConfig.ts b/ide/src/trace/component/setting/SpProbesConfig.ts
index bcf541dd9ad9b955a15d98beaf19dabddf8e7925..dc22cc6083822efde91af7431caca80599423a2b 100644
--- a/ide/src/trace/component/setting/SpProbesConfig.ts
+++ b/ide/src/trace/component/setting/SpProbesConfig.ts
@@ -181,6 +181,7 @@ export class SpProbesConfig extends BaseElement {
{ value: 'app', isSelect: true },
{ value: 'ark', isSelect: true },
{ value: 'binder', isSelect: true },
+ { value: 'commonlibrary', isSelect: false },
{ value: 'daudio', isSelect: false },
{ value: 'dcamera', isSelect: false },
{ value: 'devicemanager', isSelect: false },
diff --git a/ide/src/trace/component/setting/SpRecordTemplate.ts b/ide/src/trace/component/setting/SpRecordTemplate.ts
index 8a42e304278a077d6ecf5d54b16a33fa2cfaee8d..57385e528f8fb4ae4a8e7a49f721897aa00cc9ad 100644
--- a/ide/src/trace/component/setting/SpRecordTemplate.ts
+++ b/ide/src/trace/component/setting/SpRecordTemplate.ts
@@ -78,16 +78,24 @@ export class SpRecordTemplate extends BaseElement {
];
private frameTimeline: LitSwitch | undefined | null;
private schedulingAnalysis: LitSwitch | undefined | null;
+ private appStartup: LitSwitch | undefined | null;
initElements(): void {
this.frameTimeline = this.shadowRoot?.querySelector('#frame_timeline');
this.schedulingAnalysis = this.shadowRoot?.querySelector('#scheduling_analysis');
+ this.appStartup = this.shadowRoot?.querySelector('#app_startup');
this.frameTimeline!.addEventListener('change', (event: CustomEventInit) => {
let detail = event.detail;
if (detail!.checked) {
this.dispatchEvent(new CustomEvent('addProbe', {}));
}
});
+ this.appStartup!.addEventListener('change', (event: CustomEventInit) => {
+ let detail = event.detail;
+ if (detail!.checked) {
+ this.dispatchEvent(new CustomEvent('addProbe', {}));
+ }
+ });
this.schedulingAnalysis!.addEventListener('change', (event: CustomEventInit) => {
let detail = event.detail;
if (detail!.checked) {
@@ -101,7 +109,7 @@ export class SpRecordTemplate extends BaseElement {
let traceEventSet = new Array();
let hitraceCategories = new Array();
let useFtracePlugin: boolean = false;
- if (this.frameTimeline?.checked) {
+ if (this.frameTimeline?.checked || this.appStartup?.checked) {
useFtracePlugin = true;
SpRecordTemplate.FRAME_TIMELINE_CATEGORIES_EVENT.forEach((categories) => {
if (hitraceCategories.indexOf(categories) == -1) {
@@ -203,6 +211,12 @@ export class SpRecordTemplate extends BaseElement {
+
`;
}
diff --git a/ide/src/trace/component/trace/base/ColorUtils.ts b/ide/src/trace/component/trace/base/ColorUtils.ts
index 12681ffb2631ed601a8726a969cd028b4c5430ba..b67bd5364f589eecdf00bee880f5fd389dbcd816 100644
--- a/ide/src/trace/component/trace/base/ColorUtils.ts
+++ b/ide/src/trace/component/trace/base/ColorUtils.ts
@@ -48,7 +48,7 @@ export class ColorUtils {
'#AACEA0',
'#E69553',
'#7EC6BB',
- '#C6D9F2',
+ '#8d9171',
];
public static JANK_COLOR: Array = ['#42A14D', '#C0CE85', '#FF651D', '#E8BE44', '#009DFA', '#E97978'];
diff --git a/ide/src/trace/component/trace/base/RangeSelect.ts b/ide/src/trace/component/trace/base/RangeSelect.ts
index 4ab5da2558d09bb5c36eecb7ae84d352621b2032..cd368a4760bcbdb482f7e87e0ff6604becac987a 100644
--- a/ide/src/trace/component/trace/base/RangeSelect.ts
+++ b/ide/src/trace/component/trace/base/RangeSelect.ts
@@ -232,6 +232,11 @@ export class RangeSelect {
rt = new Rect(xMin, Math.min(this.startY2, this.endY2), xMax - xMin, Math.abs(this.startY2 - this.endY2));
} else {
bound = it.getBoundingClientRect();
+ if (spacerRect.height > 0 &&
+ (bound.y + bound.height) < (spacerRect.y + spacerRect.height)) {
+ it.rangeSelect = false;
+ return false;
+ }
itRect = Rect.getIntersect(
bound,
new Rect(rowsRect.x, rowsRect.y + spacerRect.height, rowsRect.width, rowsRect.height - spacerRect.height)
diff --git a/ide/src/trace/component/trace/base/TraceRow.ts b/ide/src/trace/component/trace/base/TraceRow.ts
index ae07e7559cf32f8b558d26709503689c534e64df..021af632f10352d08d7a9bfc36acec7cecdf9dd4 100644
--- a/ide/src/trace/component/trace/base/TraceRow.ts
+++ b/ide/src/trace/component/trace/base/TraceRow.ts
@@ -57,6 +57,8 @@ export class TraceRow extends HTMLElement {
static ROW_TYPE_HIPERF_REPORT = 'hiperf-report';
static ROW_TYPE_HIPERF_EVENT = 'hiperf-event';
static ROW_TYPE_PROCESS = 'process';
+ static ROW_TYPE_APP_STARTUP = 'app-startup';
+ static ROW_TYPE_STATIC_INIT = 'static-init';
static ROW_TYPE_THREAD = 'thread';
static ROW_TYPE_MEM = 'mem';
static ROW_TYPE_VIRTUAL_MEMORY_GROUP = 'virtual-memory-group';
diff --git a/ide/src/trace/component/trace/base/TraceSheet.ts b/ide/src/trace/component/trace/base/TraceSheet.ts
index d554f88c83dc82b91548dfaef9b769159d850e23..42b74b2560d61eac965541c59a0e21c511dae9c9 100644
--- a/ide/src/trace/component/trace/base/TraceSheet.ts
+++ b/ide/src/trace/component/trace/base/TraceSheet.ts
@@ -43,6 +43,8 @@ import { TabPaneSummary } from '../sheet/snapshot/TabPaneSummary.js';
import { TabPaneNMStatisticAnalysis } from '../sheet/native-memory/TabPaneNMStatisticAnalysis.js';
import { TabPaneCurrent } from '../sheet/TabPaneCurrent.js';
import { SlicesTime } from '../timer-shaft/SportRuler.js';
+import { AppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAppStartup.js';
+import { SoStruct } from '../../../database/ui-worker/ProcedureWorkerSoInit.js';
@element('trace-sheet')
export class TraceSheet extends BaseElement {
private litTabs: LitTabs | undefined | null;
@@ -359,6 +361,10 @@ export class TraceSheet extends BaseElement {
displayClockData = (data: ClockStruct) =>
this.displayTab('current-selection').setClockData(data);
displayIrqData = (data: IrqStruct) => this.displayTab('current-selection').setIrqData(data);
+ displayStartupData = (data: AppStartupStruct, scrollCallback: Function) =>
+ this.displayTab('current-selection').setStartupData(data,scrollCallback);
+ displayStaticInitData = (data: SoStruct, scrollCallback: Function) =>
+ this.displayTab('current-selection').setStaticInitData(data,scrollCallback);
displayNativeHookData = (data: HeapStruct, rowType: string) => {
let val = new SelectionParam();
diff --git a/ide/src/trace/component/trace/base/TraceSheetConfig.ts b/ide/src/trace/component/trace/base/TraceSheetConfig.ts
index fccc11b170adf17a7aaf17f111f0953f091b0a3f..55f9fe7992b82585eb40fb90b8e83566fcf10519 100644
--- a/ide/src/trace/component/trace/base/TraceSheetConfig.ts
+++ b/ide/src/trace/component/trace/base/TraceSheetConfig.ts
@@ -74,6 +74,8 @@ import { TabPaneFilesystemStatisticsAnalysis } from '../sheet/file-system/TabPan
import { TabPaneIOTierStatisticsAnalysis } from '../sheet/file-system/TabPaneIOTierStatisticsAnalysis.js';
import { TabPaneVirtualMemoryStatisticsAnalysis } from '../sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.js';
import { TabPaneCurrent } from '../sheet/TabPaneCurrent.js';
+import { TabPaneStartup } from '../sheet/process/TabPaneStartup.js';
+import { TabPaneStaticInit } from '../sheet/process/TabPaneStaticInit.js';
export let tabConfig: any = {
'tabpane-current': {
@@ -132,6 +134,16 @@ export let tabConfig: any = {
type: TabPaneThreadStates,
require: (param: SelectionParam) => param.threadIds.length > 0,
},
+ 'box-process-startup': {
+ title: 'App Startups',
+ type: TabPaneStartup,
+ require: (param: SelectionParam) => param.processIds.length > 0 && param.startup,
+ },
+ 'box-process-static-init': {
+ title: 'Static Initialization',
+ type: TabPaneStaticInit,
+ require: (param: SelectionParam) => param.processIds.length > 0 && param.staticInit,
+ },
'box-thread-usage': {
title: 'Thread Usage',
type: TabPaneThreadUsage,
diff --git a/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts b/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts
index 8287c1040ca67290a5b4ef4f9625caaf85405b65..552de8fc43e7c6354382b6e29a2442f5195ce811 100644
--- a/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts
+++ b/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts
@@ -29,6 +29,7 @@ import {
queryThreadWakeUp,
queryThreadWakeUpFrom,
queryCPUWakeUpIdFromBean,
+ queryThreadByItid,
} from '../../../database/SqlLite.js';
import { WakeupBean } from '../../../bean/WakeupBean.js';
import { SpApplication } from '../../../SpApplication.js';
@@ -45,6 +46,8 @@ import { JankStruct } from '../../../database/ui-worker/ProcedureWorkerJank.js';
import { LitIcon } from '../../../../base-ui/icon/LitIcon.js';
import { Utils } from '../base/Utils.js';
import { SpSystemTrace } from '../../SpSystemTrace.js';
+import { AppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAppStartup.js';
+import { SoStruct } from '../../../database/ui-worker/ProcedureWorkerSoInit.js';
const INPUT_WORD =
'This is the interval from when the task became eligible to run \n(e.g.because of notifying a wait queue it was a suspended on) to\n when it started running.';
@@ -168,7 +171,9 @@ export class TabPaneCurrentSelection extends BaseElement {
this.currentSelectionTbl!.dataSource = list;
let rightArea: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#table-right');
let rightTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightTitle');
- let rightButton: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightButton')?.shadowRoot?.querySelector("#custom-button");
+ let rightButton: HTMLElement | null | undefined = this?.shadowRoot
+ ?.querySelector('#rightButton')
+ ?.shadowRoot?.querySelector('#custom-button');
let threadClick = this.currentSelectionTbl?.shadowRoot?.querySelector('#thread-id');
threadClick?.addEventListener('click', () => {
//cpu点击
@@ -338,7 +343,9 @@ export class TabPaneCurrentSelection extends BaseElement {
this.initCanvas();
let leftTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#leftTitle');
let rightTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightTitle');
- let rightButton: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightButton')?.shadowRoot?.querySelector("#custom-button");
+ let rightButton: HTMLElement | null | undefined = this?.shadowRoot
+ ?.querySelector('#rightButton')
+ ?.shadowRoot?.querySelector('#custom-button');
if (rightTitle) {
rightTitle.style.visibility = 'hidden';
rightButton!.style.visibility = 'hidden';
@@ -391,7 +398,9 @@ export class TabPaneCurrentSelection extends BaseElement {
this.setTableHeight('550px');
this.initCanvas();
let rightTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightTitle');
- let rightButton: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightButton')?.shadowRoot?.querySelector("#custom-button");
+ let rightButton: HTMLElement | null | undefined = this?.shadowRoot
+ ?.querySelector('#rightButton')
+ ?.shadowRoot?.querySelector('#custom-button');
if (rightTitle) {
rightTitle.style.visibility = 'hidden';
rightButton!.style.visibility = 'hidden';
@@ -427,8 +436,9 @@ export class TabPaneCurrentSelection extends BaseElement {
this.initCanvas();
let leftTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#leftTitle');
let rightTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightTitle');
- let rightButton: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightButton')
- ?.shadowRoot?.querySelector("#custom-button");
+ let rightButton: HTMLElement | null | undefined = this?.shadowRoot
+ ?.querySelector('#rightButton')
+ ?.shadowRoot?.querySelector('#custom-button');
if (rightTitle) {
rightTitle.style.visibility = 'hidden';
rightButton!.style.visibility = 'hidden';
@@ -552,7 +562,7 @@ export class TabPaneCurrentSelection extends BaseElement {
scrollCallback: ((d: any) => void) | undefined
) {
//线程信息
- this.setTableHeight('550px');
+ this.setTableHeight('750px');
this.tabCurrentSelectionInit('Slice Details');
let list: any[] = [];
this.setJankCommonMessage(list, data);
@@ -562,7 +572,7 @@ export class TabPaneCurrentSelection extends BaseElement {
if (data.frame_type === 'render_service') {
queryGpuDur(data.id!).then((it) => {
if (it.length > 0) {
- list.push({ name: `Gpu Duration
`, value: getTimeString(it[0].gpu_dur)});
+ list.push({ name: `Gpu Duration
`, value: getTimeString(it[0].gpu_dur) });
}
});
if (data.src_slice) {
@@ -576,7 +586,9 @@ export class TabPaneCurrentSelection extends BaseElement {
let appNode = new JankTreeNode(a.name, a.pid, 'app');
appNode.children.push(new JankTreeNode(a.name, a.pid, 'frameTime'));
jankJumperList.push(appNode);
- list.push({name: `Slice
`, value:
+ list.push({
+ name: `Slice
`,
+ value:
a.cmdline +
' [' +
a.name +
@@ -720,6 +732,144 @@ export class TabPaneCurrentSelection extends BaseElement {
}
}
+ setStartupData(data: AppStartupStruct, scrollCallback: Function) {
+ this.setTableHeight('550px');
+ this.initCanvas();
+ let rightTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightTitle');
+ let rightButton: HTMLElement | null | undefined = this?.shadowRoot
+ ?.querySelector('#rightButton')
+ ?.shadowRoot?.querySelector('#custom-button');
+ if (rightTitle) {
+ rightTitle.style.visibility = 'hidden';
+ rightButton!.style.visibility = 'hidden';
+ }
+ let leftTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#leftTitle');
+ if (leftTitle) {
+ leftTitle.innerText = 'Details';
+ }
+ let list: any[] = [];
+ list.push({ name: 'Name', value: AppStartupStruct.getStartupName(data.startName) });
+ list.push({
+ name: 'StartTime(Relative)',
+ value: `
+
+
${getTimeString(data.startTs || 0)}
+
+
`,
+ });
+ list.push({
+ name: 'StartTime(Absolute)',
+ value: ((data.startTs || 0) + (window as any).recordStartNS) / 1000000000,
+ });
+ if (data.dur && data.dur > 0) {
+ list.push({
+ name: 'EndTime(Relative)',
+ value: `
+
${getTimeString((data.startTs || 0) + (data.dur || 0))}
+
+
`,
+ });
+ list.push({
+ name: 'EndTime(Absolute)',
+ value: ((data.startTs || 0) + (data.dur || 0) + (window as any).recordStartNS) / 1000000000,
+ });
+ } else {
+ list.push({
+ name: 'EndTime(Relative)',
+ value: `Unknown Time`,
+ });
+ list.push({
+ name: 'EndTime(Absolute)',
+ value: 'Unknown Time',
+ });
+ }
+ list.push({ name: 'Duration', value: getTimeString(data.dur || 0) });
+ this.currentSelectionTbl!.dataSource = list;
+ let startIcon = this.currentSelectionTbl?.shadowRoot?.querySelector('#start-jump');
+ let endIcon = this.currentSelectionTbl?.shadowRoot?.querySelector('#end-jump');
+ let scrollClick = (type: number) => {
+ let recordNs: number = (window as any).recordStartNS;
+ let useEnd = type === 1 && data.startName! < 4;
+ queryThreadByItid(
+ useEnd ? data.endItid! : data.itid!,
+ useEnd ? recordNs + data.startTs! + data.dur! : recordNs + data.startTs!
+ ).then((result) => {
+ if (result.length > 0) {
+ let pt: { pid: number; tid: number; dur: number,name: string, depth: number } = result[0];
+ scrollCallback({
+ pid: pt.pid,
+ tid: pt.tid,
+ type: 'func',
+ dur: pt.dur,
+ depth: pt.depth,
+ funName: pt.name,
+ startTime: useEnd ? (data.startTs || 0) + (data.dur || 0) : data.startTs,
+ keepOpen: true,
+ });
+ }
+ });
+ };
+ if (startIcon) {
+ startIcon.addEventListener('click', () => scrollClick(0));
+ }
+ if (endIcon) {
+ endIcon.addEventListener('click', () => scrollClick(1));
+ }
+ }
+
+ setStaticInitData(data: SoStruct, scrollCallback: Function) {
+ this.setTableHeight('550px');
+ this.initCanvas();
+ let rightTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightTitle');
+ let rightButton: HTMLElement | null | undefined = this?.shadowRoot
+ ?.querySelector('#rightButton')
+ ?.shadowRoot?.querySelector('#custom-button');
+ if (rightTitle) {
+ rightTitle.style.visibility = 'hidden';
+ rightButton!.style.visibility = 'hidden';
+ }
+ let leftTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#leftTitle');
+ if (leftTitle) {
+ leftTitle.innerText = 'Details';
+ }
+ let list: any[] = [];
+ list.push({ name: 'Name', value: data.soName });
+ list.push({
+ name: 'StartTime(Relative)',
+ value: `
+
${getTimeString(data.startTs || 0)}
+
+
`,
+ });
+ list.push({
+ name: 'StartTime(Absolute)',
+ value: ((data.startTs || 0) + (window as any).recordStartNS) / 1000000000,
+ });
+ list.push({ name: 'Duration', value: getTimeString(data.dur || 0) });
+ this.currentSelectionTbl!.dataSource = list;
+ let startIcon = this.currentSelectionTbl?.shadowRoot?.querySelector('#start-jump');
+ if (startIcon) {
+ startIcon.addEventListener('click', () => {
+ let recordNs: number = (window as any).recordStartNS;
+ queryThreadByItid(data.itid!, recordNs + data.startTs!).then((result) => {
+ if (result.length > 0) {
+ let pt: { pid: number; tid: number; dur: number,name: string, depth: number } = result[0];
+ scrollCallback({
+ pid: pt.pid,
+ tid: pt.tid,
+ type: 'func',
+ dur: pt.dur,
+ depth: pt.depth,
+ funName: pt.name,
+ startTime: data.startTs,
+ keepOpen: true,
+ });
+ }
+ });
+ });
+ }
+ }
+
private setJankType(data: JankStruct, list: any[]) {
if (data.jank_tag === 1) {
if (data.frame_type === 'render_service') {
@@ -735,6 +885,7 @@ export class TabPaneCurrentSelection extends BaseElement {
list.push({ name: 'Jank Type', value: 'NONE' });
}
}
+
private setJankCommonMessage(list: any[], data: JankStruct) {
list.push({ name: 'Name', value: data.name });
list.push({ name: 'StartTime', value: getTimeString(data.ts || 0) });
@@ -744,6 +895,7 @@ export class TabPaneCurrentSelection extends BaseElement {
list.push({ name: 'Process', value: data.cmdline + ' ' + data.pid });
}
}
+
private setTableHeight(height: string) {
this.scrollView!.scrollTop = 0;
this.currentSelectionTbl!.style.height = height;
diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.ts
index 20eca20e64daa72b3151b34ec7a4fc4553c433c7..376e635454b0c3b46ce58be3c07e3c90ffd3f888 100644
--- a/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.ts
+++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.ts
@@ -765,7 +765,7 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement {
for (let item of value) {
dur += item.dur;
if (key === null) {
- item.libName = 'unkown';
+ item.libName = 'unknown';
}
soName = item.libName;
}
diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.ts
index 8c01e3c80a96513e80a614f827be83f8cc502c83..8baeeb35ddbc302b495699d323b4a867c8b348e3 100644
--- a/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.ts
+++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.ts
@@ -754,7 +754,7 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement {
for (let item of value) {
dur += item.dur;
if (key === null) {
- item.libName = 'unkown';
+ item.libName = 'unknown';
}
libName = item.libName;
}
diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.ts
index 3348318ca8268313bd9e758186654e4a027cf7f8..f2abb4a728a1cc266d548fba9500d32343f6873f 100644
--- a/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.ts
+++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.ts
@@ -755,7 +755,7 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement {
for (let item of value) {
dur += item.dur;
if (key === null) {
- item.libName = 'unkown';
+ item.libName = 'unknown';
}
vmLibName = item.libName;
}
diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts
index 8799248200caeb296af74d1df281f050b8291102..38f881b6661a30cf8399dd64465c1470e25835ee 100644
--- a/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts
+++ b/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts
@@ -21,6 +21,7 @@ import '../../../../../base-ui/chart/pie/LitChartPie.js';
import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js';
import { procedurePool } from '../../../../database/Procedure.js';
import { Utils } from '../../base/Utils.js';
+import { SpHiPerf } from '../../../chart/SpHiPerf.js';
@element('tabpane-perf-analysis')
export class TabPanePerfAnalysis extends BaseElement {
@@ -514,7 +515,7 @@ export class TabPanePerfAnalysis extends BaseElement {
tableName: pName,
pid: pid,
percent: ((count / allCount) * 100).toFixed(2),
- countFormat: Utils.timeMsFormat2p(count),
+ countFormat: Utils.timeMsFormat2p(count * (SpHiPerf.stringResult?.fValue || 1)),
count: count,
};
this.pidData.push(pidData);
@@ -570,7 +571,7 @@ export class TabPanePerfAnalysis extends BaseElement {
pid: item.pid,
tid: tid,
tableName: tName,
- countFormat: Utils.timeMsFormat2p(threadCount),
+ countFormat: Utils.timeMsFormat2p(threadCount * (SpHiPerf.stringResult?.fValue || 1)),
count: threadCount,
percent: ((threadCount / allCount) * 100).toFixed(2),
};
@@ -616,7 +617,7 @@ export class TabPanePerfAnalysis extends BaseElement {
pid: item.pid,
tid: item.tid,
percent: ((libCount / parentCount) * 100).toFixed(2),
- countFormat: Utils.timeMsFormat2p(libCount),
+ countFormat: Utils.timeMsFormat2p(libCount * (SpHiPerf.stringResult?.fValue || 1)),
count: libCount,
tableName: libName,
libId: libId,
@@ -665,7 +666,7 @@ export class TabPanePerfAnalysis extends BaseElement {
pid: item.pid,
tid: item.tid,
percent: ((symbolCount / parentCount) * 100).toFixed(2),
- countFormat: Utils.timeMsFormat2p(symbolCount),
+ countFormat: Utils.timeMsFormat2p(symbolCount * (SpHiPerf.stringResult?.fValue || 1)),
count: symbolCount,
tableName: symbolName,
};
@@ -733,7 +734,7 @@ export class TabPanePerfAnalysis extends BaseElement {
totalCountData(count: number) {
let allCount;
allCount = {
- countFormat: Utils.timeMsFormat2p(count),
+ countFormat: Utils.timeMsFormat2p(count * (SpHiPerf.stringResult?.fValue || 1)),
percent: ((count / count) * 100).toFixed(2),
count: 0,
allCount: count,
@@ -756,7 +757,7 @@ export class TabPanePerfAnalysis extends BaseElement {
pieChartArr.push(res[i]);
} else {
other.count += res[i].count;
- other.countFormat = Utils.timeMsFormat2p(other.count);
+ other.countFormat = Utils.timeMsFormat2p(other.count * (SpHiPerf.stringResult?.fValue || 1));
// @ts-ignore
other.percent = ((other.count / this.sumCount) * 100).toFixed(2);
}
diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts
index f4de118365360e015438750c4ef1fde97481406f..c6727ea2e794c8b4575f68b8e49f2714bad04d22 100644
--- a/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts
+++ b/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts
@@ -31,6 +31,7 @@ import '../../../../../base-ui/progress-bar/LitProgressBar.js';
import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar.js';
import { procedurePool } from '../../../../database/Procedure.js';
import { showButtonMenu } from '../SheetUtils.js';
+import { SpHiPerf } from '../../../chart/SpHiPerf.js';
@element('tabpane-perf-profile')
export class TabpanePerfProfile extends BaseElement {
@@ -45,7 +46,7 @@ export class TabpanePerfProfile extends BaseElement {
private currentSelectedData: any = undefined;
private perfProfileFrameChart: FrameChart | null | undefined;
private isChartShow: boolean = false;
- private systmeRuleName = '/system/';
+ private systemRuleName = '/system/';
private numRuleName = '/max/min/';
private perfProfilerModal: DisassemblingWindow | null | undefined;
private needShowMenu = true;
@@ -53,7 +54,6 @@ export class TabpanePerfProfile extends BaseElement {
private perfProfileLoadingList: number[] = [];
private perfProfileLoadingPage: any;
private currentSelection: SelectionParam | undefined;
- private isCurrentIsTopDown: boolean = true;
set data(perfProfilerSelection: SelectionParam | any) {
if (perfProfilerSelection == this.currentSelection) {
@@ -72,7 +72,6 @@ export class TabpanePerfProfile extends BaseElement {
this.perfProfilerFilter!.filterValue = '';
this.perfProfileProgressEL!.loading = true;
this.perfProfileLoadingPage.style.visibility = 'visible';
- this.isCurrentIsTopDown = true;
this.getDataByWorker(
[
{
@@ -375,7 +374,7 @@ export class TabpanePerfProfile extends BaseElement {
} else {
perfProfileArgs.push({
funcName: 'resotreAllNode',
- funcArgs: [[this.systmeRuleName]],
+ funcArgs: [[this.systemRuleName]],
});
perfProfileArgs.push({
funcName: 'resetAllNode',
@@ -383,7 +382,7 @@ export class TabpanePerfProfile extends BaseElement {
});
perfProfileArgs.push({
funcName: 'clearSplitMapData',
- funcArgs: [this.systmeRuleName],
+ funcArgs: [this.systemRuleName],
});
}
this.getDataByWorker(perfProfileArgs, (result: any[]) => {
@@ -512,7 +511,6 @@ export class TabpanePerfProfile extends BaseElement {
refreshAllNode(filterData: any) {
let perfProfileArgs: any[] = [];
let isTopDown: boolean = !filterData.callTree[0];
- this.isCurrentIsTopDown = isTopDown;
let isHideSystemLibrary = filterData.callTree[1];
let list = filterData.dataMining.concat(filterData.dataLibrary);
perfProfileArgs.push({
diff --git a/ide/src/trace/component/trace/sheet/process/TabPaneStartup.ts b/ide/src/trace/component/trace/sheet/process/TabPaneStartup.ts
new file mode 100644
index 0000000000000000000000000000000000000000..05dec5eeb9274161428c359cb457be7f1105555d
--- /dev/null
+++ b/ide/src/trace/component/trace/sheet/process/TabPaneStartup.ts
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { BaseElement, element } from '../../../../../base-ui/BaseElement.js';
+import { LitTable } from '../../../../../base-ui/table/lit-table.js';
+import { SelectionParam } from '../../../../bean/BoxSelection.js';
+import { getTabStartups } from '../../../../database/SqlLite.js';
+import { log } from '../../../../../log/Log.js';
+import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js';
+import { resizeObserver } from '../SheetUtils.js';
+import { AppStartupStruct } from '../../../../database/ui-worker/ProcedureWorkerAppStartup.js';
+
+interface StartupTreeItem {
+ name: string;
+ step: number;
+ dur: number;
+ durStr: string;
+ ratio: string;
+ children: StartupTreeItem[] | undefined;
+}
+
+@element('tabpane-startup')
+export class TabPaneStartup extends BaseElement {
+ private startupTbl: LitTable | null | undefined;
+ private range: HTMLLabelElement | null | undefined;
+ private startupSource: Array = [];
+ private currentSelectionParam: SelectionParam | undefined;
+
+ set data(startupParam: SelectionParam | any) {
+ if (this.currentSelectionParam === startupParam) {
+ return;
+ }
+ this.currentSelectionParam = startupParam;
+ //@ts-ignore
+ this.startupTbl?.shadowRoot?.querySelector('.table')?.style?.height = this.parentElement!.clientHeight - 45 + 'px';
+ this.range!.textContent =
+ 'Selected range: ' + ((startupParam.rightNs - startupParam.leftNs) / 1000000.0).toFixed(5) + ' ms';
+ this.startupTbl!.loading = true;
+ getTabStartups(startupParam.processIds, startupParam.leftNs, startupParam.rightNs).then(
+ (result: AppStartupStruct[]) => {
+ this.startupTbl!.loading = false;
+ if (result != null && result.length > 0) {
+ log('getTabStartups result size : ' + result.length);
+ let map: Map = new Map();
+ result.forEach((item) => {
+ let startup = {
+ name: AppStartupStruct.getStartupName(item.startName),
+ dur: item.dur || 0,
+ durStr: getProbablyTime(item.dur || 0),
+ ratio: `0%`,
+ step: item.startName || 0,
+ children: [],
+ };
+ if (map.has(item.pid!)) {
+ let ps = map.get(item.pid!);
+ if (ps && ps.children) {
+ ps.dur += item.dur || 0;
+ ps.children!.push(startup);
+ }
+ } else {
+ map.set(item.pid!, {
+ name: item.process || `Process ${item.pid}`,
+ dur: item.dur || 0,
+ durStr: '',
+ ratio: `100%`,
+ step: 0,
+ children: [startup],
+ });
+ }
+ });
+ let startups = Array.from(map.values());
+ startups.forEach((it) => {
+ it.durStr = getProbablyTime(it.dur);
+ if (it.dur === 0) {
+ it.ratio = '0%';
+ }
+ it.children!.forEach((child) => {
+ if (it.dur === 0) {
+ child.ratio = '0%';
+ } else {
+ child.ratio = ((child.dur * 100) / (it.dur)).toFixed(2) + '%';
+ }
+ });
+ });
+ this.startupSource = startups;
+ this.startupTbl!.recycleDataSource = this.startupSource;
+ } else {
+ this.startupSource = [];
+ this.startupTbl!.recycleDataSource = [];
+ }
+ }
+ );
+ }
+
+ initElements(): void {
+ this.startupTbl = this.shadowRoot?.querySelector('#tb-startup');
+ this.range = this.shadowRoot?.querySelector('#startup-time-range');
+ this.startupTbl!.addEventListener('column-click', (evt: any) => {
+ this.sortByColumn(evt.detail);
+ });
+ }
+
+ connectedCallback() {
+ super.connectedCallback();
+ resizeObserver(this.parentElement!, this.startupTbl!);
+ }
+
+ initHtml(): string {
+ return `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `;
+ }
+
+ sortByColumn(startupDetail: any) {
+ let compare = (startupA: StartupTreeItem, startupB: StartupTreeItem) => {
+ if (startupDetail.sort === 0) {
+ return startupA.step - startupB.step;
+ } else if (startupDetail.sort === 1) {
+ return startupA.dur - startupB.dur;
+ } else {
+ return startupB.dur - startupA.dur;
+ }
+ };
+ this.startupSource.forEach((startup) => {
+ startup.children?.sort(compare);
+ });
+ this.startupSource.sort(compare);
+ this.startupTbl!.recycleDataSource = this.startupSource;
+ }
+}
diff --git a/ide/src/trace/component/trace/sheet/process/TabPaneStaticInit.ts b/ide/src/trace/component/trace/sheet/process/TabPaneStaticInit.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2db6273785246f085c42d48f08a06f33e266ef6a
--- /dev/null
+++ b/ide/src/trace/component/trace/sheet/process/TabPaneStaticInit.ts
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { BaseElement, element } from '../../../../../base-ui/BaseElement.js';
+import { LitTable } from '../../../../../base-ui/table/lit-table.js';
+import { SelectionParam } from '../../../../bean/BoxSelection.js';
+import { getTabStaticInit } from '../../../../database/SqlLite.js';
+import { log } from '../../../../../log/Log.js';
+import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js';
+import { resizeObserver } from '../SheetUtils.js';
+import { SoStruct } from '../../../../database/ui-worker/ProcedureWorkerSoInit.js';
+
+interface SoTreeItem {
+ name: string;
+ dur: number;
+ durStr: string;
+ ratio: string;
+ children: SoTreeItem[] | undefined;
+}
+
+@element('tabpane-static-init')
+export class TabPaneStaticInit extends BaseElement {
+ private staticinitTbl: LitTable | null | undefined;
+ private range: HTMLLabelElement | null | undefined;
+ private staticinitSource: Array = [];
+ private currentSelectionParam: SelectionParam | undefined;
+
+ set data(staticinitParam: SelectionParam | any) {
+ if (this.currentSelectionParam === staticinitParam) {
+ return;
+ }
+ this.currentSelectionParam = staticinitParam;
+ //@ts-ignore
+ this.staticinitTbl?.shadowRoot?.querySelector('.table')?.style?.height =
+ this.parentElement!.clientHeight - 45 + 'px';
+ this.range!.textContent =
+ 'Selected range: ' + ((staticinitParam.rightNs - staticinitParam.leftNs) / 1000000.0).toFixed(5) + ' ms';
+ this.staticinitTbl!.loading = true;
+ getTabStaticInit(staticinitParam.processIds, staticinitParam.leftNs, staticinitParam.rightNs).then(
+ (result: SoStruct[]) => {
+ this.staticinitTbl!.loading = false;
+ if (result != null && result.length > 0) {
+ log('getTabStaticInit result size : ' + result.length);
+ let map: Map = new Map();
+ result.forEach((item) => {
+ let so: SoTreeItem = {
+ name: (item.soName || '[NULL]').replace('dlopen: ', ''),
+ dur: item.dur || 0,
+ durStr: getProbablyTime(item.dur || 0),
+ ratio: `0%`,
+ children: [],
+ };
+ if (map.has(item.pid!)) {
+ let ps = map.get(item.pid!);
+ if (ps && ps.children) {
+ ps.dur += item.dur || 0;
+ ps.children!.push(so);
+ }
+ } else {
+ map.set(item.pid!, {
+ name: item.process || `Process ${item.pid}`,
+ dur: item.dur || 0,
+ durStr: '',
+ ratio: `100%`,
+ children: [so],
+ });
+ }
+ });
+ let soArr = Array.from(map.values());
+ soArr.forEach((it) => {
+ it.durStr = getProbablyTime(it.dur);
+ it.children!.forEach((child) => {
+ child.ratio = ((child.dur * 100) / it.dur).toFixed(2) + '%';
+ });
+ });
+ this.staticinitSource = soArr;
+ this.staticinitTbl!.recycleDataSource = this.staticinitSource;
+ } else {
+ this.staticinitSource = [];
+ this.staticinitTbl!.recycleDataSource = [];
+ }
+ }
+ );
+ }
+
+ initElements(): void {
+ this.staticinitTbl = this.shadowRoot?.querySelector('#tb-staticinit');
+ this.range = this.shadowRoot?.querySelector('#staticinit-time-range');
+ this.staticinitTbl!.addEventListener('column-click', (evt: any) => {
+ this.sortByColumn(evt.detail);
+ });
+ }
+
+ connectedCallback() {
+ super.connectedCallback();
+ resizeObserver(this.parentElement!, this.staticinitTbl!);
+ }
+
+ initHtml(): string {
+ return `
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `;
+ }
+
+ sortByColumn(soDetail: any) {
+ let compare = (soA: SoTreeItem, soB: SoTreeItem) => (soDetail.sort === 1 ? soA.dur - soB.dur : soB.dur - soA.dur);
+ this.staticinitSource.forEach((it) => it.children?.sort(compare));
+ this.staticinitSource.sort(compare);
+ this.staticinitTbl!.recycleDataSource = this.staticinitSource;
+ }
+}
diff --git a/ide/src/trace/database/SqlLite.ts b/ide/src/trace/database/SqlLite.ts
index 4cbd0e7fd89bf081fcf205b8d4cc23bbd6c933b0..f8ace2b35ffa83549835c37ac016b77dc630c03f 100644
--- a/ide/src/trace/database/SqlLite.ts
+++ b/ide/src/trace/database/SqlLite.ts
@@ -56,7 +56,6 @@ import { CpuFreqStruct } from './ui-worker/ProcedureWorkerFreq.js';
import { ThreadStruct } from './ui-worker/ProcedureWorkerThread.js';
import { FuncStruct } from './ui-worker/ProcedureWorkerFunc.js';
import { ProcessMemStruct } from './ui-worker/ProcedureWorkerMem.js';
-import { HeapTreeDataBean } from './logic-worker/ProcedureLogicWorkerNativeNemory.js';
import { FpsStruct } from './ui-worker/ProcedureWorkerFPS.js';
import { CpuAbilityMonitorStruct } from './ui-worker/ProcedureWorkerCpuAbility.js';
import { MemoryAbilityMonitorStruct } from './ui-worker/ProcedureWorkerMemoryAbility.js';
@@ -77,15 +76,20 @@ import {
HeapTraceFunctionInfo,
} from '../../js-heap/model/DatabaseStruct';
import { FileInfo } from '../../js-heap/model/UiStruct.js';
+import { AppStartupStruct } from './ui-worker/ProcedureWorkerAppStartup.js';
+import { SoStruct } from './ui-worker/ProcedureWorkerSoInit.js';
+import { HeapTreeDataBean } from './logic-worker/ProcedureLogicWorkerCommon.js';
class DataWorkerThread extends Worker {
taskMap: any = {};
+
uuid(): string {
// @ts-ignore
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c: any) =>
(c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)
);
}
+
//发送方法名 参数 回调
queryFunc(action: string, args: any, handler: Function) {
let id = this.uuid();
@@ -162,12 +166,10 @@ class DbThread extends Worker {
};
resetWASM() {
- this.postMessage(
- {
- id: this.uuid(),
- action: 'reset',
- }
- );
+ this.postMessage({
+ id: this.uuid(),
+ action: 'reset',
+ });
}
}
@@ -533,7 +535,7 @@ export const getFunDataByTid = (tid: number, ipid: number): Promise> =>
@@ -830,7 +832,12 @@ export const getTabCpuByThread = (cpus: Array, leftNS: number, rightNS:
{ $rightNS: rightNS, $leftNS: leftNS }
);
-export const getTabSlices = (funTids: Array, pids: Array, leftNS: number, rightNS: number): Promise> =>
+export const getTabSlices = (
+ funTids: Array,
+ pids: Array,
+ leftNS: number,
+ rightNS: number
+): Promise> =>
query(
'getTabSlices',
`
@@ -954,6 +961,38 @@ group by B.tid, B.pid, B.cpu;`;
});
};
+export const getTabStartups = (ids: Array, leftNS: number, rightNS: number): Promise> => {
+ let sql = `
+select
+ P.pid,
+ P.name as process,
+ (A.start_time - B.start_ts) as startTs,
+ (case when A.end_time = -1 then 0 else (A.end_time - A.start_time) end) as dur,
+ A.start_name as startName
+from app_startup A,trace_range B
+left join process P on A.ipid = P.ipid
+where P.pid in (${ids.join(',')})
+and not ((startTs + dur < ${leftNS}) or (startTs > ${rightNS}))
+order by start_name;`;
+ return query('getTabStartups', sql, {});
+};
+
+export const getTabStaticInit = (ids: Array, leftNS: number, rightNS: number): Promise> => {
+ let sql = `
+select
+ P.pid,
+ P.name as process,
+ (A.start_time - B.start_ts) as startTs,
+ (case when A.end_time = -1 then 0 else (A.end_time - A.start_time) end) as dur,
+ A.so_name as soName
+from static_initalize A,trace_range B
+left join process P on A.ipid = P.ipid
+where P.pid in (${ids.join(',')})
+and not ((startTs + dur < ${leftNS}) or (startTs > ${rightNS}))
+order by dur desc;`;
+ return query('getTabStaticInit', sql, {});
+};
+
export const queryBinderArgsByArgset = (argset: number): Promise> =>
query(
'queryBinderArgsByArgset',
@@ -1256,6 +1295,63 @@ where B.tid = $tid and B.pid = $pid;`,
{ $tid: tid, $pid: pid }
);
+export const queryStartupPidArray = (): Promise> =>
+ query(
+ 'queryStartupPidArray',
+ `
+ select distinct pid from app_startup A left join process P on A.ipid = p.ipid;`,
+ {}
+ );
+
+export const queryProcessStartup = (pid: number): Promise> =>
+ query(
+ 'queryProcessStartup',
+ `
+ select
+ P.pid,
+ A.tid,
+ A.call_id as itid,
+ (case when A.start_time < B.start_ts then 0 else (A.start_time - B.start_ts) end) as startTs,
+ (case
+ when A.start_time < B.start_ts then (A.end_time - B.start_ts)
+ when A.end_time = -1 then 0
+ else (A.end_time - A.start_time) end) as dur,
+ A.start_name as startName
+from app_startup A,trace_range B
+left join process P on A.ipid = P.ipid
+where P.pid = $pid
+order by start_name;`,
+ { $pid: pid }
+ );
+
+export const queryProcessSoMaxDepth = (): Promise> =>
+ query(
+ 'queryProcessSoMaxDepth',
+ `select p.pid,max(depth) maxDepth
+from static_initalize S left join process p on S.ipid = p.ipid
+group by p.pid;`,
+ {}
+ );
+
+export const queryProcessSoInitData = (pid: number): Promise> =>
+ query(
+ 'queryProcessSoInitData',
+ `
+ select
+ P.pid,
+ T.tid,
+ A.call_id as itid,
+ (A.start_time - B.start_ts) as startTs,
+ (A.end_time - A.start_time) as dur,
+ A.so_name as soName,
+ A.depth
+from static_initalize A,trace_range B
+left join process P on A.ipid = P.ipid
+left join thread T on A.call_id = T.itid
+where P.pid = $pid;`,
+ { $pid: pid }
+ );
+
export const queryThreadAndProcessName = (): Promise> =>
query(
'queryThreadAndProcessName',
@@ -2669,6 +2765,16 @@ where cat = 'binder' and c.id = $id;`,
{ $id: id }
);
+export const queryThreadByItid = (itid: number,ts: number): Promise> =>
+ query(
+ 'queryThreadByItid',
+ `select tid,pid,c.dur,c.depth,c.name
+from thread t left join process p on t.ipid = p.ipid
+left join callstack c on t.itid = c.callid
+where itid = $itid and c.ts = $ts;`,
+ { $itid: itid, $ts: ts }
+ );
+
export const queryBinderByArgsId = (id: number, startTime: number, isNext: boolean): Promise> => {
let sql = `select c.ts - D.start_ts as startTime,
c.dur,
@@ -4064,10 +4170,7 @@ export const queryHeapString = (fileId: number): Promise> =>
FROM js_heap_string WHERE file_id = ${fileId}`
);
export const queryTraceRange = (): Promise> =>
- query(
- 'queryTraceRange',
- `SELECT t.start_ts as startTs, t.end_ts as endTs FROM trace_range t`
- );
+ query('queryTraceRange', `SELECT t.start_ts as startTs, t.end_ts as endTs FROM trace_range t`);
export const queryHiPerfProcessCount = (
leftNs: number,
diff --git a/ide/src/trace/database/logic-worker/ProcedureLogicWorker.ts b/ide/src/trace/database/logic-worker/ProcedureLogicWorker.ts
index c122a72cd0de9889713f4f86a7361435e35dccec..72f30466744d27237667d16953588976fe809c45 100644
--- a/ide/src/trace/database/logic-worker/ProcedureLogicWorker.ts
+++ b/ide/src/trace/database/logic-worker/ProcedureLogicWorker.ts
@@ -19,6 +19,7 @@ import { ProcedureLogicWorkerFileSystem } from './ProcedureLogicWorkerFileSystem
import { ProcedureLogicWorkerSPT } from './ProcedureLogicWorkerSPT.js';
import { ProcedureLogicWorkerCpuState } from './ProcedureLogicWorkerCpuState.js';
import { ProcedureLogicWorkerSchedulingAnalysis } from './ProcedureLogicWorkerSchedulingAnalysis.js';
+import { DataCache } from './ProcedureLogicWorkerCommon.js';
let logicWorker: any = {
perf: new ProcedureLogicWorkerPerf(),
@@ -32,6 +33,7 @@ let logicWorker: any = {
function match(req: any) {
if (req.type === 'clear') {
Reflect.ownKeys(logicWorker).forEach(key => logicWorker[key].clearAll());
+ DataCache.getInstance().clearAll();
return;
}
Reflect.ownKeys(logicWorker).filter((it) => {
diff --git a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerCommon.ts b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerCommon.ts
index 1ceb3c493751e2d57433ed5cf32e71f610f113bb..82228a5d7d71c6571c464bb7ea57e35099dfd192 100644
--- a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerCommon.ts
+++ b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerCommon.ts
@@ -284,7 +284,7 @@ export abstract class LogicHandler {
});
}
- abstract clearAll(): void
+ abstract clearAll(): void;
}
let dec = new TextDecoder();
@@ -520,3 +520,71 @@ export function formatRealDate(date: Date, fmt: string) {
export function formatRealDateMs(timeNs: number) {
return formatRealDate(new Date(timeNs / 1000000), 'MM-dd hh:mm:ss.S');
}
+
+export class HeapTreeDataBean {
+ MoudleName: string | undefined;
+ AllocationFunction: string | undefined;
+ symbolId: number = 0;
+ fileId: number = 0;
+ startTs: number = 0;
+ endTs: number = 0;
+ eventType: string | undefined;
+ depth: number = 0;
+ heapSize: number = 0;
+ eventId: number = 0;
+ addr: string = '';
+ callChinId: number = 0;
+}
+
+export class PerfCall {
+ sampleId: number = 0;
+ depth: number = 0;
+ name: string = '';
+}
+
+export class FileCallChain {
+ callChainId: number = 0;
+ depth: number = 0;
+ symbolsId: number = 0;
+ pathId: number = 0;
+ ip: string = '';
+}
+
+export class DataCache {
+ public static instance: DataCache | undefined;
+ public dataDict = new Map();
+ public eBpfCallChainsMap = new Map>();
+ public nmFileDict = new Map();
+ public nmHeapFrameMap = new Map>();
+ public perfCountToMs = 1; // 1000 / freq
+ public perfCallChainMap: Map = new Map();
+
+ public static getInstance() {
+ if (!this.instance) {
+ this.instance = new DataCache();
+ }
+ return this.instance;
+ }
+
+ public clearAll() {
+ if (this.dataDict) {
+ this.dataDict.clear();
+ }
+ this.clearEBpf();
+ this.clearNM();
+ this.clearPerf();
+ }
+
+ public clearNM() {
+ this.nmFileDict.clear();
+ this.nmHeapFrameMap.clear();
+ }
+
+ public clearEBpf() {
+ this.eBpfCallChainsMap.clear();
+ }
+
+ public clearPerf() {
+ this.perfCallChainMap.clear();
+ }
+}
diff --git a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerFileSystem.ts b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerFileSystem.ts
index fe80216bb047213fbaf6f5dc112276ea54ca788b..b53e61d3ce323aa3700e1dcaeaaa1184935f974d 100644
--- a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerFileSystem.ts
+++ b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerFileSystem.ts
@@ -15,6 +15,8 @@
import {
convertJSON,
+ DataCache,
+ FileCallChain,
getByteWithUnit,
getProbablyTime,
getTimeString,
@@ -56,8 +58,7 @@ const PF_TYPE = 1;
const BIO_TYPE = 2;
export class ProcedureLogicWorkerFileSystem extends LogicHandler {
- static data_dict: Map = new Map();
- static callChainsMap: Map = new Map();
+ private dataCache = DataCache.getInstance();
handlerMap: Map = new Map();
currentEventId: string = '';
tab: string = '';
@@ -73,11 +74,12 @@ export class ProcedureLogicWorkerFileSystem extends LogicHandler {
if (data && data.type) {
switch (data.type) {
case 'fileSystem-init':
- ProcedureLogicWorkerFileSystem.data_dict = data.params as Map;
+ this.dataCache.dataDict = data.params;
this.initCallchains();
break;
case 'fileSystem-queryCallchains':
let callChains = convertJSON(data.params.list) || [];
+ this.dataCache.clearEBpf();
this.initCallChainTopDown(callChains);
// @ts-ignore
self.postMessage({
@@ -210,8 +212,7 @@ export class ProcedureLogicWorkerFileSystem extends LogicHandler {
}
clearAll() {
- ProcedureLogicWorkerFileSystem.data_dict.clear();
- ProcedureLogicWorkerFileSystem.callChainsMap.clear();
+ this.dataCache.clearEBpf();
for (let key of this.handlerMap.keys()) {
if (this.handlerMap.get(key).clear) {
this.handlerMap.get(key).clear();
@@ -353,14 +354,12 @@ export class ProcedureLogicWorkerFileSystem extends LogicHandler {
}
getStacksByCallchainId(id: number) {
- let stacks = ProcedureLogicWorkerFileSystem.callChainsMap.get(id) ?? [];
+ let stacks = this.dataCache.eBpfCallChainsMap.get(id) ?? [];
let arr: Array = [];
for (let s of stacks) {
let st: Stack = new Stack();
- st.path = (ProcedureLogicWorkerFileSystem.data_dict.get(s.pathId) ?? 'Unknown Path').split('/').reverse()[0];
- st.symbol = `${s.symbolsId == null ? s.ip : ProcedureLogicWorkerFileSystem.data_dict.get(s.symbolsId) ?? ''} (${
- st.path
- })`;
+ st.path = (this.dataCache.dataDict?.get(s.pathId) ?? 'Unknown Path').split('/').reverse()[0];
+ st.symbol = `${s.symbolsId == null ? s.ip : this.dataCache.dataDict?.get(s.symbolsId) ?? ''} (${st.path})`;
st.type = st.path.endsWith('.so.1') || st.path.endsWith('.dll') || st.path.endsWith('.so') ? 0 : 1;
arr.push(st);
}
@@ -376,14 +375,14 @@ export class ProcedureLogicWorkerFileSystem extends LogicHandler {
event.durPer4kStr = event.durPer4k == 0 ? '-' : getProbablyTime(event.durPer4k);
event.sizeStr = getByteWithUnit(event.size);
event.durStr = getProbablyTime(event.dur);
- event.path = event.pathId ? ProcedureLogicWorkerFileSystem.data_dict.get(event.pathId) ?? '-' : '-';
+ event.path = event.pathId ? this.dataCache.dataDict?.get(event.pathId) ?? '-' : '-';
// @ts-ignore
- event.operation = DISKIO_TYPE_MAP[`${event.type}`] || 'UNKNOW';
- let stacks = ProcedureLogicWorkerFileSystem.callChainsMap.get(event.callchainId) || [];
+ event.operation = DISKIO_TYPE_MAP[`${event.type}`] || 'UNKNOWN';
+ let stacks = this.dataCache.eBpfCallChainsMap.get(event.callchainId) || [];
if (stacks.length > 0) {
let stack = stacks[0];
event.backtrace = [
- stack.symbolsId == null ? stack.ip : ProcedureLogicWorkerFileSystem.data_dict.get(stack.symbolsId) ?? '',
+ stack.symbolsId == null ? stack.ip : this.dataCache.dataDict?.get(stack.symbolsId) ?? '',
`(${stacks.length} other frames)`,
];
} else {
@@ -399,14 +398,14 @@ export class ProcedureLogicWorkerFileSystem extends LogicHandler {
event.sizeStr = getByteWithUnit(event.size * 4096);
event.durStr = getProbablyTime(event.dur);
// @ts-ignore
- event.operation = VM_TYPE_MAP[`${event.type}`] || 'UNKNOW';
+ event.operation = VM_TYPE_MAP[`${event.type}`] || 'UNKNOWNN';
return event;
});
}
supplementFileSysEvents(res: Array, tab: string) {
res.map((r) => {
- let stacks = ProcedureLogicWorkerFileSystem.callChainsMap.get(r.callchainId);
+ let stacks = this.dataCache.eBpfCallChainsMap.get(r.callchainId);
r.startTsStr = getTimeString(r.startTs);
r.durStr = getProbablyTime(r.dur);
if (tab == 'events') {
@@ -416,17 +415,16 @@ export class ProcedureLogicWorkerFileSystem extends LogicHandler {
r.fourthArg = r.fourthArg ?? '0x0';
r.returnValue = r.returnValue ?? '0x0';
r.error = r.error ?? '0x0';
- r.path = ProcedureLogicWorkerFileSystem.data_dict.get(r.fileId) ?? '-';
+ r.path = this.dataCache.dataDict?.get(r.fileId) ?? '-';
}
// @ts-ignore
r.typeStr = FILE_TYPE_MAP[`${r.type}`] ?? '';
if (stacks && stacks.length > 0) {
let stack = stacks[0];
r.depth = stacks.length;
- r.symbol =
- stack.symbolsId == null ? stack.ip : ProcedureLogicWorkerFileSystem.data_dict.get(stack.symbolsId) ?? '';
+ r.symbol = stack.symbolsId == null ? stack.ip : this.dataCache.dataDict?.get(stack.symbolsId) ?? '';
if (tab != 'events') {
- r.path = ProcedureLogicWorkerFileSystem.data_dict.get(r.fileId) ?? '-';
+ r.path = this.dataCache.dataDict?.get(r.fileId) ?? '-';
}
r.backtrace = [r.symbol, `(${r.depth} other frames)`];
} else {
@@ -449,7 +447,6 @@ export class ProcedureLogicWorkerFileSystem extends LogicHandler {
this.handlerMap.set('fileSystem', new FileSystemCallTreeHandler('fileSystem', this.queryData));
this.handlerMap.set('io', new FileSystemCallTreeHandler('io', this.queryData));
this.handlerMap.set('virtualMemory', new FileSystemCallTreeHandler('virtualMemory', this.queryData));
- ProcedureLogicWorkerFileSystem.callChainsMap.clear();
this.queryData(
this.currentEventId,
'fileSystem-queryCallchains',
@@ -459,11 +456,12 @@ export class ProcedureLogicWorkerFileSystem extends LogicHandler {
}
initCallChainTopDown(list: any[]) {
+ const callChainsMap = this.dataCache.eBpfCallChainsMap;
list.forEach((callchain: FileCallChain) => {
- if (ProcedureLogicWorkerFileSystem.callChainsMap.has(callchain.callChainId)) {
- ProcedureLogicWorkerFileSystem.callChainsMap.get(callchain.callChainId)!.push(callchain);
+ if (callChainsMap.has(callchain.callChainId)) {
+ callChainsMap.get(callchain.callChainId)!.push(callchain);
} else {
- ProcedureLogicWorkerFileSystem.callChainsMap.set(callchain.callChainId, [callchain]);
+ callChainsMap.set(callchain.callChainId, [callchain]);
}
});
}
@@ -472,7 +470,7 @@ export class ProcedureLogicWorkerFileSystem extends LogicHandler {
let analysisSampleList = new Array();
for (let sample of samplesList) {
let analysisSample = new FileAnalysisSample(sample);
- let callChainList = ProcedureLogicWorkerFileSystem.callChainsMap.get(sample.callChainId);
+ let callChainList = this.dataCache.eBpfCallChainsMap.get(sample.callChainId);
if (!callChainList || callChainList.length === 0) {
continue;
}
@@ -486,14 +484,14 @@ export class ProcedureLogicWorkerFileSystem extends LogicHandler {
}
lastCallChain = callChainList[depth];
if (type === BIO_TYPE) {
- let symbolName = ProcedureLogicWorkerFileSystem.data_dict.get(lastCallChain.symbolsId);
+ let symbolName = this.dataCache.dataDict?.get(lastCallChain.symbolsId);
if (symbolName?.includes('submit_bio')) {
depth--;
} else {
break;
}
} else {
- let libPath = ProcedureLogicWorkerFileSystem.data_dict.get(lastCallChain.pathId);
+ let libPath = this.dataCache.dataDict?.get(lastCallChain.pathId);
if (libPath?.includes('musl') || libPath?.includes('libc++')) {
depth--;
} else {
@@ -506,10 +504,10 @@ export class ProcedureLogicWorkerFileSystem extends LogicHandler {
}
analysisSample.libId = lastCallChain.pathId;
analysisSample.symbolId = lastCallChain.symbolsId;
- let libPath = ProcedureLogicWorkerFileSystem.data_dict.get(analysisSample.libId) || '';
+ let libPath = this.dataCache.dataDict?.get(analysisSample.libId) || '';
let pathArray = libPath.split('/');
analysisSample.libName = pathArray[pathArray.length - 1];
- let symbolName = ProcedureLogicWorkerFileSystem.data_dict.get(analysisSample.symbolId);
+ let symbolName = this.dataCache.dataDict?.get(analysisSample.symbolId);
if (!symbolName) {
symbolName = lastCallChain.ip + ' (' + analysisSample.libName + ')';
}
@@ -720,7 +718,7 @@ where s.end_ts between $startTime + t.start_ts and $endTime + t.start_ts ${sql}
map = VM_TYPE_MAP;
}
// @ts-ignore
- typeCallChain.ip = map[sample.type.toString()] || 'UNKNOW';
+ typeCallChain.ip = map[sample.type.toString()] || 'UNKNOWN';
typeCallChain.symbolsId = sample.type;
typeCallChain.pathId = -1;
let threadCallChain = new FileCallChain();
@@ -728,11 +726,8 @@ where s.end_ts between $startTime + t.start_ts and $endTime + t.start_ts ${sql}
threadCallChain.ip = (sample.threadName || 'Thread') + `-${sample.tid}`;
threadCallChain.symbolsId = sample.tid;
threadCallChain.pathId = -1;
- return [
- typeCallChain,
- threadCallChain,
- ...(ProcedureLogicWorkerFileSystem.callChainsMap.get(sample.callChainId) || []),
- ];
+ const eBpfCallChainsMap = DataCache.getInstance().eBpfCallChainsMap;
+ return [typeCallChain, threadCallChain, ...(eBpfCallChainsMap.get(sample.callChainId) || [])];
}
merageChildrenByIndex(
@@ -778,11 +773,10 @@ where s.end_ts between $startTime + t.start_ts and $endTime + t.start_ts ${sql}
currentNode.libName = '';
currentNode.path = '';
} else {
- currentNode.symbol =
- ProcedureLogicWorkerFileSystem.data_dict.get(currentNode.symbolsId) || currentNode.ip || 'unkown';
- currentNode.path = ProcedureLogicWorkerFileSystem.data_dict.get(currentNode.pathId) || 'unkown';
- currentNode.lib = currentNode.libName = setFileName(currentNode.path);
- currentNode.addr = currentNode.ip;
+ const dataCache = DataCache.getInstance();
+ currentNode.symbol = dataCache.dataDict?.get(currentNode.symbolsId) || currentNode.ip || 'unknown';
+ currentNode.path = dataCache.dataDict?.get(currentNode.pathId) || 'unknown';
+ currentNode.libName = setFileName(currentNode.path);
currentNode.symbolName = `${currentNode.symbol} (${currentNode.libName})`;
}
}
@@ -861,14 +855,6 @@ where s.end_ts between $startTime + t.start_ts and $endTime + t.start_ts ${sql}
}
}
-class FileCallChain {
- callChainId: number = 0;
- depth: number = 0;
- symbolsId: number = 0;
- pathId: number = 0;
- ip: string = '';
-}
-
class FileSample {
type: number = 0;
callChainId: number = 0;
diff --git a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerNativeNemory.ts b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerNativeNemory.ts
index e8005142d18fb3d5b874db8cdc0ea7c9183f4eeb..0e38ec54720ee1abeba08b54ecc38ecf3b2ad361 100644
--- a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerNativeNemory.ts
+++ b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerNativeNemory.ts
@@ -14,9 +14,11 @@
*/
import {
convertJSON,
+ DataCache,
formatRealDateMs,
getByteWithUnit,
getTimeString,
+ HeapTreeDataBean,
LogicHandler,
MerageBean,
merageBeanDataSplit,
@@ -27,9 +29,6 @@ export class ProcedureLogicWorkerNativeMemory extends LogicHandler {
selectTotalSize = 0;
selectTotalCount = 0;
stackCount = 0;
- DATA_DICT: Map = new Map();
- FILE_DICT: Map = new Map();
- HEAP_FRAME_MAP: Map> = new Map>();
NATIVE_MEMORY_DATA: Array = [];
currentTreeMapData: any = {};
currentTreeList: any[] = [];
@@ -45,6 +44,7 @@ export class ProcedureLogicWorkerNativeMemory extends LogicHandler {
totalNS: number = 0;
isAnalysis: boolean = false;
isStatistic: boolean = false;
+ private dataCache = DataCache.getInstance();
handle(data: any): void {
this.currentEventId = data.id;
if (data && data.type) {
@@ -54,11 +54,7 @@ export class ProcedureLogicWorkerNativeMemory extends LogicHandler {
if (data.params.isRealtime) {
this.realTimeDif = data.params.realTimeDif;
}
- this.initDataDict();
- break;
- case 'native-memory-queryDataDICT':
- let dict = convertJSON(data.params.list) || [];
- dict.map((d: any) => this.DATA_DICT.set(d['id'], d['data']));
+ this.dataCache.dataDict = data.params.dataDict;
this.initNMChartData();
break;
case 'native-memory-queryNMChartData':
@@ -198,9 +194,6 @@ export class ProcedureLogicWorkerNativeMemory extends LogicHandler {
}
}
- initDataDict() {
- this.queryData(this.currentEventId, 'native-memory-queryDataDICT', `select * from data_dict;`, {});
- }
initNMChartData() {
this.queryData(
this.currentEventId,
@@ -221,9 +214,9 @@ export class ProcedureLogicWorkerNativeMemory extends LogicHandler {
(case when h.event_type = 'AllocEvent' then 2 else 3 end) as eventType
from native_hook h ,trace_range t
where
- h.start_ts between t.start_ts and t.end_ts
- and h.end_ts between t.start_ts and t.end_ts
- and (h.event_type = 'AllocEvent' or h.event_type = 'MmapEvent')
+ h.start_ts between t.start_ts and t.end_ts
+ and h.end_ts between t.start_ts and t.end_ts
+ and (h.event_type = 'AllocEvent' or h.event_type = 'MmapEvent')
)
order by startTime;
`,
@@ -231,10 +224,10 @@ export class ProcedureLogicWorkerNativeMemory extends LogicHandler {
);
}
queryNativeHookStatistic(type: number) {
- let condition = ''
+ let condition = '';
if (type === 0) {
condition = 'and type = 0';
- } else if(type === 1) {
+ } else if (type === 1) {
condition = 'and type > 0';
} else {
condition = '';
@@ -365,10 +358,10 @@ where ts between start_ts and end_ts ${condition};
initNMStack(frameArr: Array) {
frameArr.map((frame) => {
let frameEventId = frame.eventId;
- if (this.HEAP_FRAME_MAP.has(frameEventId)) {
- this.HEAP_FRAME_MAP.get(frameEventId)!.push(frame);
+ if (this.dataCache.nmHeapFrameMap.has(frameEventId)) {
+ this.dataCache.nmHeapFrameMap.get(frameEventId)!.push(frame);
} else {
- this.HEAP_FRAME_MAP.set(frameEventId, [frame]);
+ this.dataCache.nmHeapFrameMap.set(frameEventId, [frame]);
}
});
}
@@ -483,15 +476,15 @@ where ts between start_ts and end_ts ${condition};
}
resolvingActionNativeMemoryStack(paramMap: Map) {
let eventId = paramMap.get('eventId');
- let frameArr = this.HEAP_FRAME_MAP.get(eventId) || [];
+ let frameArr = this.dataCache.nmHeapFrameMap.get(eventId) || [];
let arr: Array = [];
frameArr.map((frame) => {
let target = new NativeHookCallInfo();
target.eventId = frame.eventId;
target.depth = frame.depth;
target.addr = frame.addr;
- target.symbol = this.groupCutFilePath(frame.symbolId, this.DATA_DICT.get(frame.symbolId) || '') ?? '';
- target.library = this.groupCutFilePath(frame.fileId, this.DATA_DICT.get(frame.fileId) || '') ?? '';
+ target.symbol = this.groupCutFilePath(frame.symbolId, this.dataCache.dataDict.get(frame.symbolId) || '') ?? '';
+ target.library = this.groupCutFilePath(frame.fileId, this.dataCache.dataDict.get(frame.fileId) || '') ?? '';
target.title = `[ ${target.symbol} ] ${target.library}`;
target.type =
target.library.endsWith('.so.1') || target.library.endsWith('.dll') || target.library.endsWith('.so') ? 0 : 1;
@@ -509,7 +502,7 @@ where ts between start_ts and end_ts ${condition};
let statisticsSelection = paramMap.get('statisticsSelection');
let filter = dataSource.filter((item) => {
if (item.subTypeId != null && item.subType == undefined) {
- item.subType = this.DATA_DICT.get(item.subTypeId) || '-';
+ item.subType = this.dataCache.dataDict.get(item.subTypeId) || '-';
}
let filterAllocation = true;
if (filterAllocType == '1') {
@@ -549,11 +542,11 @@ where ts between start_ts and end_ts ${condition};
memory.threadName = hook.threadName;
memory.lastLibId = hook.lastLibId;
(memory as any).isSelected = hook.isSelected;
- let arr = this.HEAP_FRAME_MAP.get(hook.eventId) || [];
+ let arr = this.dataCache.nmHeapFrameMap.get(hook.eventId) || [];
let frame = Array.from(arr)
.reverse()
.find((item) => {
- let fileName = this.DATA_DICT.get(item.fileId);
+ let fileName = this.dataCache.dataDict.get(item.fileId);
return !((fileName ?? '').includes('libc++') || (fileName ?? '').includes('musl'));
});
if (frame == null || frame == undefined) {
@@ -562,8 +555,11 @@ where ts between start_ts and end_ts ${condition};
}
}
if (frame != null && frame != undefined) {
- memory.symbol = this.groupCutFilePath(frame.symbolId, this.DATA_DICT.get(frame.symbolId) || '');
- memory.library = this.groupCutFilePath(frame.fileId, this.DATA_DICT.get(frame.fileId) || 'Unknown Path');
+ memory.symbol = this.groupCutFilePath(frame.symbolId, this.dataCache.dataDict.get(frame.symbolId) || '');
+ memory.library = this.groupCutFilePath(
+ frame.fileId,
+ this.dataCache.dataDict.get(frame.fileId) || 'Unknown Path'
+ );
} else {
memory.symbol = '-';
memory.library = '-';
@@ -609,11 +605,11 @@ where ts between start_ts and end_ts ${condition};
}
groupCutFilePath(fileId: number, path: string): string {
let name = '';
- if (this.FILE_DICT.has(fileId)) {
- name = this.FILE_DICT.get(fileId) ?? '';
+ if (this.dataCache.nmFileDict.has(fileId)) {
+ name = this.dataCache.nmFileDict.get(fileId) ?? '';
} else {
let currentPath = path.substring(path.lastIndexOf('/') + 1);
- this.FILE_DICT.set(fileId, currentPath);
+ this.dataCache.nmFileDict.set(fileId, currentPath);
name = currentPath;
}
return name == '' ? '-' : name;
@@ -708,9 +704,7 @@ where ts between start_ts and end_ts ${condition};
return false;
}
clearAll() {
- this.DATA_DICT.clear();
- this.FILE_DICT.clear();
- this.HEAP_FRAME_MAP.clear();
+ this.dataCache.clearNM();
this.splitMapData = {};
this.currentSamples = [];
this.allThreads = [];
@@ -754,8 +748,8 @@ where ts between start_ts and end_ts ${condition};
}
queryStatisticCallchainsSamples(action: string, leftNs: number, rightNs: number, types: Array) {
let condition = '';
- if(types.length === 1){
- if(types[0] === 0){
+ if (types.length === 1) {
+ if (types[0] === 0) {
condition = 'and type = 0';
} else {
condition = 'and type != 0';
@@ -800,7 +794,7 @@ where ts between start_ts and end_ts ${condition};
if (this.isStatistic) {
analysisSample.releaseCount = sample.freeCount;
analysisSample.releaseSize = sample.freeSize;
- switch(sample.subTypeId){
+ switch (sample.subTypeId) {
case 1:
analysisSample.subType = 'MmapEvent';
break;
@@ -816,7 +810,7 @@ where ts between start_ts and end_ts ${condition};
} else {
let subType = undefined;
if (sample.subTypeId) {
- subType = this.DATA_DICT.get(sample.subTypeId);
+ subType = this.dataCache.dataDict.get(sample.subTypeId);
}
analysisSample.endTs = sample.endTs;
analysisSample.addr = sample.addr;
@@ -839,7 +833,7 @@ where ts between start_ts and end_ts ${condition};
}
}
- const callChains = this.HEAP_FRAME_MAP.get(sample.eventId) || [];
+ const callChains = this.dataCache.nmHeapFrameMap.get(sample.eventId) || [];
if (!callChains || callChains.length === 0) {
return;
}
@@ -853,7 +847,7 @@ where ts between start_ts and end_ts ${condition};
}
lastFilterCallChain = callChains[index];
- const libPath = this.DATA_DICT.get(lastFilterCallChain.fileId);
+ const libPath = this.dataCache.dataDict.get(lastFilterCallChain.fileId);
//ignore musl and libc++ so
if (libPath?.includes('musl') || libPath?.includes('libc++')) {
index--;
@@ -863,13 +857,14 @@ where ts between start_ts and end_ts ${condition};
}
}
- const filePath = this.DATA_DICT.get(lastFilterCallChain.fileId)!;
+ const filePath = this.dataCache.dataDict.get(lastFilterCallChain.fileId)!;
let libName = '';
if (filePath) {
const path = filePath.split('/');
libName = path[path.length - 1];
}
- const symbolName = this.DATA_DICT.get(lastFilterCallChain.symbolId) || libName + ' (' + sample.addr + ')';
+ const symbolName =
+ this.dataCache.dataDict.get(lastFilterCallChain.symbolId) || libName + ' (' + sample.addr + ')';
analysisSample.libId = lastFilterCallChain.fileId;
analysisSample.libName = libName;
@@ -1033,7 +1028,7 @@ where ts between start_ts and end_ts ${condition};
this.currentSamples = Object.values(groupMap);
}
createThreadSample(sample: NativeHookStatistics) {
- return this.HEAP_FRAME_MAP.get(sample.eventId) || [];
+ return this.dataCache.nmHeapFrameMap.get(sample.eventId) || [];
}
merageChildrenByIndex(
currentNode: NativeHookCallInfo,
@@ -1066,8 +1061,8 @@ where ts between start_ts and end_ts ${condition};
}
setMerageName(currentNode: NativeHookCallInfo) {
currentNode.symbol =
- this.groupCutFilePath(currentNode.symbolId, this.DATA_DICT.get(currentNode.symbolId) || '') ?? 'unkown';
- currentNode.path = this.DATA_DICT.get(currentNode.fileId) || 'unkown';
+ this.groupCutFilePath(currentNode.symbolId, this.dataCache.dataDict.get(currentNode.symbolId) || '') ?? 'unknown';
+ currentNode.path = this.dataCache.dataDict.get(currentNode.fileId) || 'unknown';
currentNode.libName = setFileName(currentNode.path);
currentNode.lib = currentNode.path;
currentNode.symbolName = `[${currentNode.symbol}] ${currentNode.libName}`;
@@ -1151,20 +1146,7 @@ where ts between start_ts and end_ts ${condition};
}
}
}
-export class HeapTreeDataBean {
- MoudleName: string | undefined;
- AllocationFunction: string | undefined;
- symbolId: number = 0;
- fileId: number = 0;
- startTs: number = 0;
- endTs: number = 0;
- eventType: string | undefined;
- depth: number = 0;
- heapSize: number = 0;
- eventId: number = 0;
- addr: string = '';
- callChinId: number = 0;
-}
+
export class NativeHookStatistics {
id: number = 0;
eventId: number = 0;
diff --git a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerPerf.ts b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerPerf.ts
index 03d766f24bea1530b186451c5ffb37880eef71e7..eeb8534f6d9f78fefdb288e7c7065aa0600204cf 100644
--- a/ide/src/trace/database/logic-worker/ProcedureLogicWorkerPerf.ts
+++ b/ide/src/trace/database/logic-worker/ProcedureLogicWorkerPerf.ts
@@ -13,11 +13,11 @@
* limitations under the License.
*/
-import { LogicHandler, ChartStruct, convertJSON } from './ProcedureLogicWorkerCommon.js';
+import { LogicHandler, ChartStruct, convertJSON, DataCache, PerfCall } from './ProcedureLogicWorkerCommon.js';
+const systemRuleName = '/system/';
+const numRuleName = '/max/min/';
export class ProcedureLogicWorkerPerf extends LogicHandler {
- systmeRuleName = '/system/';
- numRuleName = '/max/min/';
filesData: any = {};
samplesData: any = {};
threadData: any = {};
@@ -28,19 +28,18 @@ export class ProcedureLogicWorkerPerf extends LogicHandler {
searchValue: string = '';
dataSource: PerfCallChainMerageData[] = [];
allProcess: PerfCallChainMerageData[] = [];
- callChainMap: Map = new Map();
- queryFunc: Function | undefined = undefined;
+ queryFunc?: Function | undefined;
isActualQuery: boolean = false;
- static cmdLineResult: any = undefined;
currentEventId: string = '';
isAnalysis: boolean = false;
+ private dataCache = DataCache.getInstance();
handle(data: any): void {
this.currentEventId = data.id;
if (data && data.type) {
switch (data.type) {
case 'perf-init':
- ProcedureLogicWorkerPerf.cmdLineResult = data.params;
+ this.dataCache.perfCountToMs = data.params.fValue;
this.initPerfFiles();
break;
case 'perf-queryPerfFiles':
@@ -63,7 +62,7 @@ export class ProcedureLogicWorkerPerf extends LogicHandler {
let perfCalls = convertJSON(data.params.list) || [];
if (perfCalls.length != 0) {
perfCalls.forEach((perfCall: any) => {
- this.callChainMap.set(perfCall.sampleId, perfCall);
+ this.dataCache.perfCallChainMap.set(perfCall.sampleId, perfCall);
});
}
this.initPerfCallchains();
@@ -75,7 +74,7 @@ export class ProcedureLogicWorkerPerf extends LogicHandler {
self.postMessage({
id: data.id,
action: data.action,
- results: this.callChainMap,
+ results: this.dataCache.perfCallChainMap,
});
break;
case 'perf-queryCallchainsGroupSample':
@@ -209,8 +208,7 @@ from (select callchain_id, s.thread_id, thread_state, process_id, count(callchai
this.searchValue = '';
this.dataSource = [];
this.allProcess = [];
- this.callChainMap.clear();
- ProcedureLogicWorkerPerf.cmdLineResult = null;
+ this.dataCache.clearPerf();
}
initPerfCallChainBottomUp(callChains: PerfCallChain[]) {
@@ -249,14 +247,14 @@ from (select callchain_id, s.thread_id, thread_state, process_id, count(callchai
callChain.fileName = this.filesData[callChain.fileId][0].fileName;
callChain.path = this.filesData[callChain.fileId][0].path;
} else {
- callChain.fileName = 'unkown';
+ callChain.fileName = 'unknown';
}
} else {
if (this.filesData[callChain.fileId] && this.filesData[callChain.fileId].length > callChain.symbolId) {
callChain.fileName = this.filesData[callChain.fileId][callChain.symbolId].fileName;
callChain.path = this.filesData[callChain.fileId][callChain.symbolId].path;
} else {
- callChain.fileName = 'unkown';
+ callChain.fileName = 'unknown';
}
}
}
@@ -268,11 +266,11 @@ from (select callchain_id, s.thread_id, thread_state, process_id, count(callchai
threadCallChain.depth = 0;
PerfCallChain.merageCallChain(threadCallChain, callChain);
threadCallChain.canCharge = false;
- threadCallChain.name = this.threadData[callChain.tid].threadName || 'Thead' + '(' + callChain.tid + ')';
+ threadCallChain.name = this.threadData[callChain.tid].threadName || 'Thread' + '(' + callChain.tid + ')';
let threadStateCallChain = new PerfCallChain(); //新增的线程状态数据
PerfCallChain.merageCallChain(threadStateCallChain, callChain);
- threadStateCallChain.name = callChain.threadState || 'Unkown State';
- threadStateCallChain.fileName = threadStateCallChain.name == '-' ? 'Unkown Thead State' : '';
+ threadStateCallChain.name = callChain.threadState || 'Unknown State';
+ threadStateCallChain.fileName = threadStateCallChain.name == '-' ? 'Unknown Thread State' : '';
threadStateCallChain.canCharge = false;
this.addPerfGroupData(threadCallChain);
this.addPerfGroupData(threadStateCallChain);
@@ -285,7 +283,7 @@ from (select callchain_id, s.thread_id, thread_state, process_id, count(callchai
perfCall.depth = this.callChainData[callChain.sampleId]?.length || 0;
perfCall.sampleId = callChain.sampleId;
perfCall.name = callChain.name;
- this.callChainMap.set(callChain.sampleId, perfCall);
+ this.dataCache.perfCallChainMap.set(callChain.sampleId, perfCall);
}
addPerfGroupData(callChain: PerfCallChain) {
@@ -569,8 +567,8 @@ from (select callchain_id, s.thread_id, thread_state, process_id, count(callchai
hideSystemLibrary() {
this.allProcess.forEach((item) => {
item.children = [];
- this.recursionChargeByRule(item, this.systmeRuleName, (node) => {
- return node.path.startsWith(this.systmeRuleName);
+ this.recursionChargeByRule(item, systemRuleName, (node) => {
+ return node.path.startsWith(systemRuleName);
});
});
}
@@ -579,7 +577,7 @@ from (select callchain_id, s.thread_id, thread_state, process_id, count(callchai
let max = endNum == '∞' ? Number.POSITIVE_INFINITY : parseInt(endNum);
this.allProcess.forEach((item) => {
item.children = [];
- this.recursionChargeByRule(item, this.numRuleName, (node) => {
+ this.recursionChargeByRule(item, numRuleName, (node) => {
return node.dur < startNum || node.dur > max;
});
});
@@ -878,7 +876,7 @@ export class PerfCallChainMerageData extends ChartStruct {
set total(data: number) {
this.#total = data;
- this.weight = `${timeMsFormat2p(this.dur * (ProcedureLogicWorkerPerf.cmdLineResult?.fValue || 1))}`;
+ this.weight = `${timeMsFormat2p(this.dur * (DataCache.getInstance().perfCountToMs || 1))}`;
this.weightPercent = `${((this.dur / data) * 100).toFixed(1)}%`;
}
@@ -893,9 +891,7 @@ export class PerfCallChainMerageData extends ChartStruct {
currentNode.pid = callChain.pid;
currentNode.tid = callChain.tid;
currentNode.libName = callChain.fileName;
- currentNode.lib = callChain.fileName;
currentNode.vaddrInFile = callChain.vaddrInFile;
- currentNode.addr = '0x' + callChain.vaddrInFile.toString(16);
currentNode.canCharge = callChain.canCharge;
if (callChain.path) {
currentNode.path = callChain.path;
@@ -903,7 +899,7 @@ export class PerfCallChainMerageData extends ChartStruct {
}
if (callChain[isTopDown ? 'nextNode' : 'previousNode'] == undefined) {
currentNode.selfDur += callChain.count;
- currentNode.self = timeMsFormat2p(currentNode.selfDur * (ProcedureLogicWorkerPerf.cmdLineResult?.fValue || 1));
+ currentNode.self = timeMsFormat2p(currentNode.selfDur * (DataCache.getInstance().perfCountToMs || 1));
}
currentNode.dur += callChain.count;
currentNode.count += callChain.count;
@@ -920,9 +916,8 @@ export class PerfCallChainMerageData extends ChartStruct {
currentNode.symbolName = callChain.name;
currentNode.pid = sample.pid;
currentNode.tid = sample.tid;
- currentNode.libName = currentNode.lib = callChain.fileName;
+ currentNode.libName = callChain.fileName;
currentNode.vaddrInFile = callChain.vaddrInFile;
- currentNode.addr = '0x' + currentNode.vaddrInFile.toString(16);
currentNode.canCharge = callChain.canCharge;
if (callChain.path) {
currentNode.path = callChain.path;
@@ -930,7 +925,7 @@ export class PerfCallChainMerageData extends ChartStruct {
}
if (isEnd) {
currentNode.selfDur += sample.count;
- currentNode.self = timeMsFormat2p(currentNode.selfDur * (ProcedureLogicWorkerPerf.cmdLineResult?.fValue || 1));
+ currentNode.self = timeMsFormat2p(currentNode.selfDur * (DataCache.getInstance().perfCountToMs || 1));
}
currentNode.dur += sample.count;
currentNode.count += sample.count;
@@ -958,11 +953,6 @@ export class PerfCmdLine {
report_value: string = '';
}
-export class PerfCall {
- sampleId: number = 0;
- depth: number = 0;
- name: string = '';
-}
class PerfAnalysisSample extends PerfCountSample {
threadName: string;
diff --git a/ide/src/trace/database/ui-worker/ProcedureWorker.ts b/ide/src/trace/database/ui-worker/ProcedureWorker.ts
index eb49ae522dc282de3269e1ff83fd13dd39385296..7d0814d2f30b4949b0a32fd0b603618b6896dcda 100644
--- a/ide/src/trace/database/ui-worker/ProcedureWorker.ts
+++ b/ide/src/trace/database/ui-worker/ProcedureWorker.ts
@@ -49,6 +49,8 @@ import { JankRender } from './ProcedureWorkerJank.js';
import { HeapTimelineRender } from './ProcedureWorkerHeapTimeline.js';
import { HeapSnapshotRender } from './ProcedureWorkerHeapSnapshot.js';
import { translateJsonString } from '../logic-worker/ProcedureLogicWorkerCommon.js';
+import { AppStartupRender } from './ProcedureWorkerAppStartup.js';
+import { SoRender } from './ProcedureWorkerSoInit.js';
let dataList: any = {};
let dataList2: any = {};
@@ -67,6 +69,8 @@ export let renders: any = {
'file-system-group': new EmptyRender(),
'file-system-cell': new FileSystemRender(),
process: new ProcessRender(),
+ 'app-start-up': new AppStartupRender(),
+ 'app-so-init': new SoRender(),
heap: new HeapRender(),
heapTimeline: new HeapTimelineRender(),
heapSnapshot: new HeapSnapshotRender(),
diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerAppStartup.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerAppStartup.ts
new file mode 100644
index 0000000000000000000000000000000000000000..00733774023d519602469ab79b64f139b093487e
--- /dev/null
+++ b/ide/src/trace/database/ui-worker/ProcedureWorkerAppStartup.ts
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ BaseStruct,
+ dataFilterHandler, drawString,
+ ns2x,
+} from './ProcedureWorkerCommon.js';
+import { TraceRow } from '../../component/trace/base/TraceRow.js';
+import { ColorUtils } from '../../component/trace/base/ColorUtils.js';
+
+export class AppStartupRender {
+ renderMainThread(
+ req: {
+ useCache: boolean;
+ context: CanvasRenderingContext2D;
+ type: string;
+ },
+ row: TraceRow
+ ) {
+ let list = row.dataList;
+ let filter = row.dataListCache;
+ dataFilterHandler(list, filter, {
+ startKey: 'startTs',
+ durKey: 'dur',
+ startNS: TraceRow.range?.startNS ?? 0,
+ endNS: TraceRow.range?.endNS ?? 0,
+ totalNS: TraceRow.range?.totalNS ?? 0,
+ frame: row.frame,
+ paddingTop: 5,
+ useCache: req.useCache || !(TraceRow.range?.refresh ?? false),
+ });
+ req.context.font = '11px sans-serif';
+ req.context.globalAlpha = 0.6;
+ let find = false;
+ let offset = 3;
+ for (let re of filter) {
+ AppStartupStruct.draw(req.context, re);
+ if (row.isHover) {
+ if (re.frame && row.hoverX >= re.frame.x - offset && row.hoverX <= re.frame.x + re.frame.width + offset) {
+ AppStartupStruct.hoverStartupStruct = re;
+ find = true;
+ }
+ }
+ }
+ if (!find && row.isHover) AppStartupStruct.hoverStartupStruct = undefined;
+ }
+
+}
+const padding = 3;
+
+export class AppStartupStruct extends BaseStruct {
+ static hoverStartupStruct: AppStartupStruct | undefined;
+ static selectStartupStruct: AppStartupStruct | undefined;
+ static StartUpStep: string[] = [
+ 'Process Creating',
+ 'Application Launching',
+ 'UI Ability Launching',
+ 'UI Ability OnForeground',
+ 'First Frame - APP Phase',
+ 'First Frame - Render Phase'
+ ]
+ dur: number | undefined;
+ value: string | undefined;
+ startTs: number | undefined;
+ pid: number | undefined;
+ process: string | undefined;
+ itid: number | undefined;
+ endItid: number | undefined;
+ tid: number | undefined;
+ startName: number | undefined;
+
+ static draw(ctx: CanvasRenderingContext2D, data: AppStartupStruct) {
+ if (data.frame) {
+ ctx.globalAlpha = 1.0;
+ ctx.fillStyle = ColorUtils.colorForTid(data.startName!);
+ ctx.fillRect(data.frame.x, data.frame.y, data.frame.width, data.frame.height);
+ if(data.frame.width > 7) {
+ ctx.fillStyle = '#fff';
+ ctx.textBaseline = 'middle';
+ ctx.font = '8px sans-serif';
+ drawString(ctx, AppStartupStruct.getStartupName(data.startName), 2, data.frame, data);
+ }
+ if (data === AppStartupStruct.selectStartupStruct) {
+ ctx.strokeStyle = '#232c5d';
+ ctx.lineWidth = 2;
+ ctx.strokeRect(
+ data.frame.x,
+ data.frame.y,
+ data.frame.width,
+ data.frame.height
+ );
+ }
+ }
+ }
+
+ static getStartupName(step: number | undefined) {
+ if (step === undefined || step < 0 || step > 5) {
+ return 'Unknown Start Step';
+ } else {
+ return AppStartupStruct.StartUpStep[step];
+ }
+ }
+
+}
diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts
index c4e8602d6374f15d43b11c4034bda66db90acb65..38fbfb86cee6be58739839b12729875d7c27a479 100644
--- a/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts
+++ b/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts
@@ -16,7 +16,6 @@
import { CpuStruct, WakeupBean } from './ProcedureWorkerCPU.js';
import { TraceRow } from '../../component/trace/base/TraceRow.js';
import { TimerShaftElement } from '../../component/trace/TimerShaftElement';
-import { TimeRange } from '../../component/trace/timer-shaft/RangeRuler';
export abstract class Render {
abstract renderMainThread(req: any, row: TraceRow): void;
diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerMem.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerMem.ts
index 0b259a87a391492fd2adfa84365929d64641c1b3..783afe8f9e397ef6b66a3c9ea8d9d1fef3a65c7a 100644
--- a/ide/src/trace/database/ui-worker/ProcedureWorkerMem.ts
+++ b/ide/src/trace/database/ui-worker/ProcedureWorkerMem.ts
@@ -173,9 +173,11 @@ export class ProcessMemStruct extends BaseProcessMemStruct {
let drawHeight: number = ((data.value || 0) * (data.frame.height || 0) * 1.0) / (data.maxValue || 1);
drawHeight = drawHeight > 0 ? drawHeight : 1;
memContext.fillRect(data.frame.x, data.frame.y + data.frame.height - drawHeight, width, drawHeight);
- memContext.lineWidth = 1;
- memContext.globalAlpha = 1.0;
- memContext.strokeRect(data.frame.x, data.frame.y + data.frame.height - drawHeight, width, drawHeight);
+ if (width > 2) {
+ memContext.lineWidth = 1;
+ memContext.globalAlpha = 1.0;
+ memContext.strokeRect(data.frame.x, data.frame.y + data.frame.height - drawHeight, width, drawHeight);
+ }
}
}
memContext.globalAlpha = 1.0;
diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerSoInit.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerSoInit.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a4ace1d7424a6c4b5d90fb1d1dfc51c20a54df6b
--- /dev/null
+++ b/ide/src/trace/database/ui-worker/ProcedureWorkerSoInit.ts
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { ColorUtils } from '../../component/trace/base/ColorUtils.js';
+import { TraceRow } from '../../component/trace/base/TraceRow.js';
+import {
+ BaseStruct,
+ isFrameContainPoint,
+ ns2x,
+ Render,
+ RequestMessage,
+ drawString,
+} from './ProcedureWorkerCommon.js';
+export class SoRender extends Render {
+ renderMainThread(
+ req: {
+ useCache: boolean;
+ context: CanvasRenderingContext2D;
+ type: string;
+ },
+ row: TraceRow
+ ) {
+ let soList = row.dataList;
+ let soFilter = row.dataListCache;
+ soDataFilter(
+ soList,
+ soFilter,
+ TraceRow.range!.startNS,
+ TraceRow.range!.endNS,
+ TraceRow.range!.totalNS,
+ row.frame,
+ req.useCache || !TraceRow.range!.refresh
+ );
+ req.context.beginPath();
+ let soFind = false;
+ for (let so of soFilter) {
+ SoStruct.draw(req.context, so);
+ if (row.isHover) {
+ if (so.dur === 0 || so.dur === null || so.dur === undefined) {
+ if (
+ so.frame &&
+ row.hoverX >= so.frame.x - 5 &&
+ row.hoverX <= so.frame.x + 5 &&
+ row.hoverY >= so.frame.y &&
+ row.hoverY <= so.frame.y + so.frame.height
+ ) {
+ SoStruct.hoverSoStruct = so;
+ soFind = true;
+ }
+ } else {
+ if (so.frame && isFrameContainPoint(so.frame, row.hoverX, row.hoverY)) {
+ SoStruct.hoverSoStruct = so;
+ soFind = true;
+ }
+ }
+ }
+ }
+ if (!soFind && row.isHover) SoStruct.hoverSoStruct = undefined;
+ req.context.closePath();
+ }
+
+ render(req: RequestMessage, list: Array, filter: Array) {}
+}
+
+export function soDataFilter(
+ soList: Array,
+ soFilter: Array,
+ startNS: number,
+ endNS: number,
+ totalNS: number,
+ frame: any,
+ use: boolean
+) {
+ if (use && soFilter.length > 0) {
+ for (let i = 0, len = soFilter.length; i < len; i++) {
+ if ((soFilter[i].startTs || 0) + (soFilter[i].dur || 0) >= startNS && (soFilter[i].startTs || 0) <= endNS) {
+ SoStruct.setSoFrame(soFilter[i], 0, startNS, endNS, totalNS, frame);
+ } else {
+ soFilter[i].frame = undefined;
+ }
+ }
+ return;
+ }
+ soFilter.length = 0;
+ if (soList) {
+ let groups = soList
+ .filter((it) => (it.startTs ?? 0) + (it.dur ?? 0) >= startNS && (it.startTs ?? 0) <= endNS)
+ .map((it) => {
+ SoStruct.setSoFrame(it, 0, startNS, endNS, totalNS, frame);
+ return it;
+ })
+ .reduce((pre: any, current, index, arr) => {
+ if(current.frame) {
+ (pre[`${current.frame.x}-${current.depth}`] = pre[`${current.frame.x}-${current.depth}`] || []).push(current);
+ }
+ return pre;
+ }, {});
+ Reflect.ownKeys(groups).map((kv) => {
+ let arr = groups[kv].sort((a: any, b: any) => b.dur - a.dur);
+ soFilter.push(arr[0]);
+ });
+ }
+}
+
+export class SoStruct extends BaseStruct{
+ static hoverSoStruct: SoStruct | undefined;
+ static selectSoStruct: SoStruct | undefined;
+ textMetricsWidth: number | undefined;
+ depth: number | undefined;
+ dur: number | undefined;
+ soName: string | undefined;
+ process: string | undefined;
+ startTs: number | undefined;
+ tid: number | undefined;
+ pid: number | undefined;
+ itid: number | undefined;
+
+ static setSoFrame(soNode: any, padding: number, startNS: number, endNS: number, totalNS: number, frame: any) {
+ let x1: number, x2: number;
+ if ((soNode.startTs || 0) > startNS && (soNode.startTs || 0) < endNS) {
+ x1 = ns2x(soNode.startTs || 0, startNS, endNS, totalNS, frame);
+ } else {
+ x1 = 0;
+ }
+ if (
+ (soNode.startTs || 0) + (soNode.dur || 0) > startNS &&
+ (soNode.startTs || 0) + (soNode.dur || 0) < endNS
+ ) {
+ x2 = ns2x((soNode.startTs || 0) + (soNode.dur || 0), startNS, endNS, totalNS, frame);
+ } else {
+ x2 = frame.width;
+ }
+ if (!soNode.frame) {
+ soNode.frame = {};
+ }
+ let getV: number = x2 - x1 < 1 ? 1 : x2 - x1;
+ soNode.frame.x = Math.floor(x1);
+ soNode.frame.y = soNode.depth * 20;
+ soNode.frame.width = Math.ceil(getV);
+ soNode.frame.height = 20;
+ }
+
+ static draw(ctx: CanvasRenderingContext2D, data: SoStruct) {
+ if (data.frame) {
+ if (data.dur === undefined || data.dur === null) {
+ } else {
+ ctx.globalAlpha = 1;
+ ctx.fillStyle = ColorUtils.FUNC_COLOR[ColorUtils.hashFunc(data.soName || '', 0, ColorUtils.FUNC_COLOR.length)];
+ let textColor = ColorUtils.FUNC_COLOR[ColorUtils.hashFunc(data.soName || '', 0, ColorUtils.FUNC_COLOR.length)];
+ let miniHeight = 20;
+ if (SoStruct.hoverSoStruct && data.soName == SoStruct.hoverSoStruct.soName) {
+ ctx.globalAlpha = 0.7;
+ }
+ ctx.fillRect(data.frame.x, data.frame.y, data.frame.width, miniHeight - padding * 2);
+ if (data.frame.width > 10) {
+ ctx.strokeStyle = '#fff';
+ ctx.lineWidth = 1;
+ ctx.strokeRect(data.frame.x, data.frame.y, data.frame.width, miniHeight - padding * 2);
+ ctx.fillStyle = ColorUtils.funcTextColor(textColor);
+ drawString(ctx, `${data.soName || ''}`, 5, data.frame, data);
+ }
+ if (data === SoStruct.selectSoStruct) {
+ ctx.strokeStyle = '#000';
+ ctx.lineWidth = 2;
+ ctx.strokeRect(data.frame.x, data.frame.y + 1, data.frame.width, miniHeight - padding * 2 - 2);
+ }
+ }
+ }
+ }
+
+}
+
+const padding = 1;
diff --git a/patches/productdefine_common.patch b/patches/productdefine_common.patch
index 9f500678525ef7b97a29ad01c1c0457341f6bb7c..07797381d6d2b534657cdada6b943bca83a654de 100644
--- a/patches/productdefine_common.patch
+++ b/patches/productdefine_common.patch
@@ -1,83 +1,92 @@
+From 130403fa56b6ac2dba0e86abe6ddf81bfcf0fda0 Mon Sep 17 00:00:00 2001
+From: jichuan
+Date: Wed, 12 Jul 2023 14:16:41 +0800
+Subject: [PATCH] patch
+
+Signed-off-by: jichuan
+---
+ inherit/default.json | 4 ++++
+ inherit/ipcamera.json | 4 ++++
+ inherit/pc.json | 4 ++++
+ inherit/rich.json | 4 ++++
+ inherit/tablet.json | 4 ++++
+ 5 files changed, 20 insertions(+)
+
diff --git a/inherit/default.json b/inherit/default.json
-index 3621e9e..d894aae 100644
+index 3621e9e..df2b902 100644
--- a/inherit/default.json
+++ b/inherit/default.json
-@@ -461,7 +461,11 @@
- {
- "component": "packing_tool",
- "features": []
-- }
-+ },
-+ {
-+ "component": "smartperf_host",
-+ "features": []
-+ }
- ]
- },
- {
+@@ -454,6 +454,10 @@
+ "component": "hiperf",
+ "features": []
+ },
++ {
++ "component": "smartperf_host",
++ "features": []
++ },
+ {
+ "component": "syscap_codec",
+ "features": []
diff --git a/inherit/ipcamera.json b/inherit/ipcamera.json
-index 4075a32..e74bfbc 100644
+index 88562be..ab81e60 100644
--- a/inherit/ipcamera.json
+++ b/inherit/ipcamera.json
-@@ -449,6 +449,10 @@
- {
- "component": "hiperf",
- "features": []
-+ },
-+ {
-+ "component": "smartperf_host",
-+ "features": []
- }
- ]
- },
+@@ -455,6 +455,10 @@
+ {
+ "component": "hiperf",
+ "features": []
++ },
++ {
++ "component": "smartperf_host",
++ "features": []
+ }
+ ]
+ },
diff --git a/inherit/pc.json b/inherit/pc.json
-index 89392c5..fffd9e9 100644
+index 89392c5..c25f665 100644
--- a/inherit/pc.json
+++ b/inherit/pc.json
-@@ -461,7 +461,11 @@
- {
- "component": "packing_tool",
- "features": []
-- }
-+ },
-+ {
-+ "component": "smartperf_host",
-+ "features": []
-+ }
- ]
- },
- {
+@@ -454,6 +454,10 @@
+ "component": "hiperf",
+ "features": []
+ },
++ {
++ "component": "smartperf_host",
++ "features": []
++ },
+ {
+ "component": "syscap_codec",
+ "features": []
diff --git a/inherit/rich.json b/inherit/rich.json
-index 5013860..09cce24 100644
+index 7277257..a80b9e2 100644
--- a/inherit/rich.json
+++ b/inherit/rich.json
-@@ -469,7 +469,11 @@
- {
- "component": "packing_tool",
- "features": []
-- }
-+ },
+@@ -464,6 +464,10 @@
+ "component": "hiperf",
+ "features": []
+ },
+ {
-+ "component": "smartperf_host",
-+ "features": []
-+ }
- ]
- },
- {
++ "component": "smartperf_host",
++ "features": []
++ },
+ {
+ "component": "syscap_codec",
+ "features": []
diff --git a/inherit/tablet.json b/inherit/tablet.json
-index 1e0e322..4281d5f 100644
+index 1e0e322..c6ad521 100644
--- a/inherit/tablet.json
+++ b/inherit/tablet.json
-@@ -428,7 +428,11 @@
- {
- "component": "packing_tool",
- "features": []
-- }
-+ },
-+ {
-+ "component": "smartperf_host",
-+ "features": []
-+ }
- ]
- },
- {
+@@ -421,6 +421,10 @@
+ "component": "hiperf",
+ "features": []
+ },
++ {
++ "component": "smartperf_host",
++ "features": []
++ },
+ {
+ "component": "syscap_codec",
+ "features": []
+--
+2.34.1
+
diff --git a/trace_streamer/BUILD.gn b/trace_streamer/BUILD.gn
old mode 100755
new mode 100644
index 7190e798ba3499128ea677810bcdb386b7e60c84..e1328b00628536f9d5dbf61c4e67089336b9ca0a
--- a/trace_streamer/BUILD.gn
+++ b/trace_streamer/BUILD.gn
@@ -10,28 +10,33 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-import("//build/ohos.gni")
+if (target_os == "ohos") {
+ import("//build/ohos.gni")
+} else {
+ import("build/ts.gni")
+}
-ohos_executable("trace_streamer") {
- cflags = [ "-D COMPILE_WITH_OHOS" ]
- sources = [ "src/main.cpp" ]
- include_dirs = [
- "src/base",
- "./",
- "src/trace_streamer",
- "src/filter",
- "src/table",
- "src/trace_data",
- "src/include",
- "src/rpc",
- "src/",
- "src/parser",
- "src/cfg",
- "src/proto_reader/include",
- "//third_party/sqlite/include",
- "//third_party/json-master/single_include/nlohmann",
- "//third_party/json/single_include/nlohmann",
- "//third_party/protobuf/src",
- "//third_party/hiperf/include",
- ]
+group("trace_streamer") {
+ if (target_os == "ohos") {
+ } else if (is_test) {
+ deps = [ "test:unittest" ]
+ testonly = true
+ } else if (is_fuzz) {
+ deps = [ "test:fuzztest" ]
+ testonly = true
+ } else if (is_protoc) {
+ deps = [ "${THIRD_PARTY}/protobuf:protoc" ]
+ } else if (is_spb) {
+ deps = [ "src/proto_reader/protoc_plugin:protoreader_plugin" ]
+ } else if (is_sdkdemo) {
+ deps = [ "sdk/demo_sdk:trace_streamer_sdk_builtin" ]
+ } else if (is_dubai_sdk) {
+ deps = [ "sdk/dubai_sdk:trace_streamer_dubai_builtin" ]
+ } else if (is_sdkdemo_test) {
+ deps = [ "sdk/test:sdkunittest" ]
+ } else if (use_wasm) {
+ deps = [ "src:trace_streamer_builtin" ]
+ } else {
+ deps = [ "src:trace_streamer" ]
+ }
}
diff --git a/trace_streamer/build.sh b/trace_streamer/build.sh
index 7f00ce90086f970216a59eed2f7be490821943cb..e1cb2f2abd8541dc52739e6f51ac62da334214a6 100755
--- a/trace_streamer/build.sh
+++ b/trace_streamer/build.sh
@@ -17,7 +17,6 @@ echo $PARAMS
echo "begin to check input"
SOURCE="${BASH_SOURCE[0]}"
cd $(dirname ${SOURCE})
-./clean.sh
./pare_third_party.sh
target_os="linux"
target_dir="linux"
diff --git a/trace_streamer/build/protoc_w.sh b/trace_streamer/build/protoc_w.sh
index ebc7a8adecb958b818fa1c255fdc0828da45de03..6b1f6e26f84ebcbde0bcd83d38efe27c20454df7 100644
--- a/trace_streamer/build/protoc_w.sh
+++ b/trace_streamer/build/protoc_w.sh
@@ -1,4 +1,4 @@
-# Copyright (c) 2023 Huawei Device Co., Ltd.
+# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
diff --git a/trace_streamer/clean.sh b/trace_streamer/clean.sh
deleted file mode 100755
index 8d19257074231abc59d646cf1eca08e721af33e6..0000000000000000000000000000000000000000
--- a/trace_streamer/clean.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2023 Huawei Device Co., Ltd.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-set -e
-
-if [ -d "third_party" ];then
- rm -rf third_party
-fi
\ No newline at end of file
diff --git a/trace_streamer/doc/des_tables.md b/trace_streamer/doc/des_tables.md
index 5880abd51104485f85065d4e3ca812846f72d825..8d8a2ec15e2aa770ed2d68d7d06afc52cf5f1c90 100755
--- a/trace_streamer/doc/des_tables.md
+++ b/trace_streamer/doc/des_tables.md
@@ -1362,17 +1362,24 @@ js_heap_sample:记录timeline的时间轴信息
- state:线程实际的的状态值
```
'R', Runnable状态
-'S', interruptible sleep
-'D', uninterruptible sleep
-'T', Stoped
-'t', Traced
-'X', ExitedDead
-'Z', ExitZombie
-'x', TaskDead
-'I', TaskDead
-'K', WakeKill
-'P', Parked
-'N', NoLoad
+"S", interruptible sleep
+"D", uninterruptible sleep
+"D-IO", uninterruptible io
+"D-NIO", uninterruptible nio
+"Runing", Runing状态
+"I", interrupted
+"T", Traced
+"X", ExitedDead
+"Z", Zombie
+"I", CloneThread
+"I", TaskKilled
+"DK",
+"DK-IO",
+"DK-NIO",
+"TK", TracedKill
+"R", WakeKill
+"P", Parked
+"R+", ForeGround
```
### clock_snapshot表
diff --git a/trace_streamer/gn/toolchain/BUILD.gn b/trace_streamer/gn/toolchain/BUILD.gn
index 37f5bc3d01272d238493b786cb65d93443e36f10..3b31509464aa0660a9b73a9d08b4865bff5d292d 100755
--- a/trace_streamer/gn/toolchain/BUILD.gn
+++ b/trace_streamer/gn/toolchain/BUILD.gn
@@ -14,12 +14,12 @@
import("//gn/wasm.gni")
declare_args() {
if (target_os == "linux" || target_os == "macx") {
- cc = "clang"
- cxx = "clang++"
+ cc = "/usr/bin/clang"
+ cxx = "/usr/bin/clang++"
pic = "-fPIC"
rebuild_string = ""
extra_asmflags = ""
- asm = "clang"
+ asm = "/usr/bin/clang"
} else if (target_os == "windows") {
cc = "gcc.exe"
cxx = "g++.exe"
diff --git a/trace_streamer/pare_third_party.sh b/trace_streamer/pare_third_party.sh
index 830e8fe7a438d52a575be07ee2d8816f5f68839c..3d8852ad2e51d12d01a2bb2fadc2c2013220800c 100755
--- a/trace_streamer/pare_third_party.sh
+++ b/trace_streamer/pare_third_party.sh
@@ -26,7 +26,7 @@ cd third_party
if [ ! -f "sqlite/BUILD.gn" ];then
rm -rf sqlite
- git clone https://gitee.com/openharmony/third_party_sqlite.git
+ git clone git@gitee.com:openharmony/third_party_sqlite.git
if [ -d "third_party_sqlite" ];then
mv third_party_sqlite sqlite
$cp ../prebuilts/patch_sqlite/sqlite3build.gn ../third_party/sqlite/BUILD.gn
@@ -34,7 +34,7 @@ if [ ! -f "sqlite/BUILD.gn" ];then
fi
if [ ! -f "protobuf/BUILD.gn" ];then
rm -rf protobuf
- git clone https://gitee.com/openharmony/third_party_protobuf.git
+ git clone git@gitee.com:openharmony/third_party_protobuf.git
if [ -d "third_party_protobuf" ];then
mv third_party_protobuf protobuf
$cp ../prebuilts/patch_protobuf/protobufbuild.gn ../third_party/protobuf/BUILD.gn
@@ -43,7 +43,7 @@ fi
if [ ! -f "googletest/BUILD.gn" ];then
rm -rf googletest
- git clone https://gitee.com/openharmony/third_party_googletest.git
+ git clone git@gitee.com:openharmony/third_party_googletest.git
if [ -d "third_party_googletest" ];then
mv third_party_googletest googletest
$cp ../prebuilts/patch_googletest/googletestbuild.gn ../third_party/googletest/BUILD.gn
@@ -56,7 +56,7 @@ fi
if [ ! -f "json-master/BUILD.gn" ];then
rm -rf json-master
- git clone https://gitee.com/openharmony/third_party_json.git
+ git clone git@gitee.com:openharmony/third_party_json.git
if [ -d "third_party_json" ];then
mv third_party_json json-master
fi
@@ -64,7 +64,7 @@ fi
if [ ! -f "libunwind/BUILD.gn" ];then
rm -rf libunwind
- git clone https://gitee.com/openharmony/third_party_libunwind.git
+ git clone git@gitee.com:openharmony/third_party_libunwind.git
if [ -d "third_party_libunwind" ];then
mv third_party_libunwind libunwind
$cp ../prebuilts/patch_libunwind/libunwindbuild.gn libunwind/BUILD.gn
@@ -88,7 +88,7 @@ fi
if [ ! -f "hiperf/BUILD.gn" ];then
rm -rf hiperf developtools_hiperf
- git clone -b OpenHarmony-3.2-Release --depth=1 https://gitee.com/openharmony/developtools_hiperf.git
+ git clone -b OpenHarmony-3.2-Release --depth=1 git@gitee.com:openharmony/developtools_hiperf.git
if [ -d "developtools_hiperf" ];then
mv developtools_hiperf hiperf
$cp ../prebuilts/patch_hiperf/BUILD.gn ../third_party/hiperf/BUILD.gn
diff --git a/trace_streamer/src/base/string_help.cpp b/trace_streamer/src/base/string_help.cpp
index fbe232fc4dfd2a868a0f35fa80d2610d49dbdb24..bff7b7c811e379136c9f96cc2e9cca4d5f22ac7a 100644
--- a/trace_streamer/src/base/string_help.cpp
+++ b/trace_streamer/src/base/string_help.cpp
@@ -112,6 +112,14 @@ int GetProcessorNumFromString(char* str)
return processorNum;
}
+bool StartWith(const std::string& str, const std::string& res)
+{
+ if (res.size() > str.size()) {
+ return false;
+ }
+ return str.compare(0, res.length(), res) == 0;
+}
+
bool EndWith(const std::string& str, const std::string& res)
{
if (res.size() > str.size()) {
diff --git a/trace_streamer/src/base/string_help.h b/trace_streamer/src/base/string_help.h
index 51dfb2285bd723df2b90d809512ae236f344682d..7ac011ecd5df7cd51a61af5cbf907c38f30bc64f 100644
--- a/trace_streamer/src/base/string_help.h
+++ b/trace_streamer/src/base/string_help.h
@@ -31,6 +31,7 @@ int32_t snprintf_s(char* strDest, size_t destMax, size_t count, const char* form
const char* GetDemangleSymbolIndex(const char* mangled);
int GetProcessorNumFromString(char* str);
std::vector SplitStringToVec(const std::string& str, const std::string& pat);
+bool StartWith(const std::string& str, const std::string& res);
bool EndWith(const std::string& str, const std::string& res);
#endif // SRC_TRACE_BASE_STRINGHELP_H
diff --git a/trace_streamer/src/filter/BUILD.gn b/trace_streamer/src/filter/BUILD.gn
index 6162f0f921647582906abc3ccfdf59cb4cd04e5a..2a4a2aa9e99ace654a9c01f5f25516bb93b1a338 100644
--- a/trace_streamer/src/filter/BUILD.gn
+++ b/trace_streamer/src/filter/BUILD.gn
@@ -18,6 +18,8 @@ ohos_source_set("filter") {
subsystem_name = "trace_streamer"
part_name = "trace_streamer_filter"
sources = [
+ "app_start_filter.cpp",
+ "app_start_filter.h",
"args_filter.cpp",
"args_filter.h",
"binder_filter.cpp",
diff --git a/trace_streamer/src/filter/app_start_filter.cpp b/trace_streamer/src/filter/app_start_filter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b8b8928e39d87ab08a284b542a14f4472d20325c
--- /dev/null
+++ b/trace_streamer/src/filter/app_start_filter.cpp
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "app_start_filter.h"
+#include "string_help.h"
+
+namespace SysTuning {
+namespace TraceStreamer {
+APPStartupFilter::APPStartupFilter(TraceDataCache* dataCache, const TraceStreamerFilters* filter)
+ : FilterBase(dataCache, filter), mAPPStartupData_(0)
+{
+}
+
+APPStartupFilter::~APPStartupFilter() = default;
+
+void APPStartupFilter::FilterAllAPPStartupData()
+{
+ ParserAppStartup();
+ ParserSoInitalization();
+}
+
+bool APPStartupFilter::GetProcessCreate(uint32_t row, uint64_t& startTime, std::string nameString)
+{
+ auto sliceData = traceDataCache_->GetConstInternalSlicesData();
+ auto parentId = sliceData.ParentIdData()[row].value();
+ auto depth = sliceData.Depths()[row];
+ auto name = traceDataCache_->GetDataFromDict(sliceData.NamesData()[parentId]);
+ while (depth--) {
+ if (StartWith(name, nameString)) {
+ startTime = sliceData.TimeStampData()[parentId];
+ return true;
+ }
+ parentId = sliceData.ParentIdData()[parentId].value();
+ name = traceDataCache_->GetDataFromDict(sliceData.NamesData()[parentId]);
+ }
+ return false;
+}
+
+bool APPStartupFilter::CaclRsDataByPid()
+{
+ auto frameSliceData = traceDataCache_->GetFrameSliceData();
+ auto sliceData = traceDataCache_->GetConstInternalSlicesData();
+ auto itor = mAPPStartupData_.begin();
+ for (const auto& item : mAPPStartupData_) {
+ if (item.second.empty()) {
+ continue;
+ }
+ auto itorSecond = item.second.begin();
+ auto dataIndex = item.first;
+ if (itorSecond->second->ipid_ != INVALID_UINT32) {
+ for (int m = 0; m < frameSliceData->Ipids().size(); m++) {
+ if (itorSecond->second->ipid_ == frameSliceData->Ipids()[m] && !frameSliceData->Types()[m] &&
+ frameSliceData->Flags()[m] != INVAILD_DATA) {
+ auto startTime = sliceData.TimeStampData()[frameSliceData->CallStackIds()[m]];
+ auto callId = sliceData.CallIds()[frameSliceData->CallStackIds()[m]];
+ auto endTime = startTime + frameSliceData->Durs()[m];
+ mAPPStartupData_[dataIndex].emplace(
+ FIRST_FRAME_APP_PHASE,
+ std::move(std::make_unique(callId, itorSecond->second->ipid_,
+ itorSecond->second->tid_, startTime, endTime)));
+ auto dstId = frameSliceData->Dsts()[m];
+ if (dstId == INVALID_UINT64) {
+ continue;
+ }
+ callId = sliceData.CallIds()[frameSliceData->CallStackIds()[dstId]];
+ startTime = frameSliceData->TimeStampData()[dstId];
+ endTime = startTime + frameSliceData->Durs()[dstId];
+ mAPPStartupData_[dataIndex].emplace(
+ FIRST_FRAME_RENDER_PHASE,
+ std::move(std::make_unique(callId, itorSecond->second->ipid_,
+ itorSecond->second->tid_, startTime, endTime)));
+ break;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+void APPStartupFilter::UpdatePidByNameIndex()
+{
+ auto threadData = traceDataCache_->GetConstThreadData();
+ for (const auto& item : mAPPStartupData_) {
+ auto ipid = INVALID_UINT32;
+ auto tid = INVALID_UINT32;
+ if (item.second.count(UI_ABILITY_ONFOREGROUND)) {
+ ipid = item.second.at(UI_ABILITY_ONFOREGROUND)->ipid_;
+ tid = item.second.at(UI_ABILITY_ONFOREGROUND)->tid_;
+ } else {
+ for (int i = 0; i < threadData.size(); ++i) {
+ if (item.first == threadData[i].nameIndex_) {
+ ipid = threadData[i].internalPid_;
+ tid = threadData[i].tid_;
+ }
+ }
+ }
+ for (const auto& itemSecond : item.second) {
+ itemSecond.second->ipid_ = ipid;
+ itemSecond.second->tid_ = tid;
+ }
+ }
+}
+
+void APPStartupFilter::AppendData()
+{
+ for (auto itor = mAPPStartupData_.begin(); itor != mAPPStartupData_.end(); ++itor) {
+ for (auto itorSecond = itor->second.begin(); itorSecond != itor->second.end(); ++itorSecond) {
+ auto item = itorSecond;
+ auto endTime = INVALID_UINT64;
+ if (item->first < VAILD_DATA_COUNT) {
+ int num = item->first + 1;
+ if ((++item) != itor->second.end() && num == item->first) {
+ endTime = (item)->second->startTime_;
+ }
+ } else {
+ endTime = itorSecond->second->endTime_;
+ }
+ traceDataCache_->GetAppStartupData()->AppendNewData(
+ itorSecond->second->ipid_, itorSecond->second->tid_, itorSecond->second->callid_,
+ itorSecond->second->startTime_, endTime, itorSecond->first, itor->first);
+ }
+ }
+}
+
+DataIndex APPStartupFilter::GetThreadNameAndUpdateAPPStartupData(uint32_t row,
+ const std::string& nameString,
+ uint32_t startIndex)
+{
+ auto sliceData = traceDataCache_->GetConstInternalSlicesData();
+ auto vNameString = SplitStringToVec(nameString, "##");
+ if (vNameString.size() < MIN_VECTOR_SIZE_) {
+ return INVALID_DATAINDEX;
+ }
+ auto dataIndex = traceDataCache_->GetDataIndex(vNameString[1].c_str());
+ auto callId = sliceData.CallIds()[row];
+ auto startTime = sliceData.TimeStampData()[row];
+ mAPPStartupData_[dataIndex].insert(
+ std::make_pair(startIndex, std::move(std::make_unique(callId, INVALID_UINT32, INVALID_UINT32,
+ startTime, INVALID_UINT64))));
+ return dataIndex;
+}
+
+void APPStartupFilter::ParserAppStartup()
+{
+ auto sliceData = traceDataCache_->GetConstInternalSlicesData();
+ std::string mainThreadName = "";
+ for (auto i = 0; i < sliceData.NamesData().size(); i++) {
+ auto callId = INVALID_UINT32;
+ uint64_t startTime = INVALID_UINT64;
+ std::string packedName = "";
+ auto& nameString = traceDataCache_->GetDataFromDict(sliceData.NamesData()[i]);
+ if (StartWith(nameString, PROCESS_CREATE)) {
+ auto vNameString = SplitStringToVec(nameString, "##");
+ if (vNameString.size() >= MIN_VECTOR_SIZE_) {
+ mainThreadName = vNameString[1];
+ }
+ if (!sliceData.ParentIdData()[i].has_value()) {
+ TS_LOGE("callstack data has no parentId");
+ return;
+ }
+ if (!GetProcessCreate(i, startTime, START_ABILITY)) {
+ continue;
+ }
+ callId = sliceData.CallIds()[i];
+ mAPPStartupData_[traceDataCache_->GetDataIndex(mainThreadName.c_str())].insert(std::make_pair(
+ PROCESS_CREATING, std::move(std::make_unique(callId, INVALID_UINT32, INVALID_UINT32,
+ startTime, INVALID_UINT64))));
+ } else if (StartWith(nameString, APP_LAUNCH)) {
+ GetThreadNameAndUpdateAPPStartupData(i, nameString, APPLICATION_LAUNCHING);
+ } else if (StartWith(nameString, LAUNCH)) {
+ auto nameIndex = GetThreadNameAndUpdateAPPStartupData(i, nameString, UI_ABILITY_LAUNCHING);
+ if (nameIndex != INVALID_DATAINDEX) {
+ auto thread = traceDataCache_->GetThreadData(sliceData.CallIds()[i]);
+ thread->nameIndex_ = nameIndex;
+ }
+ } else if (StartWith(nameString, ONFOREGROUND)) {
+ // callid is thread table->itid
+ callId = sliceData.CallIds()[i];
+ startTime = sliceData.TimeStampData()[i];
+ auto threadData = traceDataCache_->GetConstThreadData();
+ auto nameindex = threadData[callId].nameIndex_;
+ auto ipid = threadData[callId].internalPid_;
+ auto tid = threadData[callId].tid_;
+ mAPPStartupData_[nameindex].insert(std::make_pair(
+ UI_ABILITY_ONFOREGROUND,
+ std::move(std::make_unique(callId, ipid, tid, startTime, INVALID_UINT64))));
+ }
+ }
+ UpdatePidByNameIndex();
+ CaclRsDataByPid();
+ AppendData();
+ return;
+}
+
+void APPStartupFilter::CalcDepthByTimeStamp(std::map>::iterator it,
+ uint32_t& depth,
+ uint64_t endTime,
+ uint64_t startTime)
+{
+ if (!it->second.empty()) {
+ auto itor = it->second.begin();
+ if (itor->first > startTime) {
+ depth = it->second.size();
+ it->second.insert(std::make_pair(endTime, it->second.size()));
+ } else {
+ depth = itor->second;
+ it->second.erase(itor);
+ it->second.insert(std::make_pair(endTime, depth));
+ }
+ for (const auto& item : it->second) {
+ if (item.first < startTime && depth > item.second) {
+ depth = item.second;
+ }
+ }
+ } else {
+ it->second.insert(std::make_pair(endTime, 0));
+ }
+}
+
+void APPStartupFilter::ParserSoInitalization()
+{
+ std::map> mMaxTimeAndDepthWithPid;
+ auto sliceData = traceDataCache_->GetConstInternalSlicesData();
+ auto threadData = traceDataCache_->GetConstThreadData();
+ std::string nameString = "";
+ for (auto i = 0; i < sliceData.NamesData().size(); i++) {
+ nameString = traceDataCache_->GetDataFromDict(sliceData.NamesData()[i]);
+ if (nameString.find(DLOPEN) != std::string::npos) {
+ uint64_t startTime = sliceData.TimeStampData()[i];
+ uint64_t endTime = startTime + sliceData.DursData()[i];
+ uint32_t depth = 0;
+ auto callId = sliceData.CallIds()[i];
+ auto pid = threadData[callId].internalPid_;
+ auto tid = threadData[callId].tid_;
+ auto it = mMaxTimeAndDepthWithPid.find(pid);
+ if (it == mMaxTimeAndDepthWithPid.end()) {
+ mMaxTimeAndDepthWithPid.insert(std::make_pair(pid, std::map{{endTime, 0}}));
+ traceDataCache_->GetStaticInitalizationData()->AppendNewData(pid, tid, callId, startTime, endTime,
+ sliceData.NamesData()[i], depth);
+ continue;
+ } else {
+ CalcDepthByTimeStamp(it, depth, endTime, startTime);
+ traceDataCache_->GetStaticInitalizationData()->AppendNewData(threadData[callId].internalPid_,
+ threadData[callId].tid_, callId, startTime,
+ endTime, sliceData.NamesData()[i], depth);
+ }
+ }
+ }
+ return;
+}
+} // namespace TraceStreamer
+} // namespace SysTuning
diff --git a/trace_streamer/src/filter/app_start_filter.h b/trace_streamer/src/filter/app_start_filter.h
new file mode 100644
index 0000000000000000000000000000000000000000..447da95eb65608079d8121e71fdb36fa811252aa
--- /dev/null
+++ b/trace_streamer/src/filter/app_start_filter.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef APP_START_FILTER_H
+#define APP_START_FILTER_H
+
+#include
+#include
+#include "filter_base.h"
+#include "trace_data_cache.h"
+#include "trace_streamer_filters.h"
+#include "ts_common.h"
+
+namespace SysTuning {
+namespace TraceStreamer {
+constexpr uint32_t INVAILD_DATA = 2;
+constexpr uint32_t MIN_VECTOR_SIZE_ = 2;
+constexpr uint32_t VAILD_DATA_COUNT = 4;
+const std::string PROCESS_CREATE = "H:int OHOS::AAFwk::MissionListManager::StartAbilityLocked(";
+const std::string START_ABILITY = "H:virtual int OHOS::AAFwk::AbilityManagerService::StartAbility(";
+const std::string APP_LAUNCH =
+ "H:virtual void OHOS::AppExecFwk::AppMgrServiceInner::AttachApplication(const pid_t, const "
+ "sptr &)##";
+const std::string LAUNCH =
+ "H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility(const std::shared_ptr &)##";
+const std::string ONFOREGROUND =
+ "H:void OHOS::AppExecFwk::AbilityThread::HandleAbilityTransaction(const OHOS::AppExecFwk::Want &, const "
+ "OHOS::AppExecFwk::LifeCycleStateInfo &, sptr)##";
+const std::string DLOPEN = "dlopen:";
+enum StartupApp {
+ PROCESS_CREATING = 0,
+ APPLICATION_LAUNCHING,
+ UI_ABILITY_LAUNCHING,
+ UI_ABILITY_ONFOREGROUND,
+ FIRST_FRAME_APP_PHASE,
+ FIRST_FRAME_RENDER_PHASE
+};
+class APPStartupData {
+public:
+ APPStartupData(uint32_t callid, uint32_t ipid, uint32_t tid, uint64_t startTime, uint64_t endTime)
+ : callid_(callid), ipid_(ipid), tid_(tid), startTime_(startTime), endTime_(endTime)
+ {
+ }
+ uint32_t callid_;
+ uint32_t ipid_;
+ uint32_t tid_;
+ uint64_t startTime_;
+ uint64_t endTime_;
+};
+
+class APPStartupFilter : private FilterBase {
+public:
+ APPStartupFilter(TraceDataCache* dataCache, const TraceStreamerFilters* filter);
+ APPStartupFilter(const APPStartupFilter&) = delete;
+ APPStartupFilter& operator=(const APPStartupFilter&) = delete;
+ ~APPStartupFilter() override;
+ void FilterAllAPPStartupData();
+
+private:
+ void ParserSoInitalization();
+ void CalcDepthByTimeStamp(std::map>::iterator it,
+ uint32_t& depth,
+ uint64_t endTime,
+ uint64_t startTime);
+ void ParserAppStartup();
+ bool CaclRsDataByPid();
+ bool GetProcessCreate(uint32_t row, uint64_t& startTime, std::string nameString);
+ void UpdatePidByNameIndex();
+ void AppendData();
+ DataIndex GetThreadNameAndUpdateAPPStartupData(uint32_t row, const std::string& nameString, uint32_t startIndex);
+ std::unordered_map>> mAPPStartupData_;
+};
+} // namespace TraceStreamer
+} // namespace SysTuning
+
+#endif // APP_START_FILTER_H
diff --git a/trace_streamer/src/main.cpp b/trace_streamer/src/main.cpp
old mode 100755
new mode 100644
index f13e2d20c3e99ebd8b20a34904be413a6563e8e5..eff838d3595c732f54fc3957972a9fec7fa673e2
--- a/trace_streamer/src/main.cpp
+++ b/trace_streamer/src/main.cpp
@@ -45,9 +45,7 @@ namespace TraceStreamer {
using namespace SysTuning::TraceStreamer;
using namespace SysTuning::base;
constexpr size_t G_CHUNK_SIZE = 1024 * 1024;
-#ifndef COMPILE_WITH_OHOS
constexpr int G_MIN_PARAM_NUM = 2;
-#endif
constexpr size_t G_FILE_PERMISSION = 664;
// set version info in meta.cpp please
void ExportStatusToLog(const std::string& dbPath, TraceParserStatus status)
@@ -299,7 +297,6 @@ int CheckArgs(int argc, char** argv, TraceExportOption& traceExportOption, HttpO
} // namespace SysTuning
int main(int argc, char** argv)
{
-#ifndef COMPILE_WITH_OHOS
if (argc < G_MIN_PARAM_NUM) {
ShowHelpInfo(argv[0]);
return 1;
@@ -357,6 +354,5 @@ int main(int argc, char** argv)
if (!tsOption.sqlOperatorFilePath.empty()) {
ReadSqlFileAndPrintResult(ts, tsOption.sqlOperatorFilePath);
}
-#endif
return 0;
}
diff --git a/trace_streamer/src/parser/bytrace_parser/bytrace_event_parser.cpp b/trace_streamer/src/parser/bytrace_parser/bytrace_event_parser.cpp
index d5e3f18044345ef909a223650d4ec39a8f2a27cc..7fbc40684dbc200c870953bc4b94fd9e15b7198a 100644
--- a/trace_streamer/src/parser/bytrace_parser/bytrace_event_parser.cpp
+++ b/trace_streamer/src/parser/bytrace_parser/bytrace_event_parser.cpp
@@ -14,6 +14,7 @@
*/
#include "bytrace_event_parser.h"
+#include "app_start_filter.h"
#include "binder_filter.h"
#include "cpu_filter.h"
#include "filter_filter.h"
@@ -721,6 +722,7 @@ void BytraceEventParser::FilterAllEvents()
streamFilters_->cpuFilter_->Finish();
traceDataCache_->dataDict_.Finish();
traceDataCache_->UpdataZeroThreadInfo();
+ streamFilters_->appStartupFilter_->FilterAllAPPStartupData();
}
void BytraceEventParser::BeginFilterEvents(EventInfo* event)
diff --git a/trace_streamer/src/parser/bytrace_parser/bytrace_parser.cpp b/trace_streamer/src/parser/bytrace_parser/bytrace_parser.cpp
index 2178adc72cbb524576bbeff27cfbf1dec768e28d..dbd7d19589c47efe90f8131710de9d09364422a8 100644
--- a/trace_streamer/src/parser/bytrace_parser/bytrace_parser.cpp
+++ b/trace_streamer/src/parser/bytrace_parser/bytrace_parser.cpp
@@ -17,6 +17,7 @@
#include
#include
#include
+#include "app_start_filter.h"
#include "binder_filter.h"
#include "cpu_filter.h"
#include "hi_sysevent_measure_filter.h"
diff --git a/trace_streamer/src/parser/ebpf_parser/ebpf_data_reader.cpp b/trace_streamer/src/parser/ebpf_parser/ebpf_data_reader.cpp
index f6ec04fe050449c598ea5cd2a8ff304bc720cc44..cc191bdfb2df9b1a44b4ec635e2169ee11ddb98e 100644
--- a/trace_streamer/src/parser/ebpf_parser/ebpf_data_reader.cpp
+++ b/trace_streamer/src/parser/ebpf_parser/ebpf_data_reader.cpp
@@ -349,7 +349,6 @@ SymbolAndFilePathIndex EbpfDataReader::GetSymbolNameIndexFromElfSym(uint64_t ip)
symbolAndFilePathIndex.flag = true;
symbolAndFilePathIndex.symbolIndex = end->second.name;
symbolAndFilePathIndex.filePathIndex = kernelFilePath_;
- // TS_LOGD("ok for ip:%lu, kernelip:%lu, size:%lu", ip, end->first, end->second.size);
} else {
TS_LOGD("failed for ip:%lu, kernelip:%lu, size:%lu", ip, end->first, end->second.size);
}
diff --git a/trace_streamer/src/parser/htrace_pbreader_parser/htrace_event_parser/htrace_event_parser.cpp b/trace_streamer/src/parser/htrace_pbreader_parser/htrace_event_parser/htrace_event_parser.cpp
index 13a44f9ef9a76443ab0ff7f27ca77b60c09b0b76..0b3afb0710016190f6b1f6b0df93304930847f23 100644
--- a/trace_streamer/src/parser/htrace_pbreader_parser/htrace_event_parser/htrace_event_parser.cpp
+++ b/trace_streamer/src/parser/htrace_pbreader_parser/htrace_event_parser/htrace_event_parser.cpp
@@ -14,6 +14,7 @@
*/
#include "htrace_event_parser.h"
#include
+#include "app_start_filter.h"
#include "binder_filter.h"
#include "binder.pbreader.h"
#include "clk.pbreader.h"
@@ -875,6 +876,7 @@ void HtraceEventParser::FilterAllEvents()
streamFilters_->cpuFilter_->Finish();
traceDataCache_->dataDict_.Finish();
traceDataCache_->UpdataZeroThreadInfo();
+ streamFilters_->appStartupFilter_->FilterAllAPPStartupData();
}
void HtraceEventParser::Clear()
{
diff --git a/trace_streamer/src/parser/htrace_pbreader_parser/htrace_parser.cpp b/trace_streamer/src/parser/htrace_pbreader_parser/htrace_parser.cpp
index 1ec826d1be85fd77eb89c8befff13e246c7dd6de..5e079c368b94ac25093f972dde16b07d4ade4df2 100644
--- a/trace_streamer/src/parser/htrace_pbreader_parser/htrace_parser.cpp
+++ b/trace_streamer/src/parser/htrace_pbreader_parser/htrace_parser.cpp
@@ -15,6 +15,7 @@
#include "htrace_parser.h"
#include
+#include "app_start_filter.h"
#include "binder_filter.h"
#include "common_types.pbreader.h"
#include "cpu_filter.h"
diff --git a/trace_streamer/src/parser/print_event_parser.cpp b/trace_streamer/src/parser/print_event_parser.cpp
index cb83b2df729699a0cea28bc640d46dee8562d449..63c0c943f00328951b1255f58c962f5e296083db 100644
--- a/trace_streamer/src/parser/print_event_parser.cpp
+++ b/trace_streamer/src/parser/print_event_parser.cpp
@@ -46,6 +46,8 @@ bool PrintEventParser::ParsePrintEvent(const std::string& comm,
return false;
}
if (point.tgid_) {
+ // tgid use 'B|' after with 'TGID', the '(TGID)' maybe wrong, eg: xxx-21675 ( 1264) ...: print: B|21675|...
+ const_cast(line).tgid = point.tgid_;
streamFilters_->processFilter_->GetOrCreateInternalPid(ts, point.tgid_);
}
switch (point.phase_) {
diff --git a/trace_streamer/src/table/ftrace/BUILD.gn b/trace_streamer/src/table/ftrace/BUILD.gn
index 8cdc5ba0ce19b7f859427c812f5d8b5781f9e562..17621ccc79ec3d0627fb2eadf00cfd12aa23f09c 100644
--- a/trace_streamer/src/table/ftrace/BUILD.gn
+++ b/trace_streamer/src/table/ftrace/BUILD.gn
@@ -18,6 +18,8 @@ ohos_source_set("ftrace_tables") {
subsystem_name = "trace_streamer"
part_name = "table"
sources = [
+ "app_startup_table.cpp",
+ "app_startup_table.h",
"callstack_table.cpp",
"callstack_table.h",
"clk_event_filter_table.cpp",
@@ -54,6 +56,8 @@ ohos_source_set("ftrace_tables") {
"raw_table.h",
"sched_slice_table.cpp",
"sched_slice_table.h",
+ "so_static_initalization_table.cpp",
+ "so_static_initalization_table.h",
"system_call_table.cpp",
"system_call_table.h",
"system_event_filter_table.cpp",
diff --git a/trace_streamer/src/table/ftrace/app_startup_table.cpp b/trace_streamer/src/table/ftrace/app_startup_table.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3a44cbd62314e622225558bbf0923b421f32f424
--- /dev/null
+++ b/trace_streamer/src/table/ftrace/app_startup_table.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "app_startup_table.h"
+
+namespace SysTuning {
+namespace TraceStreamer {
+enum Index { ID = 0, CALL_ID, IPID, TID, START_TIME, END_TIME, START_NAME, PACKED_NAME };
+AppStartupTable::AppStartupTable(const TraceDataCache* dataCache) : TableBase(dataCache)
+{
+ tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER"));
+ tableColumn_.push_back(TableBase::ColumnInfo("call_id", "INTEGER"));
+ tableColumn_.push_back(TableBase::ColumnInfo("ipid", "INTEGER"));
+ tableColumn_.push_back(TableBase::ColumnInfo("tid", "INTEGER"));
+ tableColumn_.push_back(TableBase::ColumnInfo("start_time", "INTEGER"));
+ tableColumn_.push_back(TableBase::ColumnInfo("end_time", "INTEGER"));
+ tableColumn_.push_back(TableBase::ColumnInfo("start_name", "INTEGER"));
+ tableColumn_.push_back(TableBase::ColumnInfo("packed_name", "TEXT"));
+ tablePriKey_.push_back("id");
+}
+
+AppStartupTable::~AppStartupTable() {}
+
+std::unique_ptr AppStartupTable::CreateCursor()
+{
+ return std::make_unique(dataCache_, this);
+}
+
+AppStartupTable::Cursor::Cursor(const TraceDataCache* dataCache, TableBase* table)
+ : TableBase::Cursor(dataCache, table, static_cast(dataCache->GetConstAppStartupData().Size())),
+ appStartupObj_(dataCache->GetConstAppStartupData())
+{
+}
+
+AppStartupTable::Cursor::~Cursor() {}
+
+int32_t AppStartupTable::Cursor::Column(int32_t column) const
+{
+ switch (column) {
+ case ID:
+ sqlite3_result_int64(context_, static_cast(CurrentRow()));
+ break;
+ case IPID:
+ sqlite3_result_int64(context_, static_cast(appStartupObj_.Pids()[CurrentRow()]));
+ break;
+ case TID:
+ sqlite3_result_int64(context_, static_cast(appStartupObj_.Tids()[CurrentRow()]));
+ break;
+ case CALL_ID:
+ sqlite3_result_int64(context_, static_cast(appStartupObj_.CallIds()[CurrentRow()]));
+ break;
+ case START_TIME:
+ sqlite3_result_int64(context_, static_cast(appStartupObj_.StartTimes()[CurrentRow()]));
+ break;
+ case END_TIME:
+ sqlite3_result_int64(context_, static_cast(appStartupObj_.EndTimes()[CurrentRow()]));
+ break;
+ case START_NAME:
+ sqlite3_result_int64(context_, static_cast(appStartupObj_.StartNames()[CurrentRow()]));
+ break;
+ case PACKED_NAME:
+ sqlite3_result_text(context_,
+ dataCache_->GetDataFromDict(appStartupObj_.PackedNames()[CurrentRow()]).c_str(),
+ STR_DEFAULT_LEN, nullptr);
+ break;
+ default:
+ TS_LOGF("Unregistered column : %d", column);
+ break;
+ }
+ return SQLITE_OK;
+}
+} // namespace TraceStreamer
+} // namespace SysTuning
diff --git a/trace_streamer/src/table/ftrace/app_startup_table.h b/trace_streamer/src/table/ftrace/app_startup_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..cca17a80a99aa87d1c264e39906bdc3a4e9c334e
--- /dev/null
+++ b/trace_streamer/src/table/ftrace/app_startup_table.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef APP_STARTUP_TABLE_H
+#define APP_STARTUP_TABLE_H
+
+#include "table_base.h"
+#include "trace_data_cache.h"
+
+namespace SysTuning {
+namespace TraceStreamer {
+class AppStartupTable : public TableBase {
+public:
+ explicit AppStartupTable(const TraceDataCache* dataCache);
+ ~AppStartupTable() override;
+ std::unique_ptr CreateCursor() override;
+
+private:
+ void EstimateFilterCost(FilterConstraints& fc, EstimatedIndexInfo& ei) override
+ {
+ UNUSED(fc);
+ UNUSED(ei);
+ }
+
+ class Cursor : public TableBase::Cursor {
+ public:
+ explicit Cursor(const TraceDataCache* dataCache, TableBase* table);
+ ~Cursor() override;
+ int32_t Filter(const FilterConstraints& fc, sqlite3_value** argv) override
+ {
+ UNUSED(fc);
+ UNUSED(argv);
+ return 0;
+ }
+ int32_t Column(int32_t column) const override;
+
+ private:
+ const AppStartup& appStartupObj_;
+ };
+};
+} // namespace TraceStreamer
+} // namespace SysTuning
+#endif // APP_STARTUP_TABLE_H
diff --git a/trace_streamer/src/table/ftrace/so_static_initalization_table.cpp b/trace_streamer/src/table/ftrace/so_static_initalization_table.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fcb088dff1c9d59163b3661fa31edb049bea9cd0
--- /dev/null
+++ b/trace_streamer/src/table/ftrace/so_static_initalization_table.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "so_static_initalization_table.h"
+
+namespace SysTuning {
+namespace TraceStreamer {
+enum Index { ID = 0, IPID, TID, CALL_ID, START_TIME, END_TIME, SO_NAME, DEPTH };
+SoStaticInitalizationTable::SoStaticInitalizationTable(const TraceDataCache* dataCache) : TableBase(dataCache)
+{
+ tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER"));
+ tableColumn_.push_back(TableBase::ColumnInfo("ipid", "INTEGER"));
+ tableColumn_.push_back(TableBase::ColumnInfo("tid", "INTEGER"));
+ tableColumn_.push_back(TableBase::ColumnInfo("call_id", "INTEGER"));
+ tableColumn_.push_back(TableBase::ColumnInfo("start_time", "INTEGER"));
+ tableColumn_.push_back(TableBase::ColumnInfo("end_time", "INTEGER"));
+ tableColumn_.push_back(TableBase::ColumnInfo("so_name", "TEXT"));
+ tableColumn_.push_back(TableBase::ColumnInfo("depth", "INTEGER"));
+ tablePriKey_.push_back("id");
+}
+
+SoStaticInitalizationTable::~SoStaticInitalizationTable() {}
+
+std::unique_ptr SoStaticInitalizationTable::CreateCursor()
+{
+ return std::make_unique(dataCache_, this);
+}
+
+SoStaticInitalizationTable::Cursor::Cursor(const TraceDataCache* dataCache, TableBase* table)
+ : TableBase::Cursor(dataCache, table, static_cast(dataCache->GetConstStaticInitalizationData().Size())),
+ staticInitalizationObj_(dataCache->GetConstStaticInitalizationData())
+{
+}
+
+SoStaticInitalizationTable::Cursor::~Cursor() {}
+
+int32_t SoStaticInitalizationTable::Cursor::Column(int32_t column) const
+{
+ switch (column) {
+ case ID:
+ sqlite3_result_int64(context_, static_cast(CurrentRow()));
+ break;
+ case IPID:
+ sqlite3_result_int64(context_, static_cast(staticInitalizationObj_.Pids()[CurrentRow()]));
+ break;
+ case TID:
+ sqlite3_result_int64(context_, static_cast(staticInitalizationObj_.Tids()[CurrentRow()]));
+ break;
+ case CALL_ID:
+ sqlite3_result_int64(context_, static_cast(staticInitalizationObj_.CallIds()[CurrentRow()]));
+ break;
+ case START_TIME:
+ sqlite3_result_int64(context_, static_cast(staticInitalizationObj_.StartTimes()[CurrentRow()]));
+ break;
+ case END_TIME:
+ sqlite3_result_int64(context_, static_cast(staticInitalizationObj_.EndTimes()[CurrentRow()]));
+ break;
+ case SO_NAME:
+ sqlite3_result_text(context_,
+ dataCache_->GetDataFromDict(staticInitalizationObj_.SoNames()[CurrentRow()]).c_str(),
+ STR_DEFAULT_LEN, nullptr);
+ break;
+ case DEPTH:
+ sqlite3_result_int64(context_, static_cast(staticInitalizationObj_.Depths()[CurrentRow()]));
+ break;
+ default:
+ TS_LOGF("Unregistered column : %d", column);
+ break;
+ }
+ return SQLITE_OK;
+}
+} // namespace TraceStreamer
+} // namespace SysTuning
diff --git a/trace_streamer/src/table/ftrace/so_static_initalization_table.h b/trace_streamer/src/table/ftrace/so_static_initalization_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..1f43b67ccad699cee31417545636e50f2c43c4ba
--- /dev/null
+++ b/trace_streamer/src/table/ftrace/so_static_initalization_table.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SO_STATIC_INITALIZATION_TABLE_H
+#define SO_STATIC_INITALIZATION_TABLE_H
+
+#include "table_base.h"
+#include "trace_data_cache.h"
+
+namespace SysTuning {
+namespace TraceStreamer {
+class SoStaticInitalizationTable : public TableBase {
+public:
+ explicit SoStaticInitalizationTable(const TraceDataCache* dataCache);
+ ~SoStaticInitalizationTable() override;
+ std::unique_ptr CreateCursor() override;
+
+private:
+ void EstimateFilterCost(FilterConstraints& fc, EstimatedIndexInfo& ei) override
+ {
+ UNUSED(fc);
+ UNUSED(ei);
+ }
+
+ class Cursor : public TableBase::Cursor {
+ public:
+ explicit Cursor(const TraceDataCache* dataCache, TableBase* table);
+ ~Cursor() override;
+ int32_t Filter(const FilterConstraints& fc, sqlite3_value** argv) override
+ {
+ UNUSED(fc);
+ UNUSED(argv);
+ return 0;
+ }
+ int32_t Column(int32_t column) const override;
+
+ private:
+ const SoStaticInitalization& staticInitalizationObj_;
+ };
+};
+} // namespace TraceStreamer
+} // namespace SysTuning
+#endif // STATIC_INITALIZATION_TABLE_H
diff --git a/trace_streamer/src/trace_data/trace_data_cache.cpp b/trace_streamer/src/trace_data/trace_data_cache.cpp
index 1e71cf55e96e28517ec06a4b82fb86a6389ad0de..02c43db1f26e7b41dc639f85bfb77c02488b7096 100644
--- a/trace_streamer/src/trace_data/trace_data_cache.cpp
+++ b/trace_streamer/src/trace_data/trace_data_cache.cpp
@@ -14,6 +14,7 @@
*/
#include "trace_data_cache.h"
+#include "app_startup_table.h"
#include "appname_table.h"
#include "args_table.h"
#include "bio_latency_sample_table.h"
@@ -79,6 +80,7 @@
#include "span_join.h"
#include "sqlite3.h"
#include "stat_table.h"
+#include "so_static_initalization_table.h"
#include "symbols_table.h"
#include "sysevent_measure_table.h"
#include "system_call_table.h"
@@ -175,6 +177,8 @@ void TraceDataCache::InitDB()
TableBase::TableDeclare(*db_, this, "frame_slice");
TableBase::TableDeclare(*db_, this, "frame_maps");
TableBase::TableDeclare(*db_, this, "gpu_slice");
+ TableBase::TableDeclare(*db_, this, "app_startup");
+ TableBase::TableDeclare(*db_, this, "static_initalize");
#if WITH_PERF
TableBase::TableDeclare(*db_, this, "perf_report");
@@ -245,6 +249,8 @@ void TraceDataCache::InitDB()
TableBase::TableDeclare(*db_, this, "_frame_slice");
TableBase::TableDeclare(*db_, this, "_frame_maps");
TableBase::TableDeclare(*db_, this, "_gpu_slice");
+ TableBase::TableDeclare(*db_, this, "_app_startup");
+ TableBase::TableDeclare(*db_, this, "_static_initalize");
#if WITH_EBPF_HELP
TableBase::TableDeclare(*db_, this, "_ebpf_process_maps");
TableBase::TableDeclare(*db_, this, "_ebpf_elf");
diff --git a/trace_streamer/src/trace_data/trace_data_cache_base.h b/trace_streamer/src/trace_data/trace_data_cache_base.h
index bc780e17921aa7f521b422a36153155c37a58695..7823286043cf767563cc8bb6ce76bf86f8fc4f2a 100644
--- a/trace_streamer/src/trace_data/trace_data_cache_base.h
+++ b/trace_streamer/src/trace_data/trace_data_cache_base.h
@@ -71,17 +71,17 @@ public:
{TASK_TRACED, "T"},
{TASK_EXIT_DEAD, "X"},
{TASK_ZOMBIE, "Z"},
- {TASK_KILLED, "I"},
- {TASK_WAKEKILL, "R"},
- {TASK_PARKED, "P"},
- {TASK_INVALID, "U"},
{TASK_CLONE, "I"},
+ {TASK_KILLED, "I"},
{TASK_DK, "DK"},
{TASK_DK_IO, "DK-IO"},
{TASK_DK_NIO, "DK-NIO"},
{TASK_TRACED_KILL, "TK"},
+ {TASK_WAKEKILL, "R"},
+ {TASK_PARKED, "P"},
{TASK_FOREGROUND, "R+"},
- {TASK_MAX, "S"}};
+ {TASK_MAX, "S"},
+ {TASK_INVALID, "U"}};
std::map threadStatus2Value_ = {};
uint64_t traceStartTime_ = std::numeric_limits::max();
uint64_t traceEndTime_ = 0;
@@ -161,6 +161,8 @@ public:
JsHeapString jsHeapStringData_;
JsHeapTraceFuncInfo jsHeapTraceFuncInfoData_;
JsHeapTraceNode jsHeapTraceNodeData_;
+ AppStartup appStartupData_;
+ SoStaticInitalization staticInitalizationData_;
};
} // namespace TraceStreamer
} // namespace SysTuning
diff --git a/trace_streamer/src/trace_data/trace_data_cache_reader.cpp b/trace_streamer/src/trace_data/trace_data_cache_reader.cpp
index fa01a2a14f44bcee15c5315493324c10e9e54cc5..e824fd4c4a53edc50f221e6a1fbf16f5db325bcd 100644
--- a/trace_streamer/src/trace_data/trace_data_cache_reader.cpp
+++ b/trace_streamer/src/trace_data/trace_data_cache_reader.cpp
@@ -326,5 +326,13 @@ const GPUSlice& TraceDataCacheReader::GetConstGPUSliceData() const
{
return gpuSliceData_;
}
+const AppStartup& TraceDataCacheReader::GetConstAppStartupData() const
+{
+ return appStartupData_;
+}
+const SoStaticInitalization& TraceDataCacheReader::GetConstStaticInitalizationData() const
+{
+ return staticInitalizationData_;
+}
} // namespace TraceStreamer
} // namespace SysTuning
diff --git a/trace_streamer/src/trace_data/trace_data_cache_reader.h b/trace_streamer/src/trace_data/trace_data_cache_reader.h
index fcf68491c0df2ef7bbc6ca6886d39e9b1ac1c487..675924fbe81981a8d8724362ea37d4e36ab9994f 100644
--- a/trace_streamer/src/trace_data/trace_data_cache_reader.h
+++ b/trace_streamer/src/trace_data/trace_data_cache_reader.h
@@ -105,6 +105,8 @@ public:
const JsHeapString& GetConstJsHeapStringData() const;
const JsHeapTraceFuncInfo& GetConstJsHeapTraceFuncInfoData() const;
const JsHeapTraceNode& GetConstJsHeapTraceNodeData() const;
+ const AppStartup& GetConstAppStartupData() const;
+ const SoStaticInitalization& GetConstStaticInitalizationData() const;
};
} // namespace TraceStreamer
} // namespace SysTuning
diff --git a/trace_streamer/src/trace_data/trace_data_cache_writer.cpp b/trace_streamer/src/trace_data/trace_data_cache_writer.cpp
index cd2a2cf50b2715db69d2c4d5cb77fdeba278dbb6..a2122be30d79170476cc388e40c736d8cf332652 100644
--- a/trace_streamer/src/trace_data/trace_data_cache_writer.cpp
+++ b/trace_streamer/src/trace_data/trace_data_cache_writer.cpp
@@ -371,6 +371,14 @@ JsHeapTraceNode* TraceDataCacheWriter::GetJsHeapTraceNodeData()
{
return &jsHeapTraceNodeData_;
}
+AppStartup* TraceDataCacheWriter::GetAppStartupData()
+{
+ return &appStartupData_;
+}
+SoStaticInitalization* TraceDataCacheWriter::GetStaticInitalizationData()
+{
+ return &staticInitalizationData_;
+}
void TraceDataCacheWriter::Clear()
{
rawData_.Clear();
@@ -428,6 +436,8 @@ void TraceDataCacheWriter::Clear()
jsHeapStringData_.Clear();
jsHeapTraceFuncInfoData_.Clear();
jsHeapTraceNodeData_.Clear();
+ appStartupData_.Clear();
+ staticInitalizationData_.Clear();
#if WITH_EBPF_HELP
ebpfProcessMaps_.Clear();
diff --git a/trace_streamer/src/trace_data/trace_data_cache_writer.h b/trace_streamer/src/trace_data/trace_data_cache_writer.h
index 15f7793d91a8680d2215cc89e81e597d4cb437ff..cb0ea8af2550b98313fabd8dad3bb46af5c36f03 100644
--- a/trace_streamer/src/trace_data/trace_data_cache_writer.h
+++ b/trace_streamer/src/trace_data/trace_data_cache_writer.h
@@ -104,6 +104,8 @@ public:
JsHeapString* GetJsHeapStringData();
JsHeapTraceFuncInfo* GetJsHeapTraceFuncInfoData();
JsHeapTraceNode* GetJsHeapTraceNodeData();
+ AppStartup* GetAppStartupData();
+ SoStaticInitalization* GetStaticInitalizationData();
};
} // namespace TraceStreamer
} // namespace SysTuning
diff --git a/trace_streamer/src/trace_data/trace_stdtype.cpp b/trace_streamer/src/trace_data/trace_stdtype.cpp
index a2069f18c8121f5fb1079ac484e97075e0b0dbe7..cc5ecc4d50f8bfa233ab2cdf424ce4efd4822f97 100644
--- a/trace_streamer/src/trace_data/trace_stdtype.cpp
+++ b/trace_streamer/src/trace_data/trace_stdtype.cpp
@@ -2308,6 +2308,100 @@ const size_t GPUSlice::Size() const
return durs_.size();
}
+size_t AppStartup::AppendNewData(uint32_t ipid,
+ uint32_t tid,
+ uint32_t callId,
+ uint64_t startTime,
+ uint64_t endTime,
+ uint32_t startName,
+ DataIndex packedName)
+{
+ ipids_.emplace_back(ipid);
+ tids_.emplace_back(tid);
+ callIds_.emplace_back(callId);
+ startTimes_.emplace_back(startTime);
+ endTimes_.emplace_back(endTime);
+ startNames_.emplace_back(startName);
+ packedNames_.emplace_back(packedName);
+ ids_.emplace_back(Size());
+ return Size() - 1;
+}
+const std::deque& AppStartup::Pids() const
+{
+ return ipids_;
+}
+const std::deque& AppStartup::Tids() const
+{
+ return tids_;
+}
+const std::deque& AppStartup::CallIds() const
+{
+ return callIds_;
+}
+const std::deque& AppStartup::StartTimes() const
+{
+ return startTimes_;
+}
+const std::deque& AppStartup::EndTimes() const
+{
+ return endTimes_;
+}
+const std::deque& AppStartup::StartNames() const
+{
+ return startNames_;
+}
+const std::deque& AppStartup::PackedNames() const
+{
+ return packedNames_;
+}
+
+size_t SoStaticInitalization::AppendNewData(uint32_t ipid,
+ uint32_t tid,
+ uint32_t callId,
+ uint64_t startTime,
+ uint64_t endTime,
+ DataIndex soName,
+ uint32_t depth)
+{
+ ipids_.emplace_back(ipid);
+ tids_.emplace_back(tid);
+ callIds_.emplace_back(callId);
+ startTimes_.emplace_back(startTime);
+ endTimes_.emplace_back(endTime);
+ soNames_.emplace_back(soName);
+ depths_.emplace_back(depth);
+ ids_.emplace_back(Size());
+ return Size() - 1;
+}
+const std::deque& SoStaticInitalization::Pids() const
+{
+ return ipids_;
+}
+const std::deque& SoStaticInitalization::Tids() const
+{
+ return tids_;
+}
+const std::deque& SoStaticInitalization::CallIds() const
+{
+ return callIds_;
+}
+const std::deque& SoStaticInitalization::StartTimes() const
+{
+ return startTimes_;
+}
+const std::deque& SoStaticInitalization::EndTimes() const
+{
+ return endTimes_;
+}
+const std::deque& SoStaticInitalization::SoNames() const
+{
+ return soNames_;
+}
+const std::deque SoStaticInitalization::Depths() const
+{
+ return depths_;
+}
+
size_t JsHeapFiles::AppendNewData(uint32_t id,
std::string filePath,
uint64_t startTime,
diff --git a/trace_streamer/src/trace_data/trace_stdtype.h b/trace_streamer/src/trace_data/trace_stdtype.h
index 61fb841736591ddd893ab6bdfb7d99417d238117..77ce8bd1f7718f27af6dcb11d100cfcfd4745c69 100644
--- a/trace_streamer/src/trace_data/trace_stdtype.h
+++ b/trace_streamer/src/trace_data/trace_stdtype.h
@@ -139,7 +139,7 @@ public:
states_.clear();
cpus_.clear();
}
- uint32_t Size() const
+ const uint32_t Size() const
{
return itids_.size();
}
@@ -1822,7 +1822,7 @@ public:
names_.emplace_back(name);
return ts_.size();
}
- size_t Size() const
+ const size_t Size() const
{
return ts_.size();
}
@@ -1853,7 +1853,7 @@ public:
clockIds_.emplace_back(clockId);
return dataSourceNames_.size();
}
- size_t Size() const
+ const size_t Size() const
{
return dataSourceNames_.size();
}
@@ -1934,6 +1934,84 @@ private:
std::deque dsts_ = {};
};
+class AppStartup : public CacheBase {
+public:
+ size_t AppendNewData(uint32_t ipid,
+ uint32_t tid,
+ uint32_t callId,
+ uint64_t startTime,
+ uint64_t endTime,
+ uint32_t startName,
+ DataIndex packedName);
+ const std::deque& Pids() const;
+ const std::deque& Tids() const;
+ const std::deque& CallIds() const;
+ const std::deque& StartTimes() const;
+ const std::deque& EndTimes() const;
+ const std::deque& StartNames() const;
+ const std::deque& PackedNames() const;
+
+ void Clear() override
+ {
+ CacheBase::Clear();
+ ipids_.clear();
+ tids_.clear();
+ callIds_.clear();
+ startTimes_.clear();
+ endTimes_.clear();
+ startNames_.clear();
+ packedNames_.clear();
+ }
+
+private:
+ std::deque ipids_ = {};
+ std::deque tids_ = {};
+ std::deque callIds_ = {};
+ std::deque startTimes_ = {};
+ std::deque endTimes_ = {};
+ std::deque startNames_ = {};
+ std::deque packedNames_ = {};
+};
+
+class SoStaticInitalization : public CacheBase {
+public:
+ size_t AppendNewData(uint32_t ipid,
+ uint32_t tid,
+ uint32_t callId,
+ uint64_t startTime,
+ uint64_t endTime,
+ DataIndex soName,
+ uint32_t depth);
+ const std::deque& Pids() const;
+ const std::deque& Tids() const;
+ const std::deque& CallIds() const;
+ const std::deque& StartTimes() const;
+ const std::deque& EndTimes() const;
+ const std::deque& SoNames() const;
+ const std::deque Depths() const;
+
+ void Clear() override
+ {
+ CacheBase::Clear();
+ ipids_.clear();
+ tids_.clear();
+ callIds_.clear();
+ startTimes_.clear();
+ endTimes_.clear();
+ soNames_.clear();
+ depths_.clear();
+ }
+
+private:
+ std::deque ipids_ = {};
+ std::deque tids_ = {};
+ std::deque callIds_ = {};
+ std::deque startTimes_ = {};
+ std::deque endTimes_ = {};
+ std::deque soNames_ = {};
+ std::deque depths_ = {};
+};
+
class JsHeapFiles : public CacheBase {
public:
size_t AppendNewData(uint32_t id,
@@ -2225,7 +2303,7 @@ public:
size_t AppendNew(uint32_t frameRow, uint64_t dur);
const std::deque& FrameRows() const;
const std::deque& Durs() const;
- size_t Size() const;
+ const size_t Size() const;
private:
std::deque frameRows_ = {};
diff --git a/trace_streamer/src/trace_streamer/trace_streamer_filters.cpp b/trace_streamer/src/trace_streamer/trace_streamer_filters.cpp
index e29910ff5268929c87f8522e84e9133d466ca8fd..f25e3ebe1964c88f524448b71ad2c6a941980d30 100644
--- a/trace_streamer/src/trace_streamer/trace_streamer_filters.cpp
+++ b/trace_streamer/src/trace_streamer/trace_streamer_filters.cpp
@@ -14,6 +14,7 @@
*/
#include "trace_streamer_filters.h"
+#include "app_start_filter.h"
#include "args_filter.h"
#include "binder_filter.h"
#include "clock_filter_ex.h"
diff --git a/trace_streamer/src/trace_streamer/trace_streamer_filters.h b/trace_streamer/src/trace_streamer/trace_streamer_filters.h
index 0f6623ec5f34d9eb32e02f20b558f5b51c466a48..9d0c114e1e51bba195d19c0041d8c1abbf75d899 100644
--- a/trace_streamer/src/trace_streamer/trace_streamer_filters.h
+++ b/trace_streamer/src/trace_streamer/trace_streamer_filters.h
@@ -33,6 +33,7 @@ class IrqFilter;
class SystemEventMeasureFilter;
class HiSysEventMeasureFilter;
class FrameFilter;
+class APPStartupFilter;
#if WITH_PERF
class PerfDataFilter;
#endif
@@ -66,6 +67,7 @@ public:
std::unique_ptr sysEventSourceFilter_;
std::unique_ptr hiSysEventMeasureFilter_;
std::unique_ptr frameFilter_;
+ std::unique_ptr appStartupFilter_;
#if WITH_PERF
std::unique_ptr perfDataFilter_;
#endif
diff --git a/trace_streamer/src/trace_streamer/trace_streamer_selector.cpp b/trace_streamer/src/trace_streamer/trace_streamer_selector.cpp
index d063ffca7aa9025e41e4087c5241e5a0e936731d..3723a4ecb9192b6c2abc136485e19586a9e64e3a 100644
--- a/trace_streamer/src/trace_streamer/trace_streamer_selector.cpp
+++ b/trace_streamer/src/trace_streamer/trace_streamer_selector.cpp
@@ -18,6 +18,7 @@
#include
#include
#include
+#include "app_start_filter.h"
#include "args_filter.h"
#include "binder_filter.h"
#include "clock_filter_ex.h"
@@ -141,6 +142,7 @@ void TraceStreamerSelector::InitFilter()
std::make_unique(traceDataCache_.get(), streamFilters_.get(), E_SYS_MEMORY_FILTER);
streamFilters_->sysEventVMemMeasureFilter_ = std::make_unique(
traceDataCache_.get(), streamFilters_.get(), E_SYS_VIRTUAL_MEMORY_FILTER);
+ streamFilters_->appStartupFilter_ = std::make_unique(traceDataCache_.get(), streamFilters_.get());
#if WITH_PERF
streamFilters_->perfDataFilter_ = std::make_unique(traceDataCache_.get(), streamFilters_.get());
#endif
diff --git a/trace_streamer/src/trace_streamer/trace_streamer_selector.h b/trace_streamer/src/trace_streamer/trace_streamer_selector.h
index f6caacd759987777e36960cd344f78f7ac2d91b6..f084f7a55dece2c4dccf530dd480d3681535e6a4 100644
--- a/trace_streamer/src/trace_streamer/trace_streamer_selector.h
+++ b/trace_streamer/src/trace_streamer/trace_streamer_selector.h
@@ -56,7 +56,6 @@ private:
TraceFileType fileType_;
std::unique_ptr streamFilters_ = {};
std::unique_ptr traceDataCache_ = {};
-
std::unique_ptr bytraceParser_;
std::unique_ptr htraceParser_;
bool enableFileSeparate_ = false;
diff --git a/trace_streamer/test/unittest/smaps_parser_test.cpp b/trace_streamer/test/unittest/smaps_parser_test.cpp
index 71e4c7a47047d0877db343e96002bf7aeeacba7c..f775dfbe470a3614fd50e77e6de71284d7da4c12 100644
--- a/trace_streamer/test/unittest/smaps_parser_test.cpp
+++ b/trace_streamer/test/unittest/smaps_parser_test.cpp
@@ -302,7 +302,6 @@ HWTEST_F(SmapsParserTest, ParseEmptySmapsData, TestSize.Level1)
tracePacket.clear_processesinfo();
auto eventCount = stream_.traceDataCache_->GetConstStatAndInfo().GetValue(TRACE_SMAPS, STAT_EVENT_RECEIVED);
- // EXPECT_TRUE(0 == eventCount);
EXPECT_EQ(0, eventCount);
}
} // namespace TraceStreamer