1# Main Thread Jank Event Overview 2 3## Introduction 4 5When the main thread of an application executes a time-consuming task, the user perceives the application freezing. However, if the freezing duration does not reach the freezing time limit, no error will be logged, which is inconvenient for you to locate the fault. To address this problem, the system provides a mechanism for detecting the task execution timeout in the main thread, which generates call stack sampling files or trace files for you to locate and analyze the task execution status of the main thread. 6 7You can use the **hiAppEvent** APIs to subscribe to the main thread jank event to obtain the debugging and maintenance information. 8 9- [Subscribing to Main Thread Jank Events (ArkTS)](hiappevent-watcher-mainthreadjank-events-arkts.md) 10- [Subscribing to Main Thread Jank Events (C/C++)](hiappevent-watcher-mainthreadjank-events-ndk.md) 11 12## Default Main Thread Jank Event Time Specifications 13 14When the main thread experiences a timeout between 150 ms and 450 ms, it triggers a call stack sampling. If the timeout exceeds 450 ms, it triggers a trace sampling. 15 161. Begin time 17 18 Stack sampling triggered by main thread Jank (150 ms < Main thread processing time < 450 ms): For the processes with the same PID, the call stack sampling for a main thread jank event can be triggered only once. If **Developer Options** is enabled, call stack sampling can be triggered once an hour. No timeout check is performed within 10s after the application starts. 19 20 Trace sampling triggered by main thread jank (Main thread processing time > 450 ms): For the processes with the same PID, the trace sampling for a main thread jank event can be triggered only once in a day. 21 22 > **NOTE** 23 > 24 > To enable the main thread checker to collect tracing data when a task times out, ensure that the nolog version is used and **Developer Options** is disabled 25 > 26 > You can go to **Settings** > **About phone** to check the software version. The log version ends with **log**. 27 > 28 > When **Developer Options** is disabled, DevEco Studio may be unavailable. Therefore, you are advised to install the application before disabling **Developer Options**. 29 302. Stack capture time 31 32 When the main thread jank event occurs, the main thread checker starts to check whether the jank event occurs again every 150 ms (1 ≤ number of check times ≤ 2). There are three cases: 33 34 (1) If a jank event is detected during the first check, the main thread checker starts stack sampling every 150 ms for 10 times. The stack sampling data is collected and an event is reported at the next interval. Then the check ends. 35 36  37 38 (2) If a jank event is detected during the second check, the main thread checker starts stack sampling every 150 ms for 10 times. The stack sampling data is collected and an event is reported at the next interval. Then the check ends. 39 40  41 42 (3) If no jank event is detected in the two checks, the check ends. 43 44  45 463. Trace capture time 47 48 After the function is called to capture tracing data, the main thread checker checks for a main thread jank event every 150 ms for 20 times. If a main thread jank event occurs in any of the 20 checks, the check ends in 3s and the tracing data is stored. 49 50 (1) No main thread jank event is detected. 51 52  53 54 (2) At least one main thread jank event is detected. 55 56  57 58## Customizing Stack Sampling Parameters 59 60The system provides the basic check function for the main thread jank event. However, if your application has special requirements for the check interval and collection times, you can customize parameters for stack sampling. 61 62For details about how to use the APIs, see [hiAppEvent.setEventConfig in Application Event Logging](../reference/apis-performance-analysis-kit/js-apis-hiviewdfx-hiappevent.md#hiappeventseteventconfig15). 63 64### Available APIs 65 66| API | Description | 67| -------------------------------------------------------------------------------------| -------------------------------------------- | 68| setEventConfig(name: string, config: Record<string, ParamType>): Promise\<void> | Sets the parameters of the main thread jank event that triggers the stack sampling. Currently, only the **MAIN_THREAD_JANK** event parameter can be customized. Therefore, the value of **name** is **MAIN_THREAD_JANK**. | 69 70### Setting Parameters 71 72You can use the API provided by HiAppEvent to customize the parameters for collecting the **MAIN_THREAD_JANK** event in **Record<string, ParamType>**. 73 74You can customize the specifications of the **MAIN_THREAD_JANK** event by setting the value of **log_type** (log collecting type of the **MAIN_THREAD_JANK** event). The specifications are as follows: 75 761. If **log_type** is set to the default value **0**, the stack sampling is triggered when the main thread processing time is greater than 150 ms but less than 450 ms, and the trace sampling is triggered when the main thread processing time exceeds 450 ms. If **log_type** has been set to **1** for capturing stack sampling data, the custom parameter is invalid. The setting example is as follows: 77 78 ```text 79 let params: Record<string, hiAppEvent.ParamType> = { 80 "log_type": "0" 81 }; 82 ``` 83 842. If **log_type** is set to **1**, you can customize the threshold parameters of the main thread jank event for triggering the stack sampling. You need to set the following parameters: 85 86 (1) **sample_interval**: sampling interval of the main thread jank event. The system performs the check based on the custom interval and uses the interval for the periodic check. The value range is [50, 500], in ms. The default value is 150 ms. 87 88 (2) **ignore_startup_time**: time window after thread startup during which no checks are performed. For the process that takes time to start, it is not necessary to capture the full stack. You can set this parameter to prevent the check from being performed within the custom startup time. The minimum value is 3s. The default value is 10s. 89 90 (3) **sample_count**: number of sampling times for the main thread jank event. After detecting that the main thread processing time exceeds the threshold, the system starts periodic stack sampling for **sample_count** times. The minimum value is 1. The maximum value can be calculated based on the custom value of **sample_interval** as follows: <br>**sample_count** ≤ (2500/**sample_interval** - 4) 91 92 > **NOTE** 93 > 94 > The value **2500** (ms) indicates the maximum time allowed for a main thread jank event to be reported after being detected. Therefore, the value of **sample_count** cannot be greater than the maximum value calculated based on the formula. 95 > 96 > The value **4** indicates the number of check intervals, that is, the first check interval, the twice second check intervals, and the interval for collecting and reporting stack information. 97 98 (4) **report_times_per_app**: number of sampling reporting times for the main thread jank event of the processes with the same PID of an application. This parameter can be set only once for the processes with the same PID. 99 100 > **NOTE** 101 > 102 > When **Developer Options** is enabled, the value range is [1, 3] times per hour. The default value is 1. 103 > 104 > When **Developer Options** is disabled, the value range is [1, 3] times per day. The default value is 1. 105 106 The setting example is as follows: 107 108 ```text 109 let params: Record<string, hiAppEvent.ParamType> = { 110 "log_type": "1", 111 "sample_interval": "100", 112 "ignore_startup_time": "11", 113 "sample_count": "21", 114 "report_times_per_app": "3", 115 }; 116 ``` 117 1183. If **log_type** is set to **2**, a trace sampling is triggered when the main thread processing time exceeds 450 ms. The setting example is as follows: 119 120 ```text 121 let params: Record<string, hiAppEvent.ParamType> = { 122 "log_type": "2" 123 }; 124 ``` 125 126## Main Thread Jank Event Specifications 127 1281. Log aging 129 130 Generally, the size of a stack file is 7 KB to 10 KB, and the size of a trace file is 1 MB to 5 MB. The **watchdog** directory in the application sandbox can hold files up to10 MB. If the total file size exceeds the limit, the user needs to manually delete files. The path to **watchdog** is **/data/app/el2/100/log/*app_bundle_name*/watchdog**. 131 1322. 133 134 You can obtain the log path from **external_logs**. 135 1363. Currently, stack capturing supports only the ARM64 architecture. The stack capture result contains both native frames and JS frames parsed. 137 138 An example of the stack capture result is as follows: 139 140 ```text 141 9 #00 pc 0000757c /system/bin/appspawn(55679d09bcdea35bb1e0d4e1d9a3e58f) 142 9 #01 pc 000731c0 /system/lib/ld-musl-aarch64.so.1(add9e521e4eaf5cb009d4260f3b69ccd) 143 9 #02 pc 000090a9 /system/bin/appspawn(main+396)(55679d09bcdea35bb1e0d4e1d9a3e58f) 144 9 #03 pc 0000ab5d /system/bin/appspawn(AppSpawnRun+100)(55679d09bcdea35bb1e0d4e1d9a3e58f) 145 9 #04 pc 0000e7f1 /system/lib/chipset-pub-sdk/libbegetutil.z.so(RunLoop_+200)(52ace27d827ad482439bf32cc75bb17b) 146 ...... 147 9 #21 pc 00107aec /system/lib/ld-musl-aarch64.so.1(__pthread_cond_timedwait+628)(add9e521e4eaf5cb009d4260f3b69ccd) 148 1 #00 pc 00032e67 /system/lib/platformsdk/libmmi-util.z.so(OHOS::MMI::UDSSocket::OnReadPackets(OHOS::MMI::CircleStreamBuffer&, std::__h::function<void (OHOS::MMI::NetPacket&)>)+158)(99e56bc765f9208f7b7ba8b268886a59) 149 1 #01 pc 0000312e5 /system/lib/platformsdk/libmmi-client.z.so(OHOS::MMI::ClientMsgHandler::OnMsgHandler(OHOS::MMI::UDSClient const&, OHOS::MMI::NetPacket&)+340)(66ac85e964777ae89f0c26c339093cd1) 150 1 #02 pc 0003016b /system/lib/platformsdk/libmmi-client.z.so(OHOS::MMI::ClientMsgHandler::OnPointerEvent(OHOS::MMI::UDSClient const&, OHOS::MMI::NetPacket&)+1222)(66ac85e964777ae89f0c26c339093cd1) 151 1 #03 pc 0003b96b /system/lib/platformsdk/libmmi-client.z.so(OHOS::MMI::InputManagerImpl::OnPointerEvent(std::__h::shared_ptr<OHOS::MMI::PointerEvent>)+1370)(66ac85e964777ae89f0c26c339093cd1) 152 1 #04 pc 00095903 /system/lib/platformsdk/libwm.z.so(OHOS::Rosen::InputEventListener::OnInputEvent(std::__h::shared_ptr<OHOS::MMI::PointerEvent>) const+478)(9c40c5f416d6f830435126998fbcad42) 153 ...... 154 1 #21 pc 003f5c55 /system/lib/platformsdk/libark_jsruntime.so(4e6a2651ec80a7f639233f414d6486fe) 155 1 #22 at anonymous (/entry/build/default/cache/default/default@CompileArkTS/esmodule/debug/entry/src/main/ets/pages/Index.js:67:17) 156 1 #23 at wait2 (/entry/build/default/cache/default/default@CompileArkTS/esmodule/debug/entry/src/main/ets/pages/Index.js:16:12) 157 ...... 158 ``` 159 160 Each time a stack is sampled, 16 KB of the call stack information of the main thread is captured for backtrace analysis. Therefore, each stack capture result contains a maximum of 16 KB call information of the process. The stack sampling is performed 10 times in total. The captured data is displayed in a tree view, with repeated stack frames aggregated and different call layers distinguished by line indentation. If the stack fails to be captured (for example, the main thread is blocked in the kernel or signals are masked), the content of the **/proc/self/wchan** file is output. 161 162 In the result, each row indicates a piece of stack information. The meaning of a row of stack frame information can be interpreted as follows: 163 164 Native frame: 165 166 ```text 167 9 #02 pc 000090a9 /system/bin/appspawn(main+396)(55679d09bcdea35bb1e0d4e1d9a3e58f) 168 ^ ^ ^ ^ ^ ^ 169 1 2 3 4 5 6 170 171 1 indicates the number of times that the frame is sampled. 172 2 indicates the call level of the frame. The line indentation size corresponds to this level. The number of sampling times of all frames at the same level cannot be greater than 10. The number of sampling times of #00 is 10 (sampling times specified). 173 3 indicates the Program Counter (PC) value of the native frame. 174 4 indicates the path of the called file. 175 5 indicates the name of the called function and code line offset (available in unstripped version, and may not available in stripped version). 176 6 indicates the MD5 value of the .so file. 177 ``` 178 179 JS frame: 180 181 ```text 182 1 #23 at wait2 (/entry/build/default/cache/default/XXX/entry/src/main/ets/pages/Index.js:16:12) 183 ^ ^ ^ ^ 184 1 2 3 4 185 186 1 indicates the number of times that the frame is sampled. The maximum value is the sampling times. 187 2 indicates the call level of the frame, which is the same as that of the native frame. 188 3 indicates the name of the called function, which is **wait2**. 189 4 indicates the path, file, row number, and column number of the called function. 190 ``` 191 1924. Trace specifications 193 194 The size of a trace file is 1 MB to 5 MB. You can parse the trace file using [SmartPerf](https://www.smartperf.host). 195 196 After a trace file is imported, the page displays the time axis, CPU usage, CPU load, IPC method calling, and process, thread, and method calling information from the top down. In this way, the data is displayed from the event dimension. 197 198 For details about how to use trace files, see [How to Load Trace Files on the Web Client](https://gitee.com/openharmony/developtools_smartperf_host/blob/master/ide/src/doc/md/quickstart_systemtrace.md). 199 200## params 201 202| Name | Type | Description | 203| ------- | ------ | ------------------------- | 204| time | number | Event triggering time, in ms.| 205| bundle_version | string | Application version.| 206| bundle_name | string | Application name.| 207| pid | number | Process ID of the application.| 208| uid | number | User ID of the application.| 209| begin_time | number | Begin time of a task in the main thread.| 210| end_time | number | End time of a task in the main thread.| 211| external_log| string[] | Path of the generated log files. If the directory files exceed the threshold (for details, see **log_over_limit**), new log files may fail to be written. Therefore, delete the log files immediately after they are processed.| 212| log_over_limit| boolean | Whether the size of generated log files and existing log files exceeds the upper limit (10 MB). The value **true** indicates that the upper limit is exceeded and logs fail to be written. The value **false** indicates that the upper limit is not exceeded.| 213| app_start_jiffies_time| number | Start time of the task when the main thread jank event occurs. The information is printed in the sampling stack.| 214| heaviest_stack| string | Call stack that is generated multiple times in the log file. The information is printed in the sampling stack.| 215 216<!--no_check-->