1# HiDebug能力概述 2 3<!--Kit: Performance Analysis Kit--> 4<!--Subsystem: HiviewDFX--> 5<!--Owner: @hello_harmony; @yu_haoqiaida--> 6<!--Designer: @kutcherzhou1--> 7<!--Tester: @gcw_KuLfPSbe--> 8<!--Adviser: @foryourself--> 9 10HiDebug可用于获取系统或应用进程的内存、CPU和GPU等数据,以及开启进程Trace采集。 11 12本文介绍HiDebug模块中的ArkTS和C/C++接口,并按接口能力分类。 13 14接口详情可查看[ArkTS API参考文档](../reference/apis-performance-analysis-kit/js-apis-hidebug.md)及[C API参考文档](../reference/apis-performance-analysis-kit/capi-hidebug-h.md)。 15 16## 约束限制 17 18该模块的接口调用较为耗时,部分接口调用时长可达秒级,可能导致调用线程FREEZE。基于HiDebug模块定义,建议仅在应用调试、调优阶段使用该模块内的接口。若需在其他场景使用,请评估接口调用对应用性能的影响。 19 20## 获取内存信息 21 22HiDebug可用于获取整机内存、应用进程内存占用、应用线程内存占用及内存分配器统计的native内存分配数据。在程序开发过程中,查看设备和应用进程的内存数据是发现和解决各种问题、优化程序性能及确保程序稳定性的关键手段。 23 24### 接口说明(ArkTS) 25 26| 接口名 | 描述 | 27| -------- | -------- | 28| hidebug.getNativeHeapSize | 获取内存分配器统计的进程持有的普通块所占用的总字节数。mallinfo接口中获取到的uordblks与fordblks之和。 | 29| hidebug.getNativeHeapAllocatedSize | 获取内存分配器统计的进程持有的已使用的普通块所占用的总字节数。mallinfo接口中获取到的uordblks。 | 30| hidebug.getNativeHeapFreeSize | 获取内存分配器统计的进程持有的空闲的普通块所占用的总字节数。mallinfo接口中获取到的fordblks。 | 31| hidebug.getPss | 获取应用进程实际使用的物理内存大小。读取/proc/{pid}/smaps_rollup节点中的Pss与SwapPss值并求和。 | 32| hidebug.getVss | 获取应用进程虚拟耗用内存大小。读取/proc/{pid}/statm节点中的size值(内存页数),vss = size * 页大小(4K/页)。 | 33| hidebug.getSharedDirty | 获取进程的共享脏内存大小。读取/proc/{pid}/smaps_rollup节点中的Shared_Dirty值。 | 34| hidebug.getPrivateDirty | 获取进程的私有脏内存大小。读取/proc/{pid}/smaps_rollup中的Private_Dirty值。 | 35| hidebug.getAppNativeMemInfo | 获取应用进程内存信息。读取/proc/{pid}/smaps_rollup和/proc/{pid}/statm节点的数据。 | 36| hidebug.getAppNativeMemInfoAsync | 异步方式获取应用进程内存信息。<br/>**说明**:从API version 20开始,支持该接口。 | 37| hidebug.getAppNativeMemInfoWithCache | 获取应用进程内存信息(该接口存在缓存机制以提高接口性能)。<br/>**说明**:从API version 20开始,支持该接口。 | 38| hidebug.getSystemMemInfo | 获取系统内存信息。读取/proc/meminfo节点的数据。 | 39| hidebug.getAppMemoryLimit | 获取应用程序进程内存限制,其中rsslimit由getrlimit 接口获取到的RLIMIT_RSS资源值,vsslimit由getrlimit接口获取到的的RLIMIT_AS资源值。 | 40| hidebug.setJsRawHeapTrimLevel | 设置当前进程转储虚拟机原始堆快照的裁剪级别。<br/>**说明**:从API version 20开始,支持该接口。 | 41 42### 接口说明(C/C++) 43 44| 接口名 | 描述 | 45| -------- | -------- | 46| OH_HiDebug_GetSystemMemInfo | 获取系统内存信息。读取/proc/meminfo节点的数据。 | 47| OH_HiDebug_GetAppNativeMemInfo | 获取应用进程内存信息。读取/proc/{pid}/smaps_rollup和/proc/{pid}/statm节点的数据。 | 48| OH_HiDebug_GetAppNativeMemInfoWithCache | 获取应用程序进程的内存信息,该接口存在缓存机制以提高性能。<br/>**说明**:从API version 20开始,支持该接口。 | 49| OH_HiDebug_GetAppMemoryLimit | 获取应用程序进程内存限制,其中rsslimit由getrlimit 接口获取到的RLIMIT_RSS资源值,vsslimit由getrlimit接口获取到的的RLIMIT_AS资源值。 | 50 51## 获取显存信息 52 53HiDebug可获取应用占用的显存资源数据。在图形密集型应用中,显存管理至关重要,滥用显存资源将导致应用严重卡顿,影响用户体验。显存资源包括两部分: 54 551. MemoryTracker统计的内存是由GPU驱动程序使用物理页面分配器直接分配的,这部分内存的大小取决于GPU硬件驱动程序的实现。 56 572. RenderService渲染进程加载所需资源占用的内存,例如图片、纹理等。 58 59### 接口说明(ArkTS) 60 61| 接口名 | 描述 | 62| -------- | -------- | 63| hidebug.getGraphicsMemory | 使用异步方式获取应用程序的显存大小。 | 64| hidebug.getGraphicsMemorySync | 使用同步方式获取应用程序的显存大小。 | 65 66### 接口说明(C/C++) 67 68| 接口名 | 描述 | 69| -------- | -------- | 70| OH_HiDebug_GetGraphicsMemory | 用于获取应用程序的显存大小。 | 71 72## 获取CPU使用率 73 74应用开发中,监控CPU使用率是性能分析的关键。获取CPU使用率有助于优化应用性能,确保流畅运行。HiDebug提供了多个接口,方便获取CPU使用率。 75 76### 实现原理 77 78hiview进程每10秒获取一次当前CPU的运行数据并缓存,作为CPU使用率计算的基准,主要包括以下数据: 79 801.系统CPU使用数据: 81 82/proc/stat节点包含了自系统启动以来CPU 运行数据的统计信息,可在终端中使用以下命令查看该节点信息: 83 84``` 85cat /proc/stat 86cpu 648079 547 703220 16994706 23006 101071 0 0 0 0 87... 88``` 89 90CPU 指标字段含义: 91 92CPU的统计信息从左到右分别代表以下含义(其中cpu为所有cpu运行数据的总和): 93 94- user: 用户态时间(单位:jiffies) 95 96- nice: nice 用户态时间(单位:jiffies) 97 98- system: 内核态时间(单位:jiffies) 99 100- idle: 空闲时间(单位:jiffies,不包含 IO 等待时间) 101 102- iowait: IO 等待时间(单位:jiffies) 103 104- irq: 硬中断时间(单位:jiffies) 105 106- softirq: 软中断时间(单位:jiffies) 107 108- steal: 被盗时间(虚拟化环境中运行其他操作系统上花费的时间) 109 110- guest: 来宾时间(操作系统运行虚拟 CPU 花费的时间) 111 112- guest_nice: nice 来宾时间(运行一个带 nice 值的 guest 花费的时间) 113 1142.进程CPU使用数据/线程CPU使用数据: 115 116``` 117// 内核统计的进程cpu运行数据 118struct ucollection_process_cpu_item { 119 int pid; 120 unsigned int thread_total; 121 unsigned long long min_flt; 122 unsigned long long maj_flt; 123 unsigned long long cpu_usage_utime; // 用户态CPU运行时长 124 unsigned long long cpu_usage_stime;// 内核态CPU运行时长 125 unsigned long long cpu_load_time; 126}; 127// 内核统计的线程cpu运行数据 128struct ucollection_thread_cpu_item { 129 int tid; 130 char name[16]; // 16 :max length of thread name 131 unsigned long long cpu_usage_utime;// 用户态CPU运行时长 132 unsigned long long cpu_usage_stime;// 内核态CPU运行时长 133 unsigned long long cpu_load_time; 134}; 135``` 136 137调用接口,获取当前数据,计算与基准数据的增量,使用以下公式获取CPU使用率: 138 139系统CPU使用率: 140 141``` 142(systemUsage增量 + niceUsage增量 + userUsage增量) /(userTime增量 + niceTime增量 + systemTime增量 + idleTime增量 + ioWaitTime增量 + irqTime增量 + softIrqTime增量) 143``` 144 145进程CPU使用率/线程CPU使用率 : 146 147``` 148(cpu_usage_utime增量 + cpu_usage_stime增量) /(ms级时间戳增量) 149``` 150 151### 接口说明(ArkTS) 152 153| 接口名 | 描述 | 154| -------- | -------- | 155| hidebug.getAppThreadCpuUsage | 获取应用线程的CPU使用率。 | 156| hidebug.getCpuUsage | 获取应用进程CPU使用率。 | 157| hidebug.getSystemCpuUsage | 获取系统CPU使用率。 | 158 159### 接口说明(C/C++) 160 161| 接口名 | 描述 | 162| -------- | -------- | 163| OH_HiDebug_GetSystemCpuUsage | 获取系统的CPU使用率。 | 164| OH_HiDebug_GetAppCpuUsage | 获取进程的CPU使用率。 | 165| OH_HiDebug_GetAppThreadCpuUsage | 获取应用所有线程CPU使用率。 | 166| OH_HiDebug_FreeThreadCpuUsage | 释放通过OH_HiDebug_GetAppThreadCpuUsage接口获取到的数据。 | 167 168## 获取VM信息 169 170HiDebug可用于获取VM内存数据、GC统计数据及VM堆转储。 171 172### 接口说明(ArkTS) 173 174| 接口名 | 描述 | 175| -------- | -------- | 176| hidebug.getAppVMMemoryInfo | 获取VM内存相关信息。 | 177| hidebug.getVMRuntimeStats | 获取系统[GC](../arkts-utils/gc-introduction.md)统计信息。 | 178| hidebug.getVMRuntimeStat | 根据参数获取指定的系统[GC](../arkts-utils/gc-introduction.md)统计信息。 | 179| hidebug.dumpJsRawHeapData | 使用异步方式为当前线程转储虚拟机的原始堆快照,辅助[JS内存泄漏分析](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-stability-js-memleak-detection)。 | 180| hidebug.dumpJsHeapData | 使用同步方式导出虚拟机堆,辅助[JS内存泄漏分析](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-stability-js-memleak-detection)。 | 181| hidebug.getAppMemoryLimit | 获取应用程序进程内存限制,其中vmHeapLimit为当前线程对应的虚拟机堆大小限制,vmTotalHeapSize为当前进程所有虚拟机堆总和大小的限制。 | 182 183## 获取应用Trace记录信息 184 185HiTrace提供业务流程调用链跟踪的维测接口,帮助开发者获取指定业务流程调用链的运行日志,定位跨设备、跨进程、跨线程的故障问题。详情请参考[Trace性能跟踪](hitracemeter-intro.md)。为了便于实现HiTrace的自动化采集,HiDebug模块提供了启动和停止HiTrace采集的接口。 186 187### 接口说明(ArkTS) 188 189| 接口名 | 描述 | 190| -------- | -------- | 191| hidebug.startAppTraceCapture | 启动应用Trace采集。 | 192| hidebug.stopAppTraceCapture | 停止应用Trace采集。 | 193 194### 接口说明(C/C++) 195 196| 接口名 | 描述 | 197| -------- | -------- | 198| OH_HiDebug_StartAppTraceCapture | 启动应用Trace采集。 | 199| OH_HiDebug_StopAppTraceCapture | 停止应用Trace采集。 | 200 201## 启动虚拟机CpuProfiler采集 202 203HiDebug提供了开启和停止VM虚拟机CpuProfiler采集的接口,帮助开发者实现CpuProfiler的自动采集。 204 205### 接口说明(ArkTS) 206 207| 接口名 | 描述 | 208| -------- | -------- | 209| hidebug.startJsCpuProfiling | 启动虚拟机Profiling方法跟踪。 | 210| hidebug.stopJsCpuProfiling | 停止虚拟机Profiling方法跟踪。 | 211 212## 获取调用栈 213 214获取方法的调用栈信息对于调试和错误处理非常有用。调用栈信息帮助开发者了解方法的调用顺序和调用者的信息。HiDebug开放了获取调用栈信息的接口,便于开发者获取调用栈信息。 215 216### 栈回溯原理 217 218ARM64架构函数栈帧的结构如下图所示: 219 220**图1** 221 222 223FP:栈顶指针,指向一个栈帧的顶部,当函数发生跳转时,会记录当时的栈的起始位置。 224 225SP:栈指针(也称为栈底指针),指向栈当前的位置。 226 227LR:保存函数返回的地址。 228 229如图,与FP相邻的地址分别保存了上一帧的FP地址和当前帧的函数返回地址。进行栈回溯时,通过函数返回地址解析上一帧的栈信息,并根据上一帧的FP地址,依次找出每个函数栈帧中存储的LR和FP地址。基于FP回栈的特性,在当前调用函数中只能获取当前函数的返回地址进行栈解析,因此无法获取当前函数的调用栈信息。 230 231### 接口说明(C/C++) 232 233| 接口名 | 描述 | 234| -------- | -------- | 235| OH_HiDebug_CreateBacktraceObject | 创建一个用于栈回溯及栈解析的对象。<br/>说明:从API version 20开始,支持该接口。 | 236| OH_HiDebug_DestroyBacktraceObject | 销毁OH_HiDebug_CreateBacktraceObject接口创建的用于栈回溯及栈解析对象。<br/>说明:从API version 20开始,支持该接口。 | 237| OH_HiDebug_BacktraceFromFp | 获取从给定的栈帧指针开始的回溯帧。<br/>说明:从API version 20开始,支持该接口。 | 238| OH_HiDebug_SymbolicAddress | 通过给定的程序计数器(PC)获取详细的符号信息。<br/>说明:从API version 20开始,支持该接口。 | 239 240## 设置资源泄露检测阈值 241 242HiDebug提供设置系统资源泄露检测阈值的接口,开发者可根据业务需求自定义资源泄露事件触发的阈值。此接口主要用于辅助内存泄漏检测和功能开发,详情请参考[资源泄漏检测](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/resource-leak-guidelines)。 243 244### 接口说明(ArkTS) 245 246| 接口名 | 描述 | 247| -------- | -------- | 248| hidebug.setAppResourceLimit | 设置应用的fd数量、线程数量、js内存或者native内存等资源触发资源泄露检测事件的阈值。 | 249 250## 管理GWP-ASan 251 252HiDebug提供了启停[GWP-ASan](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-stability-gwpasan-detection)使能和查询使能天数的能力。 253 254### 接口说明(ArkTS) 255 256| 接口名 | 描述 | 257| -------- | -------- | 258| hidebug.enableGwpAsanGrayscale | 使能GWP-ASan,用于检测堆内存使用中的非法行为。 | 259| hidebug.disableGwpAsanGrayscale | 停止使能GWP-ASan。 | 260| hidebug.getGwpAsanGrayscaleState | 获取当前GWP-ASan剩余使能天数。 | 261 262## 其他 263 264HiDebug提供了获取应用调试状态和启动系统进程DUMP信息采集等功能。 265 266### 接口说明(ArkTS) 267 268| 接口名 | 描述 | 269| -------- | -------- | 270| hidebug.isDebugState | 获取应用进程被调试状态。如果应用进程的Ark层或Native层处于调试状态,返回true;否则返回false。 | 271| hidebug.getServiceDump | 获取系统服务的DUMP信息,仅系统应用可调用。 | 272 273## 常见问题 274 275**在使用OH_HiDebug_StartAppTraceCapture和startAppTraceCapture接口抓取HiTrace日志时,接口返回路径为设备内物理路径** 276 277接口返回的路径为设备内的真实物理路径,如需要在应用内访问,请参考[应用沙箱路径和真实物理路径的对应关系](../file-management/app-sandbox-directory.md#应用沙箱路径和真实物理路径的对应关系),需将真实物理路径转化为沙箱路径。 278 279例如:/data/app/el2/100/log/com.example.myapplication/trace/com.example.myapplication_20250604_173158.trace -> /data/storage/el2/base/trace/com.example.myapplication_20250604_173158.trace 280 281**在使用OH_HiDebug_GetAppThreadCpuUsage与getAppThreadCpuUsage接口获取线程CPU使用率时,新创建线程的使用率为0** 282 283基于CPU使用率的计算方式,需要同时获取当前CPU运行统计数据和hiview每10秒周期性刷新的计算基准值。由于新创建的线程没有计算基准值,导致CPU使用率无法计算,默认返回0。 284