1e41f4b71Sopenharmony_ci# Analyzing Cpp Crash
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciA cpp crash refers to a process crash in C/C++ application. The FaultLogger module provides capabilities such as process crash detection, log collection, log storage, and log reporting, helping you to locate faults more effectively.
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciThe following introduces cpp crash detection, crash fault locating and analysis, and typical cases. To use this guideline, you need to have basic knowledge about stack and heap in C/C++.
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci## Cpp Crash Detection
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ciProcess crash detection is based on the posix signal mechanism. Currently, the exception signals that can be processed are as follows:
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci| Signo| Signal| Description| Trigger Cause|
12e41f4b71Sopenharmony_ci| -------- | -------- | -------- | -------- |
13e41f4b71Sopenharmony_ci| 4 | SIGILL | Invalid instruction| An invalid, incorrectly formatted, unknown, or privileged instruction is executed.|
14e41f4b71Sopenharmony_ci| 5 | SIGTRAP | Breakpoint or trap| An exception occurs or a trap instruction is executed.|
15e41f4b71Sopenharmony_ci| 6 | SIGABRT | Process abort| The process is aborted abnormally. Generally, this exception occurs when the process calls **abort()** in the Standard Function Library.|
16e41f4b71Sopenharmony_ci| 7 | SIGBUS | Illegal memory access| The process accesses an aligned or nonexistent physical address.|
17e41f4b71Sopenharmony_ci| 8 | SIGFPE | Floating-point exception| An incorrect arithmetic operation is executed, for example, a 0 divisor, floating point overflow, or integer overflow.|
18e41f4b71Sopenharmony_ci| 11 | SIGSEGV | Invalid memory access| The process accesses an invalid memory region.|
19e41f4b71Sopenharmony_ci| 16 | SIGSTKFLT | Stack error| The processor performs an incorrect stack operation, such as a pop when the stack is empty or a push when the stack is full.|
20e41f4b71Sopenharmony_ci| 31 | SIGSYS | Incorrect system call| An incorrect or invalid parameter is used in a system call.|
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ciSome of the preceding fault signals are classified into codes based on specific scenarios.
23e41f4b71Sopenharmony_ci**SIGILL** occurs in Unix and Unix-like operating systems. It indicates an invalid instruction exception. The **SIGILL** signal is usually triggered by the following causes:
24e41f4b71Sopenharmony_ci| No.| Code| Description| Trigger Cause|
25e41f4b71Sopenharmony_ci| -------- | -------- | -------- | -------- |
26e41f4b71Sopenharmony_ci| 1 | ILL_ILLOPC | Illegal operation code| A privileged instruction or an instruction that is unsupported by the CPU is executed.|
27e41f4b71Sopenharmony_ci| 2 | ILL_ILLOPN | Illegal operand| An incorrect operand or improper operand type is used.|
28e41f4b71Sopenharmony_ci| 3 | ILL_ILLADR | Illegal address| A program accesses an invalid memory address or an unaligned memory address.|
29e41f4b71Sopenharmony_ci| 4 | ILL_ILLTRP | Illegal trap| A program performs an illegal trap instruction or an undefined operation.|
30e41f4b71Sopenharmony_ci| 5 | ILL_PRVOPC | Illegal privileged operation code| A common user executes a privileged instruction.|
31e41f4b71Sopenharmony_ci| 6 | ILL_PRVREG | Illegal privileged register| A common user accesses a privileged register.|
32e41f4b71Sopenharmony_ci| 7 | ILL_COPROC | Illegal coprocessor| A program performs an undefined coprocessor instruction.|
33e41f4b71Sopenharmony_ci| 8 | ILL_BADSTK | Illegal stack| A program performs an operation at an invalid stack address, or when the stack overflows.|
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_ci**SIGTRAP** usually occurs in debugging and tracking. The four scenarios of the **SIGTRAP** signal are described as follows.
36e41f4b71Sopenharmony_ci| No.| Code| Description| Trigger Cause|
37e41f4b71Sopenharmony_ci| -------- | -------- | -------- | -------- |
38e41f4b71Sopenharmony_ci| 1 | TRAP_BRKPT | Software breakpoint| The software breakpoint is reached in a program. When debugging a program, a software breakpoint at the key position can be used to pause the program execution and check information such as variable values.|
39e41f4b71Sopenharmony_ci| 2 | TRAP_TRACE | Single-step debugging| A single instruction is executed in a program. Single instruction can be used to check the execution result of each instruction.|
40e41f4b71Sopenharmony_ci| 3 | TRAP_BRANCH | Branch Tracing| A branch instruction is executed in a program. Branch instruction can be used to control the execution process of a program, such as if statements and loop statements.|
41e41f4b71Sopenharmony_ci| 4 | TRAP_HWBKPT | Hardware breakpoint| The hardware breakpoint is reached in a program. When debugging a program, a hardware breakpoint at the key position can be used to pause the program execution and check information such as variable values. Different from a software breakpoint, a hardware breakpoint is implemented in CPU hardware. Therefore, whether a hardware breakpoint is triggered can be detected in real time during program execution.|
42e41f4b71Sopenharmony_ci
43e41f4b71Sopenharmony_ciThe **SIGBUS** signal is sent by the operating system to a process. It usually indicates a memory access error. The codes of the **SIGBUS** signal are described as follows:
44e41f4b71Sopenharmony_ci| No.| Code| Description| Trigger Cause|
45e41f4b71Sopenharmony_ci| -------- | -------- | -------- | -------- |
46e41f4b71Sopenharmony_ci| 1 | BUS_ADRALN | Unaligned memory address| A program accesses an unaligned memory address, for example, a non-even address of a 4-byte integer.|
47e41f4b71Sopenharmony_ci| 2 | BUS_ADRERR | Invalid memory address| A program accesses a memory address that does not exist in the Process Address Space, such as a null pointer.|
48e41f4b71Sopenharmony_ci| 3 | BUS_OBJERR | Invalid object access| A program accesses an object that is deleted or not initialized.|
49e41f4b71Sopenharmony_ci| 4 | BUS_MCEERR_AR | Invalid hardware memory check| A checksum error is detected when the hardware memory is accessed.|
50e41f4b71Sopenharmony_ci| 5 | BUS_MCEERR_AO | Invalid hardware memory check| An address check error is detected when the hardware memory is accessed.|
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_ciThe **SIGFPE** signal indicates a floating-point exception or an arithmetic exception. The codes of the **SIGFPE** signal are described as follows:
53e41f4b71Sopenharmony_ci| No.| Code| Description| Trigger Cause|
54e41f4b71Sopenharmony_ci| -------- | -------- | -------- | -------- |
55e41f4b71Sopenharmony_ci| 1 | FPE_INTDIV | Invalid integer division| The divisor in an integer division is zero.  |
56e41f4b71Sopenharmony_ci| 2 | FPE_INTOVF | Integer overflow| The divisor in an integer division is negative.  |
57e41f4b71Sopenharmony_ci| 3 | FPE_FLTDIV | Invalid floating-point division| The divisor in a floating-point division is zero.  |
58e41f4b71Sopenharmony_ci| 4 | FPE_FLTOVF | Floating-point overflow| The divisor in a floating-point division is negative.  |
59e41f4b71Sopenharmony_ci| 5 | FPE_FLTUND | Floating-point underflow| The divisor in a floating-point division is zero.  |
60e41f4b71Sopenharmony_ci| 6 | FPE_FLTRES | Invalid floating-point result| The divisor in a floating-point division is positive.  |
61e41f4b71Sopenharmony_ci| 7 | FPE_FLTINV | Invalid floating-point operation| The divisor in a floating-point division is negative.  |
62e41f4b71Sopenharmony_ci| 8 | FPE_FLTSUB | Floating-point trap| The divisor in a floating-point division is zero.  |
63e41f4b71Sopenharmony_ci
64e41f4b71Sopenharmony_ciThe **SIGSEGV** signal occurs when a process accesses a non-existent memory address or an inaccessible address. The codes of the **SIGSEGV** signal are described as follows:
65e41f4b71Sopenharmony_ci| No.| Code| Description| Trigger Cause|
66e41f4b71Sopenharmony_ci| -------- | -------- | -------- | -------- |
67e41f4b71Sopenharmony_ci| 1 | SEGV_MAPERR | Non-existent memory address| A process accesses a memory address that does not exist or that is not mapped to the Process Address Space. This exception is usually caused by pointer errors or memory leaks.|
68e41f4b71Sopenharmony_ci| 2 | SEGV_ACCERR | Inaccessible memory address| A process accesses an inaccessible memory address marked by the operating system, such as a read-only memory address or a memory address without execution permission. This exception is usually caused by buffer overflow or modifying read-only memory.|
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ciThe classification of codes cannot only be based on **signo**, but also be based on the causes of the signal. The preceding describes the codes classified based on the **signo** of each signal, while the following describes the codes classified based on causes of all signals:
71e41f4b71Sopenharmony_ci| No.| Code| Description| Trigger Cause|
72e41f4b71Sopenharmony_ci| -------- | -------- | -------- | -------- |
73e41f4b71Sopenharmony_ci| 0 | SI_USER | User space signal|This signal is sent by a process in user space to another process, usually using the **kill()**. For example, when a user presses **Ctrl+C** on the terminal, a **SIGINT** signal is sent to all foreground processes.|
74e41f4b71Sopenharmony_ci| 0x80 | SI_KERNEL | Kernel signal|This signal is sent by the kernel to the process. It is usually sent when the kernel detects some errors or exceptions. For example, when a process accesses an invalid memory address or executes an invalid instruction, the kernel sends a **SIGSEGV** signal to the process.|
75e41f4b71Sopenharmony_ci| -1 | SI_QUEUE | **sigqueue()** signal|This signal is sent by **sigqueue()**, and an additional integer value and a pointer can be carried. It is usually used for advanced communication between processes, such as transferring data or notifying a process that an event occurs.|
76e41f4b71Sopenharmony_ci| -2 | SI_TIMER | Timer signal|This signal is sent by a timer and is usually used to execute a scheduled task or a periodic task. For example, when a timer expires, the kernel sends a **SIGALRM** signal to the process.|
77e41f4b71Sopenharmony_ci| -3 | SI_MESGQ | Message queue signal|This signal is sent by a message queue and is usually used for communication across processes. For example, when a process sends a message to a message queue, the kernel sends a **SIGIO** signal to the receiving process.|
78e41f4b71Sopenharmony_ci| -4 | SI_ASYNCIO | Asynchronous I/O signal|This signal is sent by an asynchronous I/O and is usually used for a non-blocking I/O. For example, when an I/O operation on a file descriptor is complete, the kernel sends a **SIGIO** signal to the process.|
79e41f4b71Sopenharmony_ci| -5 | SI_SIGIO | Synchronous I/O signal|This signal is sent by a synchronous I/O and is usually used for a non-blocking I/O. For example, when an I/O operation on a file descriptor is complete, the kernel sends a **SIGIO** signal to the process.|
80e41f4b71Sopenharmony_ci| -6 | SI_TKILL | **tkill()** signal|This signal is sent by the function **tkill()**, which is similar to the function **kill()**. In addition, you can specify the ID of the thread that sends the signal. It is usually used to send a signal to a specified thread in a multithreaded program.|
81e41f4b71Sopenharmony_ci
82e41f4b71Sopenharmony_ci## Fault Analysis
83e41f4b71Sopenharmony_ci
84e41f4b71Sopenharmony_ci### Crash Log Collection
85e41f4b71Sopenharmony_ci
86e41f4b71Sopenharmony_ciThe process crash log is managed together with the app freeze and JS crash logs by the FaultLogger module. You can obtain process crash logs using any of the following methods:
87e41f4b71Sopenharmony_ci
88e41f4b71Sopenharmony_ci- Method 1: DevEco Studio
89e41f4b71Sopenharmony_ci
90e41f4b71Sopenharmony_ci    DevEco Studio collects process crash logs from **/data/log/faultlog/faultlogger/** to FaultLog, where logs are displayed by process name, fault, and time. For details about how to obtain logs, see <!--RP1-->[DevEco Studio User Guide-FaultLog](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-fault-log-V5)<!--RP1End-->.
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ci- Method 2: hiAppEvent APIs
93e41f4b71Sopenharmony_ci
94e41f4b71Sopenharmony_ci    hiAppEvent provides APIs to subscribe to various fault logs. For details, see [Introduction to HiAppEvent](hiappevent-intro.md).
95e41f4b71Sopenharmony_ci
96e41f4b71Sopenharmony_ci<!--Del-->
97e41f4b71Sopenharmony_ci- Method 3: Shell
98e41f4b71Sopenharmony_ci
99e41f4b71Sopenharmony_ci    - When a process crashes, you can find fault logs in **/data/log/faultlog/temp/** on the device. The log files are named in the format of **cppcrash-process PID-timestamp (millisecond)**. They contain information such as the process crash call stack, process crash register, stack memory, maps, and process file handle list.
100e41f4b71Sopenharmony_ci
101e41f4b71Sopenharmony_ci        ![cppcrash-temp-log](figures/20230407111853.png)
102e41f4b71Sopenharmony_ci
103e41f4b71Sopenharmony_ci    - You can find more comprehensive fault logs in **/data/log/faultlog/faultlogger/**, which include information such as device name, system version and process logs. The log files are named in the format of **cppcrash-process name-process UID-time (second)**.
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ci        ![cppcrash-faultlogger-log](figures/20230407112159.png)
106e41f4b71Sopenharmony_ci
107e41f4b71Sopenharmony_ci<!--DelEnd-->
108e41f4b71Sopenharmony_ci**Fault Logs of Null Pointer**
109e41f4b71Sopenharmony_ciIn this scenario, a message is printed in the log, indicating that the fault may be caused by null pointer dereference.
110e41f4b71Sopenharmony_ciThe following is the core content of a process crash log archived by DevEco Studio in FaultLog. The content is the same as that archived in /**data/log/faultlog/faultlogger**.
111e41f4b71Sopenharmony_ci
112e41f4b71Sopenharmony_ci```
113e41f4b71Sopenharmony_ciGenerated by HiviewDFX@OpenHarmony
114e41f4b71Sopenharmony_ci================================================================
115e41f4b71Sopenharmony_ciDevice info:OpenHarmony 3.2        <- Device information
116e41f4b71Sopenharmony_ciBuild info:OpenHarmony 5.0.0.23    <- Build information
117e41f4b71Sopenharmony_ciFingerprint:cdf52fd0cc328fc432459928f3ed8edfe8a72a92ee7316445143bed179138073 <- Fingerprint
118e41f4b71Sopenharmony_ciModule name:crasher_cpp            <-Module name
119e41f4b71Sopenharmony_ciTimestamp:2024-05-06 20:10:51.000  <- Timestamp when the fault occurs
120e41f4b71Sopenharmony_ciPid:9623   <- Process ID
121e41f4b71Sopenharmony_ciUid:0         <- User ID
122e41f4b71Sopenharmony_ciProcess name:./crasher_cpp         <- Process name
123e41f4b71Sopenharmony_ciProcess life time:1s               <- Process life time
124e41f4b71Sopenharmony_ciReason:Signal:SIGSEGV(SEGV_MAPERR)@0x00000004 probably caused by NULL pointer dereference  <- Fault cause and null pointer prompt
125e41f4b71Sopenharmony_ciFault thread info:
126e41f4b71Sopenharmony_ciTid:9623, Name:crasher_cpp         <- Thread ID, thread name
127e41f4b71Sopenharmony_ci#00 pc 00008d22 /system/bin/crasher_cpp(TestNullPointerDereferenceCrash0()+22)(adfc673300571d2da1e47d1d12f48b44)  <- Call stack
128e41f4b71Sopenharmony_ci#01 pc 000064d1 /system/bin/crasher_cpp(DfxCrasher::ParseAndDoCrash(char const*) const+160)(adfc673300571d2da1e47d1d12f48b44)
129e41f4b71Sopenharmony_ci#02 pc 00006569 /system/bin/crasher_cpp(main+92)(adfc673300571d2da1e47d1d12f48b44)
130e41f4b71Sopenharmony_ci#03 pc 00072b98 /system/lib/ld-musl-arm.so.1(libc_start_main_stage2+56)(d820b1827e57855d4f9ed03ba5dfea83)
131e41f4b71Sopenharmony_ci#04 pc 00004e28 /system/bin/crasher_cpp(_start_c+84)(adfc673300571d2da1e47d1d12f48b44)
132e41f4b71Sopenharmony_ci#05 pc 00004dcc /system/bin/crasher_cpp(adfc673300571d2da1e47d1d12f48b44)
133e41f4b71Sopenharmony_ciRegisters:   <- Fault registers
134e41f4b71Sopenharmony_cir0:ffffafd2 r1:00000004 r2:00000001 r3:00000000
135e41f4b71Sopenharmony_cir4:ffd27e39 r5:0096e000 r6:00000a40 r7:0096fdfc
136e41f4b71Sopenharmony_cir8:f7ba58d5 r9:f7baea86 r10:f7cadd38
137e41f4b71Sopenharmony_cifp:ffd27308 ip:f7cb2078 sp:ffd272a0 lr:f7c7ab98 pc:0096ad22
138e41f4b71Sopenharmony_ciMemory near registers:  <- Memory near fault registers
139e41f4b71Sopenharmony_cir4([stack]):
140e41f4b71Sopenharmony_ci    ffd27e30 72656873
141e41f4b71Sopenharmony_ci    ffd27e34 7070635f
142e41f4b71Sopenharmony_ci    ...
143e41f4b71Sopenharmony_ci    ffd27eac 3d73746f
144e41f4b71Sopenharmony_cir5(/system/bin/crasher_cpp):
145e41f4b71Sopenharmony_ci    0096dff8 00000000
146e41f4b71Sopenharmony_ci    0096dffc 0096717d
147e41f4b71Sopenharmony_ci    ...
148e41f4b71Sopenharmony_ci    0096e074 00000000
149e41f4b71Sopenharmony_cir7(/system/lib/ld-musl-arm.so.1):
150e41f4b71Sopenharmony_ci    f7cabb58 00000000
151e41f4b71Sopenharmony_ci    f7cabb5c 0034ba00
152e41f4b71Sopenharmony_ci    ...
153e41f4b71Sopenharmony_ci    f7cabbd4 00000000
154e41f4b71Sopenharmony_cir8(/system/lib/ld-musl-arm.so.1):
155e41f4b71Sopenharmony_ci    f7ba58cc 63637573
156e41f4b71Sopenharmony_ci    f7ba58d0 2e737365
157e41f4b71Sopenharmony_ci    ...
158e41f4b71Sopenharmony_ci    f7ba5948 70206269
159e41f4b71Sopenharmony_cir9(/system/lib/ld-musl-arm.so.1):
160e41f4b71Sopenharmony_ci    f7baea7c 20746f6e
161e41f4b71Sopenharmony_ci    f7baea80 6e756f66
162e41f4b71Sopenharmony_ci    ...
163e41f4b71Sopenharmony_ci    f7baeaf8 25206e69
164e41f4b71Sopenharmony_cir10([anon:ld-musl-arm.so.1.bss]):
165e41f4b71Sopenharmony_ci    f7cadd30 00000000
166e41f4b71Sopenharmony_ci    f7cadd34 00000000
167e41f4b71Sopenharmony_ci    ...
168e41f4b71Sopenharmony_ci    f7caddac 00000000
169e41f4b71Sopenharmony_cir12([anon:ld-musl-arm.so.1.bss]):
170e41f4b71Sopenharmony_ci    f7cb2070 56726562
171e41f4b71Sopenharmony_ci    f7cb2074 65756c61
172e41f4b71Sopenharmony_ci    ...
173e41f4b71Sopenharmony_ci    f7cb20ec 00000000
174e41f4b71Sopenharmony_cisp([stack]):
175e41f4b71Sopenharmony_ci    ffd27328 00000000
176e41f4b71Sopenharmony_ci    ffd2732c 00966dd0
177e41f4b71Sopenharmony_ci    ...
178e41f4b71Sopenharmony_ci    ffd273a4 00000004
179e41f4b71Sopenharmony_cipc(/system/bin/crasher_cpp):
180e41f4b71Sopenharmony_ci    00966dc8 e1a0d00c
181e41f4b71Sopenharmony_ci    00966dcc eb000000
182e41f4b71Sopenharmony_ci    ...
183e41f4b71Sopenharmony_ci    00966e44 e5907008
184e41f4b71Sopenharmony_cipc(/system/bin/crasher_cpp):
185e41f4b71Sopenharmony_ci    00966dc8 e1a0d00c
186e41f4b71Sopenharmony_ci    00966dcc eb000000
187e41f4b71Sopenharmony_ci    ...
188e41f4b71Sopenharmony_ci    00966e44 e5907008
189e41f4b71Sopenharmony_ciFaultStack:  <- Stack of the crashed thread
190e41f4b71Sopenharmony_ci    ffd27260 00000000
191e41f4b71Sopenharmony_ci    ffd27264 f7cac628
192e41f4b71Sopenharmony_ci    ...
193e41f4b71Sopenharmony_ci    ffd2729c 0096ad1f
194e41f4b71Sopenharmony_cisp0:ffd272a0 0096fdfc <- #00Stack top
195e41f4b71Sopenharmony_ci    ffd272a4 009684d3
196e41f4b71Sopenharmony_cisp1:ffd272a8 00000001
197e41f4b71Sopenharmony_ci    ffd272ac 73657408
198e41f4b71Sopenharmony_ci    ffd272b0 f7590074
199e41f4b71Sopenharmony_ci    ...
200e41f4b71Sopenharmony_ci    ffd272dc 0096856d
201e41f4b71Sopenharmony_cisp2:ffd272e0 ffd27334
202e41f4b71Sopenharmony_ci    ffd272e4 ffd27334
203e41f4b71Sopenharmony_ci    ffd272e8 00000002
204e41f4b71Sopenharmony_ci    ....
205e41f4b71Sopenharmony_ci    ffd272f4 f7bfbb9c
206e41f4b71Sopenharmony_cisp3:ffd272f8 00000000
207e41f4b71Sopenharmony_ci    ffd272fc ffd27334
208e41f4b71Sopenharmony_ci
209e41f4b71Sopenharmony_ciMaps:   <- Process maps files when the fault occurs
210e41f4b71Sopenharmony_ci962000-966000 r--p 00000000 /system/bin/crasher_cpp
211e41f4b71Sopenharmony_ci966000-96c000 r-xp 00003000 /system/bin/crasher_cpp
212e41f4b71Sopenharmony_ci96c000-96f000 r--p 00008000 /system/bin/crasher_cpp
213e41f4b71Sopenharmony_ci96f000-970000 rw-p 0000a000 /system/bin/crasher_cpp
214e41f4b71Sopenharmony_ci149f000-14a0000 ---p 00000000 [heap]
215e41f4b71Sopenharmony_ci14a0000-14a2000 rw-p 00000000 [heap]
216e41f4b71Sopenharmony_ci...
217e41f4b71Sopenharmony_cif7b89000-f7be1000 r--p 00000000 /system/lib/ld-musl-arm.so.1
218e41f4b71Sopenharmony_cif7be1000-f7ca9000 r-xp 00057000 /system/lib/ld-musl-arm.so.1
219e41f4b71Sopenharmony_cif7ca9000-f7cab000 r--p 0011e000 /system/lib/ld-musl-arm.so.1
220e41f4b71Sopenharmony_cif7cab000-f7cad000 rw-p 0011f000 /system/lib/ld-musl-arm.so.1
221e41f4b71Sopenharmony_cif7cad000-f7cbc000 rw-p 00000000 [anon:ld-musl-arm.so.1.bss]
222e41f4b71Sopenharmony_ciffd07000-ffd28000 rw-p 00000000 [stack]
223e41f4b71Sopenharmony_ciffff0000-ffff1000 r-xp 00000000 [vectors]
224e41f4b71Sopenharmony_ciOpenFiles:   <- FD information of the file opened by the process when the fault occurs
225e41f4b71Sopenharmony_ci0->/dev/pts/1 native object of unknown type 0
226e41f4b71Sopenharmony_ci1->/dev/pts/1 native object of unknown type 0
227e41f4b71Sopenharmony_ci2->/dev/pts/1 native object of unknown type 0
228e41f4b71Sopenharmony_ci3->socket:[67214] native object of unknown type 0
229e41f4b71Sopenharmony_ci...
230e41f4b71Sopenharmony_ci11->pipe:[67219] native object of unknown type 0
231e41f4b71Sopenharmony_ci12->socket:[29074] native object of unknown type 0
232e41f4b71Sopenharmony_ci25->/dev/ptmx native object of unknown type 0
233e41f4b71Sopenharmony_ci26->/dev/ptmx native object of unknown type 0
234e41f4b71Sopenharmony_ci
235e41f4b71Sopenharmony_ciHiLog:   <- Hilog logs when the fault occurs
236e41f4b71Sopenharmony_ci05-06 20:10:51.301  9623  9623 E C03f00/MUSL-SIGCHAIN: signal_chain_handler call 2 rd sigchain action for signal: 11
237e41f4b71Sopenharmony_ci05-06 20:10:51.306  9623  9623 I C02d11/DfxSignalHandler: DFX_SigchainHandler :: sig(11), pid(9623), tid(9623).
238e41f4b71Sopenharmony_ci05-06 20:10:51.307  9623  9623 I C02d11/DfxSignalHandler: DFX_SigchainHandler :: sig(11), pid(9623), processName(./crasher_cpp), threadName(crasher_cpp).
239e41f4b71Sopenharmony_ci05-06 20:10:51.389  9623  9623 I C02d11/DfxSignalHandler: processdump have get all resgs
240e41f4b71Sopenharmony_ci
241e41f4b71Sopenharmony_ci```
242e41f4b71Sopenharmony_ci
243e41f4b71Sopenharmony_ci<!--Del-->
244e41f4b71Sopenharmony_ciThe fault logs obtained using Shell in **/data/log/faultlog/temp** is as follows:
245e41f4b71Sopenharmony_ci
246e41f4b71Sopenharmony_ci```
247e41f4b71Sopenharmony_ciTimestamp:2024-05-06 20:10:51.000  <- Timestamp when the fault occurs
248e41f4b71Sopenharmony_ciPid:9623                           <- Process ID
249e41f4b71Sopenharmony_ciUid:0                              <- User ID
250e41f4b71Sopenharmony_ciProcess name:./crasher_cpp         <- Process name
251e41f4b71Sopenharmony_ciProcess life time:1s               <- Process life time
252e41f4b71Sopenharmony_ciReason:Signal:SIGSEGV(SEGV_MAPERR)@0x00000004 probably caused by NULL pointer dereference <-  Fault cause and null pointer prompt
253e41f4b71Sopenharmony_ciFault thread info:
254e41f4b71Sopenharmony_ciTid:9623, Name:crasher_cpp         <- Thread ID, thread name
255e41f4b71Sopenharmony_ci#00 pc 00008d22 /system/bin/crasher_cpp(TestNullPointerDereferenceCrash0()+22)(adfc673300571d2da1e47d1d12f48b44) <- Call stack
256e41f4b71Sopenharmony_ci#01 pc 000064d1 /system/bin/crasher_cpp(DfxCrasher::ParseAndDoCrash(char const*) const+160)(adfc673300571d2da1e47d1d12f48b44)
257e41f4b71Sopenharmony_ci#02 pc 00006569 /system/bin/crasher_cpp(main+92)(adfc673300571d2da1e47d1d12f48b44)
258e41f4b71Sopenharmony_ci#03 pc 00072b98 /system/lib/ld-musl-arm.so.1(libc_start_main_stage2+56)(d820b1827e57855d4f9ed03ba5dfea83)
259e41f4b71Sopenharmony_ci#04 pc 00004e28 /system/bin/crasher_cpp(_start_c+84)(adfc673300571d2da1e47d1d12f48b44)
260e41f4b71Sopenharmony_ci#05 pc 00004dcc /system/bin/crasher_cpp(adfc673300571d2da1e47d1d12f48b44)
261e41f4b71Sopenharmony_ciRegisters:   <- Fault registers
262e41f4b71Sopenharmony_cir0:ffffafd2 r1:00000004 r2:00000001 r3:00000000
263e41f4b71Sopenharmony_cir4:ffd27e39 r5:0096e000 r6:00000a40 r7:0096fdfc
264e41f4b71Sopenharmony_cir8:f7ba58d5 r9:f7baea86 r10:f7cadd38
265e41f4b71Sopenharmony_cifp:ffd27308 ip:f7cb2078 sp:ffd272a0 lr:f7c7ab98 pc:0096ad22
266e41f4b71Sopenharmony_ciMemory near registers:  <-  Memory near fault registers
267e41f4b71Sopenharmony_cir4([stack]):
268e41f4b71Sopenharmony_ci    ffd27e30 72656873
269e41f4b71Sopenharmony_ci    ffd27e34 7070635f
270e41f4b71Sopenharmony_ci    ...
271e41f4b71Sopenharmony_ci    ffd27eac 3d73746f
272e41f4b71Sopenharmony_cir5(/system/bin/crasher_cpp):
273e41f4b71Sopenharmony_ci    0096dff8 00000000
274e41f4b71Sopenharmony_ci    0096dffc 0096717d
275e41f4b71Sopenharmony_ci    ...
276e41f4b71Sopenharmony_ci    0096e074 00000000
277e41f4b71Sopenharmony_cir7(/system/lib/ld-musl-arm.so.1):
278e41f4b71Sopenharmony_ci    f7cabb58 00000000
279e41f4b71Sopenharmony_ci    f7cabb5c 0034ba00
280e41f4b71Sopenharmony_ci    ...
281e41f4b71Sopenharmony_ci    f7cabbd4 00000000
282e41f4b71Sopenharmony_cir8(/system/lib/ld-musl-arm.so.1):
283e41f4b71Sopenharmony_ci    f7ba58cc 63637573
284e41f4b71Sopenharmony_ci    f7ba58d0 2e737365
285e41f4b71Sopenharmony_ci    ...
286e41f4b71Sopenharmony_ci    f7ba5948 70206269
287e41f4b71Sopenharmony_cir9(/system/lib/ld-musl-arm.so.1):
288e41f4b71Sopenharmony_ci    f7baea7c 20746f6e
289e41f4b71Sopenharmony_ci    f7baea80 6e756f66
290e41f4b71Sopenharmony_ci    ...
291e41f4b71Sopenharmony_ci    f7baeaf8 25206e69
292e41f4b71Sopenharmony_cir10([anon:ld-musl-arm.so.1.bss]):
293e41f4b71Sopenharmony_ci    f7cadd30 00000000
294e41f4b71Sopenharmony_ci    f7cadd34 00000000
295e41f4b71Sopenharmony_ci    ...
296e41f4b71Sopenharmony_ci    f7caddac 00000000
297e41f4b71Sopenharmony_cir12([anon:ld-musl-arm.so.1.bss]):
298e41f4b71Sopenharmony_ci    f7cb2070 56726562
299e41f4b71Sopenharmony_ci    f7cb2074 65756c61
300e41f4b71Sopenharmony_ci    ...
301e41f4b71Sopenharmony_ci    f7cb20ec 00000000
302e41f4b71Sopenharmony_cisp([stack]):
303e41f4b71Sopenharmony_ci    ffd27328 00000000
304e41f4b71Sopenharmony_ci    ffd2732c 00966dd0
305e41f4b71Sopenharmony_ci    ...
306e41f4b71Sopenharmony_ci    ffd273a4 00000004
307e41f4b71Sopenharmony_cipc(/system/bin/crasher_cpp):
308e41f4b71Sopenharmony_ci    00966dc8 e1a0d00c
309e41f4b71Sopenharmony_ci    00966dcc eb000000
310e41f4b71Sopenharmony_ci    ...
311e41f4b71Sopenharmony_ci    00966e44 e5907008
312e41f4b71Sopenharmony_cipc(/system/bin/crasher_cpp):
313e41f4b71Sopenharmony_ci    00966dc8 e1a0d00c
314e41f4b71Sopenharmony_ci    00966dcc eb000000
315e41f4b71Sopenharmony_ci    ...
316e41f4b71Sopenharmony_ci    00966e44 e5907008
317e41f4b71Sopenharmony_ciFaultStack: <- Stack of the crashed thread
318e41f4b71Sopenharmony_ci    ffd27260 00000000
319e41f4b71Sopenharmony_ci    ffd27264 f7cac628
320e41f4b71Sopenharmony_ci    ...
321e41f4b71Sopenharmony_ci    ffd2729c 0096ad1f
322e41f4b71Sopenharmony_cisp0:ffd272a0 0096fdfc <- #00Stack top
323e41f4b71Sopenharmony_ci    ffd272a4 009684d3
324e41f4b71Sopenharmony_cisp1:ffd272a8 00000001
325e41f4b71Sopenharmony_ci    ffd272ac 73657408
326e41f4b71Sopenharmony_ci    ffd272b0 f7590074
327e41f4b71Sopenharmony_ci    ...
328e41f4b71Sopenharmony_ci    ffd272dc 0096856d
329e41f4b71Sopenharmony_cisp2:ffd272e0 ffd27334
330e41f4b71Sopenharmony_ci    ffd272e4 ffd27334
331e41f4b71Sopenharmony_ci    ffd272e8 00000002
332e41f4b71Sopenharmony_ci    ....
333e41f4b71Sopenharmony_ci    ffd272f4 f7bfbb9c
334e41f4b71Sopenharmony_cisp3:ffd272f8 00000000
335e41f4b71Sopenharmony_ci    ffd272fc ffd27334
336e41f4b71Sopenharmony_ci
337e41f4b71Sopenharmony_ciMaps:   <-  Process maps files when the fault occurs
338e41f4b71Sopenharmony_ci962000-966000 r--p 00000000 /system/bin/crasher_cpp
339e41f4b71Sopenharmony_ci966000-96c000 r-xp 00003000 /system/bin/crasher_cpp
340e41f4b71Sopenharmony_ci96c000-96f000 r--p 00008000 /system/bin/crasher_cpp
341e41f4b71Sopenharmony_ci96f000-970000 rw-p 0000a000 /system/bin/crasher_cpp
342e41f4b71Sopenharmony_ci149f000-14a0000 ---p 00000000 [heap]
343e41f4b71Sopenharmony_ci14a0000-14a2000 rw-p 00000000 [heap]
344e41f4b71Sopenharmony_ci...
345e41f4b71Sopenharmony_cif7b89000-f7be1000 r--p 00000000 /system/lib/ld-musl-arm.so.1
346e41f4b71Sopenharmony_cif7be1000-f7ca9000 r-xp 00057000 /system/lib/ld-musl-arm.so.1
347e41f4b71Sopenharmony_cif7ca9000-f7cab000 r--p 0011e000 /system/lib/ld-musl-arm.so.1
348e41f4b71Sopenharmony_cif7cab000-f7cad000 rw-p 0011f000 /system/lib/ld-musl-arm.so.1
349e41f4b71Sopenharmony_cif7cad000-f7cbc000 rw-p 00000000 [anon:ld-musl-arm.so.1.bss]
350e41f4b71Sopenharmony_ciffd07000-ffd28000 rw-p 00000000 [stack]
351e41f4b71Sopenharmony_ciffff0000-ffff1000 r-xp 00000000 [vectors]
352e41f4b71Sopenharmony_ciOpenFiles:   <-  FD information of the file opened by the process when the fault occurs
353e41f4b71Sopenharmony_ci0->/dev/pts/1 native object of unknown type 0
354e41f4b71Sopenharmony_ci1->/dev/pts/1 native object of unknown type 0
355e41f4b71Sopenharmony_ci2->/dev/pts/1 native object of unknown type 0
356e41f4b71Sopenharmony_ci3->socket:[67214] native object of unknown type 0
357e41f4b71Sopenharmony_ci...
358e41f4b71Sopenharmony_ci11->pipe:[67219] native object of unknown type 0
359e41f4b71Sopenharmony_ci12->socket:[29074] native object of unknown type 0
360e41f4b71Sopenharmony_ci25->/dev/ptmx native object of unknown type 0
361e41f4b71Sopenharmony_ci26->/dev/ptmx native object of unknown type 0
362e41f4b71Sopenharmony_ci```
363e41f4b71Sopenharmony_ci<!--DelEnd-->
364e41f4b71Sopenharmony_ci**Fault Logs of Stack Overflow**
365e41f4b71Sopenharmony_ciIf the following prompt information is printed in logs, it indicates that the fault may be caused by stack overflow. The key logs are as follows:
366e41f4b71Sopenharmony_ci
367e41f4b71Sopenharmony_ci```
368e41f4b71Sopenharmony_ciGenerated by HiviewDFX@OpenHarmony
369e41f4b71Sopenharmony_ci================================================================
370e41f4b71Sopenharmony_ciDevice info:OpenHarmony 3.2            <- Device information
371e41f4b71Sopenharmony_ciBuild info:OpenHarmony 5.0.0.23        <- Build information
372e41f4b71Sopenharmony_ciFingerprint:8bc3343f50024204e258b8dce86f41f8fcc50c4d25d56b24e71fe26c0a23e321 <- Fingerprint
373e41f4b71Sopenharmony_ciModule name:crasher_cpp                <- Module name
374e41f4b71Sopenharmony_ciTimestamp:2024-05-06 20:18:24.000      <- Timestamp when the fault occurs
375e41f4b71Sopenharmony_ciPid:9838                               <- Process ID
376e41f4b71Sopenharmony_ciUid:0                                  <- User ID
377e41f4b71Sopenharmony_ciProcess name:./crasher_cpp             <- Process name
378e41f4b71Sopenharmony_ciProcess life time:2s                   <- Process life time
379e41f4b71Sopenharmony_ciReason:Signal:SIGSEGV(SEGV_ACCERR)@0xf76b7ffc current thread stack low address = 0xf76b8000, probably caused by stack-buffer-overflow <- Fault cause and stack overflow prompt
380e41f4b71Sopenharmony_ci...
381e41f4b71Sopenharmony_ci```
382e41f4b71Sopenharmony_ci
383e41f4b71Sopenharmony_ci**Fault Logs of Stack Coverage**
384e41f4b71Sopenharmony_ciIn the stack coverage scenario, the stack frame cannot be traced because the stack memory is illegally accessed. A message is displayed in the log, indicating that the stack fails to be returned and the system attempts to parse the thread stack to obtain an unreliable call stack. The information is provided for problem analysis. The key logs are as follows:
385e41f4b71Sopenharmony_ci
386e41f4b71Sopenharmony_ci```
387e41f4b71Sopenharmony_ciGenerated by HiviewDFX@OpenHarmony
388e41f4b71Sopenharmony_ci================================================================
389e41f4b71Sopenharmony_ciDevice info:OpenHarmony 3.2               <- Device information
390e41f4b71Sopenharmony_ciBuild info:OpenHarmony 5.0.0.23           <- Build information
391e41f4b71Sopenharmony_ciFingerprint:79b6d47b87495edf27135a83dda8b1b4f9b13d37bda2560d43f2cf65358cd528    <- Fingerprint
392e41f4b71Sopenharmony_ciModule name:crasher_cpp                   <- Module name
393e41f4b71Sopenharmony_ciTimestamp:2024-05-06 20:27:23.2035266415  <- Timestamp when the fault occurs
394e41f4b71Sopenharmony_ciPid:10026                                 <- Process ID
395e41f4b71Sopenharmony_ciUid:0                                     <- User ID
396e41f4b71Sopenharmony_ciProcess name:./crasher_cpp                <- Process name
397e41f4b71Sopenharmony_ciProcess life time:1s                      <- Process life time
398e41f4b71Sopenharmony_ciReason:Signal:SIGSEGV(SEGV_MAPERR)@0000000000 probably caused by NULL pointer dereference  <- Fault Cause
399e41f4b71Sopenharmony_ciLastFatalMessage: Failed to unwind stack, try to get unreliable call stack from #02 by reparsing thread stack   <- Attempt to obtain an unreliable stack from the thread stack
400e41f4b71Sopenharmony_ciFault thread info:
401e41f4b71Sopenharmony_ciTid:10026, Name:crasher_cpp               <- Thread ID, thread name
402e41f4b71Sopenharmony_ci#00 pc 00000000 Not mapped
403e41f4b71Sopenharmony_ci#01 pc 00008d22 /system/bin/crasher_cpp(TestNullPointerDereferenceCrash0()+22)(adfc673300571d2da1e47d1d12f48b44)  <- Call stack
404e41f4b71Sopenharmony_ci#02 pc 000064d1 /system/bin/crasher_cpp(DfxCrasher::ParseAndDoCrash(char const*) const+160)(adfc673300571d2da1e47d1d12f48b44)
405e41f4b71Sopenharmony_ci#03 pc 00006569 /system/bin/crasher_cpp(main+92)(adfc673300571d2da1e47d1d12f48b44)
406e41f4b71Sopenharmony_ci#04 pc 00072b98 /system/lib/ld-musl-arm.so.1(libc_start_main_stage2+56)(d820b1827e57855d4f9ed03ba5dfea83)
407e41f4b71Sopenharmony_ci...
408e41f4b71Sopenharmony_ci```
409e41f4b71Sopenharmony_ci
410e41f4b71Sopenharmony_ci**Fault Logs of Asynchronous Thread**
411e41f4b71Sopenharmony_ci(Currently, this logging only supports ARM64 architecture and is enabled in the debugging application **HAP_DEBUGGABLE**.)
412e41f4b71Sopenharmony_ciWhen an asynchronous thread crashes, the stack of the thread that submits the asynchronous task is also printed to locate the fault. The **SubmitterStacktrace** is used to differentiate the call stack of the crash thread and that of the submitting thread. The key logs are as follows:
413e41f4b71Sopenharmony_ci
414e41f4b71Sopenharmony_ci```
415e41f4b71Sopenharmony_ciGenerated by HiviewDFX@OpenHarmony
416e41f4b71Sopenharmony_ci================================================================
417e41f4b71Sopenharmony_ciDevice info:OpenHarmony 3.2                 <- Device information
418e41f4b71Sopenharmony_ciBuild info:OpenHarmony 5.0.0.23             <- Build information
419e41f4b71Sopenharmony_ciFingerprint:8bc3343f50024204e258b8dce86f41f8fcc50c4d25d56b24e71fe26c0a23e321  <- Fingerprint
420e41f4b71Sopenharmony_ciModule name:crasher_cpp                     <- Module name
421e41f4b71Sopenharmony_ciTimestamp:2024-05-06 20:28:24.000           <- Timestamp when the fault occurs
422e41f4b71Sopenharmony_ciPid:9838                                    <- Process ID
423e41f4b71Sopenharmony_ciUid:0                                       <- User ID
424e41f4b71Sopenharmony_ciProcess name:./crasher_cpp                  <- Process name
425e41f4b71Sopenharmony_ciProcess life time:2s                        <- Process life time
426e41f4b71Sopenharmony_ciReason:Signal:SIGSEGV(SI_TKILL)@0x000000000004750 from:18256:0   <- Fault Cause
427e41f4b71Sopenharmony_ciFault thread info:
428e41f4b71Sopenharmony_ciTid:18257, Name:crasher_cpp                 <- Thread ID, thread name
429e41f4b71Sopenharmony_ci#00 pc 000054e6 /system/bin/ld-musl-aarch64.so.l(raise+228)(adfc673300571d2da1e47d1d12f48b44) <- Call stack
430e41f4b71Sopenharmony_ci#01 pc 000054f9 /system/bin/crasher_cpp(CrashInSubThread(void*)+56)(adfc673300571d2da1e47d1d12f48b50)
431e41f4b71Sopenharmony_ci#02 pc 000054f9 /system/bin/ld-musl-aarch64.so.l(start+236)(adfc673300571d2da1e47d1d12f48b44)
432e41f4b71Sopenharmony_ci========SubmitterStacktrace========       <- The call stack used to print submitting thread
433e41f4b71Sopenharmony_ci#00 pc 000094dc /system/bin/crasher_cpp(DfxCrasher::AsyncStacktrace()+36)(adfc673300571d2da1e47d1d12f48b50)
434e41f4b71Sopenharmony_ci#01 pc 00009a58 /system/bin/crasher_cpp(DfxCrasher::ParseAndDoCrash(char const*) const+232)(adfc673300571d2da1e47d1d12f48b50)
435e41f4b71Sopenharmony_ci#02 pc 00009b40 /system/bin/crasher_cpp(main+140)(adfc673300571d2da1e47d1d12f48b50)
436e41f4b71Sopenharmony_ci#03 pc 0000a4e1c /system/bin/ld-musl-aarch64.so.l(libc_start_main_stage2+68)(adfc673300571d2da1e47d1d12f48b44)
437e41f4b71Sopenharmony_ci...
438e41f4b71Sopenharmony_ci```
439e41f4b71Sopenharmony_ci
440e41f4b71Sopenharmony_ci### Locating the Problematic Code Based on the Crash Stack
441e41f4b71Sopenharmony_ci
442e41f4b71Sopenharmony_ci#### Method 1: DevEco Studio
443e41f4b71Sopenharmony_ci
444e41f4b71Sopenharmony_ciIn application development, you can locate the problematic code in the cppcrash stack of the dynamic library. Both native stack frames and JS stack frames are supported. For some stack frames that fail to be parsed and located in DevEco Studio, refer to Method 2.
445e41f4b71Sopenharmony_ci
446e41f4b71Sopenharmony_ci![cppcrash-addr2line1](figures/cppcrash_image_002.png)
447e41f4b71Sopenharmony_ci
448e41f4b71Sopenharmony_ci#### Method 2: SDK llvm-addr2line
449e41f4b71Sopenharmony_ci
450e41f4b71Sopenharmony_ci- Obtain the symbol list
451e41f4b71Sopenharmony_ci    Obtain the .so file with symbols in the crash stack, which should be the same as that of the application or system.
452e41f4b71Sopenharmony_ci    Compiled and built in DevEco Studio, the .so file of dynamic library is generated with symbols by default in **/build/default/intermediates/libs**. You can run the **Linux file** command to check whether the BuildID of two .so files match. Generated by a compiler, BuildID is the unique identifier of a binary file, in which "not stripped" indicates that a symbol table is included.
453e41f4b71Sopenharmony_ci
454e41f4b71Sopenharmony_ci    ```
455e41f4b71Sopenharmony_ci    $ file libbabel.so
456e41f4b71Sopenharmony_ci    libbabel.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=fdb1b5432b9ea4e2a3d29780c3abf30e2a22da9d, with debug_info, not stripped
457e41f4b71Sopenharmony_ci    ```
458e41f4b71Sopenharmony_ci
459e41f4b71Sopenharmony_ci    Note: The symbol table of the system dynamic library is archived with the version.
460e41f4b71Sopenharmony_ci
461e41f4b71Sopenharmony_ci- Locate the line number using llvm-addr2line
462e41f4b71Sopenharmony_ci    You can find llvm-addr2line in **[SDK DIR PATH]\OpenHarmony\11\native\llvm\bin**, or you need to search for the path as it varies based on the SDK version. 
463e41f4b71Sopenharmony_ci    The sample stack is as follows (part are omitted):
464e41f4b71Sopenharmony_ci
465e41f4b71Sopenharmony_ci    ```
466e41f4b71Sopenharmony_ci    Generated by HiviewDFX@OpenHarmony
467e41f4b71Sopenharmony_ci    ================================================================
468e41f4b71Sopenharmony_ci    Device info:OpenHarmony 3.2
469e41f4b71Sopenharmony_ci    Build info:OpenHarmony 5.0.0.22
470e41f4b71Sopenharmony_ci    Fingerprint:50577c0a1a1b5644ac030ba8f08c241cca0092026b59f29e7b142d5d4d5bb934
471e41f4b71Sopenharmony_ci    Module name:com.samples.recovery
472e41f4b71Sopenharmony_ci    Version:1.0.0
473e41f4b71Sopenharmony_ci    VersionCode:1000000
474e41f4b71Sopenharmony_ci    PreInstalled:No
475e41f4b71Sopenharmony_ci    Foreground:No
476e41f4b71Sopenharmony_ci    Timestamp:2017-08-05 17:03:40.000
477e41f4b71Sopenharmony_ci    Pid:2396
478e41f4b71Sopenharmony_ci    Uid:20010044
479e41f4b71Sopenharmony_ci    Process name:com.samples.recovery
480e41f4b71Sopenharmony_ci    Process life time:7s
481e41f4b71Sopenharmony_ci    Reason:Signal:SIGSEGV(SEGV_MAPERR)@0000000000  probably caused by NULL pointer dereference
482e41f4b71Sopenharmony_ci    Tid:2396, Name:amples.recovery
483e41f4b71Sopenharmony_ci    # 00 pc 00003510 /data/storage/el1/bundle/libs/arm/libentry.so(TriggerCrash(napi_env__*, napi_callback_info__*)+24)(446ff75d3f6a518172cc52e8f8055650b02b0e54)
484e41f4b71Sopenharmony_ci    # 01 pc 0002b0c5 /system/lib/platformsdk/libace_napi.z.so(panda::JSValueRef ArkNativeFunctionCallBack<true>(panda::JsiRuntimeCallInfo*)+448)(a84fbb767fd826946623779c608395bf)
485e41f4b71Sopenharmony_ci    # 02 pc 001e7597 /system/lib/platformsdk/libark_jsruntime.so(panda::ecmascript::EcmaInterpreter::RunInternal(panda::ecmascript::JSThread*, unsigned char const*, unsigned long long*)+14710)(106c552f6ce4420b9feac95e8b21b792)
486e41f4b71Sopenharmony_ci    # 03 pc 001e0439 /system/lib/platformsdk/libark_jsruntime.so(panda::ecmascript::EcmaInterpreter::Execute(panda::ecmascript::EcmaRuntimeCallInfo*)+984)(106c552f6ce4420b9feac95e8b21b792)
487e41f4b71Sopenharmony_ci    ...
488e41f4b71Sopenharmony_ci    # 39 pc 00072998 /system/lib/ld-musl-arm.so.1(libc_start_main_stage2+56)(5b1e036c4f1369ecfdbb7a96aec31155)
489e41f4b71Sopenharmony_ci    # 40 pc 00005b48 /system/bin/appspawn(_start_c+84)(cb0631260fa74df0bc9b0323e30ca03d)
490e41f4b71Sopenharmony_ci    # 41 pc 00005aec /system/bin/appspawn(cb0631260fa74df0bc9b0323e30ca03d)
491e41f4b71Sopenharmony_ci    Registers:
492e41f4b71Sopenharmony_ci    r0:00000000 r1:ffc47af8 r2:00000001 r3:f6555c94
493e41f4b71Sopenharmony_ci    r4:00000000 r5:f4d90f64 r6:bd8434f8 r7:00000000
494e41f4b71Sopenharmony_ci    r8:00000000 r9:ffc48808 r10:ffc47b70
495e41f4b71Sopenharmony_ci    fp:f7d8a5a0 ip:00000000 sp:ffc47aac lr:f4d6b0c7 pc:bd843510
496e41f4b71Sopenharmony_ci    ```
497e41f4b71Sopenharmony_ci
498e41f4b71Sopenharmony_ci    Parsed by SDK llvm-addr2line, the row number of problematic code is as follows:
499e41f4b71Sopenharmony_ci
500e41f4b71Sopenharmony_ci    ```
501e41f4b71Sopenharmony_ci    [SDK DIR PATH]\OpenHarmony\11\native\llvm\bin> .\llvm-addr2line.exe -Cfie libentry.so 3150
502e41f4b71Sopenharmony_ci    TrggerCrash(napi_env__*, napi_callback_info__*)
503e41f4b71Sopenharmony_ci    D:/code/apprecovery-demo/entry/src/main/cpp/hello.cpp:48
504e41f4b71Sopenharmony_ci    ```
505e41f4b71Sopenharmony_ci
506e41f4b71Sopenharmony_ci    You can use the **llvm-addr2line.exe -fCpie libutils.z.so offset** command to parse the stack line by line. If there are multiple offsets, you can parse them together using the **llvm-addr2line.exe -fCpie libxxx.so 0x1bc868 0x1be28c xxx** command. If the obtained row number does not seem correct, you can change the address (for example, subtract 1) or disable some compilation optimization.
507e41f4b71Sopenharmony_ci
508e41f4b71Sopenharmony_ci#### Method 3: DevEco Studio hstack
509e41f4b71Sopenharmony_ci
510e41f4b71Sopenharmony_cihstack is a tool provided by DevEco Studio for you to restore the crash stack of an obfuscated release app to the source code stack. It runs on Windows, macOS, and Linux platforms. [DevEco Studio hstack User Guide](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-command-line-hstack-0000001777724494-V5)
511e41f4b71Sopenharmony_ci
512e41f4b71Sopenharmony_ci### Reviewing Code Based on Services
513e41f4b71Sopenharmony_ci
514e41f4b71Sopenharmony_ciReview the context after the row number of the stack top is obtained. As shown in the following figure, line 48 in the **hello.cpp** file indicates a null pointer dereference.
515e41f4b71Sopenharmony_ci
516e41f4b71Sopenharmony_ci![cppcrash-demo1](figures/cppcrash_image_004.png)
517e41f4b71Sopenharmony_ci
518e41f4b71Sopenharmony_ciThis example is constructed, and actual scenario is usually more complicate and needs to be analyzed based on services.
519e41f4b71Sopenharmony_ci
520e41f4b71Sopenharmony_ci### Disassembling (optional)
521e41f4b71Sopenharmony_ci
522e41f4b71Sopenharmony_ciGenerally, if the problem is clear, you can locate the problem by decompiling the code line. In a few cases, if the method called in a line contains multiple parameters and the parameters involve structs, you need to use disassembly for further analysis.
523e41f4b71Sopenharmony_ci
524e41f4b71Sopenharmony_ci```
525e41f4b71Sopenharmony_ciobjdump -S xxx.so > xxx.txt
526e41f4b71Sopenharmony_ciobjdump -d xxxx                    Disassembles the xxxx file.
527e41f4b71Sopenharmony_ciobjdump -S -l xxxx                 Disassembles the xxxx file and display the source code line.
528e41f4b71Sopenharmony_ci```
529e41f4b71Sopenharmony_ci
530e41f4b71Sopenharmony_ci### Common CppCrash Faults and Causes
531e41f4b71Sopenharmony_ci
532e41f4b71Sopenharmony_ci- Null pointer dereference
533e41f4b71Sopenharmony_ci    When a crash log is in format **SIGSEGV(SEGV_MAPERR)@0x00000000** or the values of the input parameter registers such as **r0** and **r1** printed in the **Register** are **0**, check whether a null pointer is input when invoking a method.
534e41f4b71Sopenharmony_ci    When a crash log is in format **SIGSEGV(SEGVMAPERR)@0x0000000c** or the value of the input parameter register such as **r1** printed in the **Register** is small, check whether the called structs contain a null pointer.
535e41f4b71Sopenharmony_ci- SIGABRT
536e41f4b71Sopenharmony_ci    Generally, this fault is triggered by the user, framework, or C library, and you can locate the problematic code in the first frame of the framework library. In this case, check whether resources such as thread and file descriptor are properly used, and whether the invoking sequence of APIs is correct.
537e41f4b71Sopenharmony_ci- SIGSEGV
538e41f4b71Sopenharmony_ci  - Multithreading operation of STL collection is not thread-safe. If the collection is added or deleted on multiple threads, the **SIGSEGV** crash occurs. If **llvm-addr2line** is used and the result code involve operations on collections, this could be the reason for the crash.
539e41f4b71Sopenharmony_ci  - If the pointer does not match the lifecycle of an object, for example, using a raw pointer to store the **sptr** type and **shared_ptr** type, can lead to memory leak and dangling pointer. A raw pointer is a pointer that does not have features such as encapsulation and automatic memory management. It is only a simple pointer to the memory address. The memory to which the pointer points is not protected or managed. A raw pointer can directly access the pointed memory, but problems such as memory leak and null pointer reference may also occur. Therefore, when using a raw pointer, pay attention to potential security problems. You are advised to use smart pointers to manage memory.
540e41f4b71Sopenharmony_ci- Use after free
541e41f4b71Sopenharmony_ci    This fault occurs when the reference of a released stack variable is not set to null and the access continues.
542e41f4b71Sopenharmony_ci
543e41f4b71Sopenharmony_ci    ```
544e41f4b71Sopenharmony_ci    # include <iostream>
545e41f4b71Sopenharmony_ci
546e41f4b71Sopenharmony_ci    int& getStackReference() {
547e41f4b71Sopenharmony_ci        int x = 5;
548e41f4b71Sopenharmony_ci        return x; // Return the reference to x.
549e41f4b71Sopenharmony_ci    }
550e41f4b71Sopenharmony_ci
551e41f4b71Sopenharmony_ci    int main() {
552e41f4b71Sopenharmony_ci        int& ref = getStackReference (); // Obtain the reference to x.
553e41f4b71Sopenharmony_ci        // x is released when getStackReference() returns.
554e41f4b71Sopenharmony_ci        // ref is now a dangling reference. If you continue to access it, undefined behavior occurs.
555e41f4b71Sopenharmony_ci        std::cout << ref << std::endl; // Outputting the value of x is an undefined behavior.
556e41f4b71Sopenharmony_ci        return 0;
557e41f4b71Sopenharmony_ci    }
558e41f4b71Sopenharmony_ci    ```
559e41f4b71Sopenharmony_ci
560e41f4b71Sopenharmony_ci- Stack overflow occurs in recursive invocation, mutual invocation of destructors, and the use of large stack memory blocks in special stacks (signal stacks).
561e41f4b71Sopenharmony_ci    ```
562e41f4b71Sopenharmony_ci    # include <iostream>
563e41f4b71Sopenharmony_ci
564e41f4b71Sopenharmony_ci    class RecursiveClass {
565e41f4b71Sopenharmony_ci    public:
566e41f4b71Sopenharmony_ci        RecursiveClass() {
567e41f4b71Sopenharmony_ci            std::cout << "Constructing RecursiveClass" << std::endl;
568e41f4b71Sopenharmony_ci        }
569e41f4b71Sopenharmony_ci
570e41f4b71Sopenharmony_ci        ~RecursiveClass() {
571e41f4b71Sopenharmony_ci            std::cout << "Destructing RecursiveClass" << std::endl;
572e41f4b71Sopenharmony_ci            // Recursive invocation of a destructor.
573e41f4b71Sopenharmony_ci            RecursiveClass obj;
574e41f4b71Sopenharmony_ci        }
575e41f4b71Sopenharmony_ci    };
576e41f4b71Sopenharmony_ci
577e41f4b71Sopenharmony_ci    int main() {
578e41f4b71Sopenharmony_ci        RecursiveClass obj;
579e41f4b71Sopenharmony_ci        return 0;
580e41f4b71Sopenharmony_ci    }
581e41f4b71Sopenharmony_ci    ```
582e41f4b71Sopenharmony_ci    When a **RecursiveClass** object is created, its constructor is called. When this object is destroyed, its destructor is called. In the destructor, a new **RecursiveClass** object is created, which causes recursive calls until the stack overflows. Recursive calls are infinite. As a result, the stack space is used up and the application crashes.
583e41f4b71Sopenharmony_ci- Binary mismatch usually indicates the mismatch of the Application Binary Interface (ABI). For example, when a compiled binary interface or its data structure definition does not match the ABI, a random crash stack is generated.
584e41f4b71Sopenharmony_ci- Memory corruption occurs when the memory of a valid wild pointer is changed to an invalid value, which results in out-of-bounds access and data overwrite. In this case, a random crash stack is generated.
585e41f4b71Sopenharmony_ci- SIGBUS (Aligment) occurs when the address is in the unaligned state after the pointer is forcibly converted.
586e41f4b71Sopenharmony_ci
587e41f4b71Sopenharmony_ci## Case Study
588e41f4b71Sopenharmony_ci
589e41f4b71Sopenharmony_ciThe following analyzes the typical CppCrash cases based on signals, scenarios, and tools respectively.
590e41f4b71Sopenharmony_ciThe analysis based on signals introduces common crash signals and provides a typical case for each type of signal.
591e41f4b71Sopenharmony_ciThe analysis based on scenarios concludes a common scenario for frequent problems, and provides a typical case for each scenario.
592e41f4b71Sopenharmony_ciThe analysis based on tools describes how to use various maintenance and debugging tools, and provides a typical case for each tool.
593e41f4b71Sopenharmony_ci
594e41f4b71Sopenharmony_ci### Analyzing CppCrash Based on Signals
595e41f4b71Sopenharmony_ci
596e41f4b71Sopenharmony_ci#### Type 1: SIGSEGV Crash
597e41f4b71Sopenharmony_ci
598e41f4b71Sopenharmony_ciThe **SIGSEGV** signal indicates a Segmentation Fault of the program. This fault occurs when a program accesses a memory area outside its bounds (for example, writes a memory in the operating system), or accesses a memory area without correct permission (for example, writes to read-only memory). The details are as follows:
599e41f4b71Sopenharmony_ci
600e41f4b71Sopenharmony_ci- **SIGSEGV** is a type of memory management fault.
601e41f4b71Sopenharmony_ci- **SIGSEGV** is generated in a user-mode program. 
602e41f4b71Sopenharmony_ci- **SIGSEGV** occurs when a user-mode program accesses a memory area outside its bound.
603e41f4b71Sopenharmony_ci- **SIGSEGV** also occurs when a user-mode program accesses a memory without correct permission.
604e41f4b71Sopenharmony_ci
605e41f4b71Sopenharmony_ciIn most cases, **SIGSEGV** is caused by pointer overwriting. However, not all pointer overwriting causes **SIGSEGV**. The **SIGSEGV** crash would not be triggered unless an out-of-bounds pointer is dereferenced. In addition, even if an out-of-bounds pointer is dereferenced, the **SIGSEGV** crash may not be caused. The **SIGSEGV** crash involves the operating system, C library, compiler, and linker. The example is as follows.
606e41f4b71Sopenharmony_ci
607e41f4b71Sopenharmony_ci- The memory area is read-only memory.
608e41f4b71Sopenharmony_ci    The sample code is as follows:
609e41f4b71Sopenharmony_ci
610e41f4b71Sopenharmony_ci    ```
611e41f4b71Sopenharmony_ci    static napi_value TriggerCrash(napi_env env, napi_callback_info info)
612e41f4b71Sopenharmony_ci    {
613e41f4b71Sopenharmony_ci        char *s = "hello world";
614e41f4b71Sopenharmony_ci        s[1] = 'H';
615e41f4b71Sopenharmony_ci        return 0;
616e41f4b71Sopenharmony_ci    }
617e41f4b71Sopenharmony_ci    ```
618e41f4b71Sopenharmony_ci
619e41f4b71Sopenharmony_ci    This is one of the most common examples. In this case, "hello world" is a constant string and is placed in **.rodata section** of GCC. When the target program is generated, **.rodata section** is merged into the **text segment** and placed together with the **code segment**. Therefore, the memory area where the **.rodata section** is located is read-only. This is the **SIGSEGV(SEGV_ACCERR)** crash caused by writing to read-only memory area.
620e41f4b71Sopenharmony_ci
621e41f4b71Sopenharmony_ci    ![cppcrash-demo2](figures/cppcrash_image_005.png)
622e41f4b71Sopenharmony_ci
623e41f4b71Sopenharmony_ci- The memory area is out of the process address space.
624e41f4b71Sopenharmony_ci
625e41f4b71Sopenharmony_ci    The sample code is as follows:
626e41f4b71Sopenharmony_ci
627e41f4b71Sopenharmony_ci    ```
628e41f4b71Sopenharmony_ci    static napi_value TriggerCrash(napi_env env, napi_callback_info info)
629e41f4b71Sopenharmony_ci    {
630e41f4b71Sopenharmony_ci        uint64_t* p = (uint64_t*)0xffffffcfc42ae6f4;
631e41f4b71Sopenharmony_ci        *p = 10;
632e41f4b71Sopenharmony_ci        return 0;
633e41f4b71Sopenharmony_ci    }
634e41f4b71Sopenharmony_ci    ```
635e41f4b71Sopenharmony_ci
636e41f4b71Sopenharmony_ci    In this example, the program accesses a memory address in the kernel. The **SIGSEGV(SEGV_MAPERR)@0xffffffcfc42ae6f4** crash is usually triggered by the program by accident. The key logs of this cpp crash are as follows:
637e41f4b71Sopenharmony_ci
638e41f4b71Sopenharmony_ci    ```
639e41f4b71Sopenharmony_ci    Device info:xxxxxx xxxx xx xxx
640e41f4b71Sopenharmony_ci    Build info:xxxxxxx
641e41f4b71Sopenharmony_ci    Fingerprint:73a5dcdf3e509605563aa11ac8cb4f3d7f99b9946dc142212246b53b741c4129
642e41f4b71Sopenharmony_ci    Module name:com.samples.recovery
643e41f4b71Sopenharmony_ci    Version:1.0.0
644e41f4b71Sopenharmony_ci    VersionCode:1000000
645e41f4b71Sopenharmony_ci    PreInstalled:No
646e41f4b71Sopenharmony_ci    Foreground:Yes
647e41f4b71Sopenharmony_ci    Timestamp:2024-04-29 14:07:12.082
648e41f4b71Sopenharmony_ci    Pid:21374
649e41f4b71Sopenharmony_ci    Uid:20020144
650e41f4b71Sopenharmony_ci    Process name:com.samples.recovery
651e41f4b71Sopenharmony_ci    Process life time:8s
652e41f4b71Sopenharmony_ci    Reason:Signal:SIGSEGV(SEGV_MAPERR)@0xffffffcfc42ae6f4 
653e41f4b71Sopenharmony_ci    Fault thread info:
654e41f4b71Sopenharmony_ci    Tid:21374, Name:amples.recovery
655e41f4b71Sopenharmony_ci    # 00 pc 0000000000001ccc /data/storage/el1/bundle/libs/arm64/libentry.so(TriggerCrash(napi_env__*, napi_callback_info__*)+36)(4dd115fa8b8c1b3f37bdb5b7b67fc70f31f0dbac)
656e41f4b71Sopenharmony_ci    # 01 pc 0000000000033678 /system/lib64/platformsdk/libace_napi.z.so(ArkNativeFunctionCallBack(panda::JsiRuntimeCallInfo*)+372)(7d6f229764fdd4b72926465066bc475e)
657e41f4b71Sopenharmony_ci    # 02 pc 00000000001d7f38 /system/lib64/module/arkcompiler/stub.an(RTStub_PushCallArgsAndDispatchNative+40)
658e41f4b71Sopenharmony_ci    # 03 at doTriggerException (entry/src/main/ets/pages/FaultTriggerPage.ets:72:7)
659e41f4b71Sopenharmony_ci    # 04 at triggerNativeException (entry/src/main/ets/pages/FaultTriggerPage.ets:79:5)
660e41f4b71Sopenharmony_ci    # 05 at anonymous (entry/src/main/ets/pages/FaultTriggerPage.ets:353:19)
661e41f4b71Sopenharmony_ci    # 06 pc 000000000048e024 /system/lib64/platformsdk/libark_jsruntime.so(panda::FunctionRef::Call(panda::ecmascript::EcmaVM const*, panda::Local<panda::JSValueRef>, panda::Local<panda::JSValueRef> const*, int)+1040)(9fa942a1d42bd4ae607257975fbc1b77)
662e41f4b71Sopenharmony_ci    ...
663e41f4b71Sopenharmony_ci    # 38 pc 00000000000324b0 /system/bin/appspawn(AppSpawnRun+172)(c992404f8d1cf03c84c067fbf3e1dff9)
664e41f4b71Sopenharmony_ci    # 39 pc 00000000000213a8 /system/bin/appspawn(main+956)(c992404f8d1cf03c84c067fbf3e1dff9)
665e41f4b71Sopenharmony_ci    # 40 pc 00000000000a4b98 /system/lib/ld-musl-aarch64.so.1(libc_start_main_stage2+64)(ff4c94d996663814715bedb2032b2bbc)
666e41f4b71Sopenharmony_ci    ```
667e41f4b71Sopenharmony_ci
668e41f4b71Sopenharmony_ci3. The memory does not exist.
669e41f4b71Sopenharmony_ci    The sample code is as follows:
670e41f4b71Sopenharmony_ci
671e41f4b71Sopenharmony_ci    ```
672e41f4b71Sopenharmony_ci    static napi_value TriggerCrash(napi_env env, napi_callback_info info)
673e41f4b71Sopenharmony_ci    {
674e41f4b71Sopenharmony_ci        int *a = NULL;
675e41f4b71Sopenharmony_ci        *a = 1;
676e41f4b71Sopenharmony_ci        return 0;
677e41f4b71Sopenharmony_ci    }
678e41f4b71Sopenharmony_ci    ```
679e41f4b71Sopenharmony_ci
680e41f4b71Sopenharmony_ci    In practice, the most common null pointer dereference occurs when the user-mode address to which the null pointer points does not exist. The inference information "Reason:Signal:SIGSEGV(SEGV_MAPERR)@000000000000000000 probably caused by NULL pointer dereference" is printed in the **Reason** of CppCrash logs, as shown in the following figure.
681e41f4b71Sopenharmony_ci
682e41f4b71Sopenharmony_ci    ![cppcrash-demo3](figures/cppcrash_image_006.png)
683e41f4b71Sopenharmony_ci
684e41f4b71Sopenharmony_ci4. Double free.
685e41f4b71Sopenharmony_ci    The sample code is as follows:
686e41f4b71Sopenharmony_ci
687e41f4b71Sopenharmony_ci    ```
688e41f4b71Sopenharmony_ci    static napi_value TriggerCrash(napi_env env, napi_callback_info info)
689e41f4b71Sopenharmony_ci    {
690e41f4b71Sopenharmony_ci        void *pc = malloc(1024);
691e41f4b71Sopenharmony_ci        free(pc);
692e41f4b71Sopenharmony_ci        free (pc); // Double free
693e41f4b71Sopenharmony_ci        printf("free ok!\n");
694e41f4b71Sopenharmony_ci        return 0;
695e41f4b71Sopenharmony_ci    }
696e41f4b71Sopenharmony_ci    ```
697e41f4b71Sopenharmony_ci
698e41f4b71Sopenharmony_ci    In the double-free memory scenario, the system throws a **SIGSEGV(SI_TKILL)** fault indicating an illegal memory operation, as shown below
699e41f4b71Sopenharmony_ci
700e41f4b71Sopenharmony_ci    ![cppcrash-demo3](figures/cppcrash_image_007.png)
701e41f4b71Sopenharmony_ci
702e41f4b71Sopenharmony_ci    The preceding are common causes for **SIGSEGV** crashes. Other scenarios may also trigger  **SIGSEGV** crashes, which include stack overflow memory access, heap overflow memory access, global wild pointer access, execution on an invalid address, and invalid parameter invocation. The **SIGSEGV** crash is associated to the stack allocation and recovery of the operating system and the compiler. 
703e41f4b71Sopenharmony_ci
704e41f4b71Sopenharmony_ci#### Type 2: SIGABRT Crash
705e41f4b71Sopenharmony_ci
706e41f4b71Sopenharmony_ciThe **SIGABRT** signal is sent to abort the process. This signal can be called by the process executing **abort()** in C standard library, or it can be sent to the process from outside like other signals. 
707e41f4b71Sopenharmony_ci
708e41f4b71Sopenharmony_ci- Executing the **abort()** function.
709e41f4b71Sopenharmony_ci    The sample code is as follows:
710e41f4b71Sopenharmony_ci
711e41f4b71Sopenharmony_ci    ```
712e41f4b71Sopenharmony_ci    static napi_value TriggerCrash(napi_env env, napi_callback_info info)
713e41f4b71Sopenharmony_ci    {
714e41f4b71Sopenharmony_ci        OH_LOG_FATAL(LOG_APP, "test fatal log.");
715e41f4b71Sopenharmony_ci        abort();
716e41f4b71Sopenharmony_ci        return 0;
717e41f4b71Sopenharmony_ci    }
718e41f4b71Sopenharmony_ci    ```
719e41f4b71Sopenharmony_ci
720e41f4b71Sopenharmony_ci    In this scenario, the **abort()** function is proactively called when a process is identified as not safe in checks from basic libraries. The last fatal log before the process exits is printed in the crash log, as shown in the following figure:
721e41f4b71Sopenharmony_ci
722e41f4b71Sopenharmony_ci    ![cppcrash-demo4](figures/cppcrash_image_008.png)
723e41f4b71Sopenharmony_ci
724e41f4b71Sopenharmony_ci- Executing the **assert()** function.
725e41f4b71Sopenharmony_ci    The sample code is as follows:
726e41f4b71Sopenharmony_ci
727e41f4b71Sopenharmony_ci    ```
728e41f4b71Sopenharmony_ci    static napi_value TriggerCrash(napi_env env, napi_callback_info info)
729e41f4b71Sopenharmony_ci    {
730e41f4b71Sopenharmony_ci    # if 0 // If the value is 0, an error is reported. If the value is 1, it is normal.
731e41f4b71Sopenharmony_ci        void *pc = malloc(1024);
732e41f4b71Sopenharmony_ci    # else
733e41f4b71Sopenharmony_ci        void *pc = nullptr;
734e41f4b71Sopenharmony_ci    # endif
735e41f4b71Sopenharmony_ci        assert(pc != nullptr);
736e41f4b71Sopenharmony_ci        return 0;
737e41f4b71Sopenharmony_ci    }
738e41f4b71Sopenharmony_ci    ```
739e41f4b71Sopenharmony_ci
740e41f4b71Sopenharmony_ci    In addition to the **abort()** function, other exception handling mechanisms in C++ include the **assert()** function, **exit()** function, exception capture mechanism (**try-catch**), and **exception** class. The **assert()** function is used to check some data in the function execution. If the check fails, the process aborts.  The corresponding fault scenario is shown below. 
741e41f4b71Sopenharmony_ci
742e41f4b71Sopenharmony_ci    ![cppcrash-demo5](figures/cppcrash_image_009.png)
743e41f4b71Sopenharmony_ci
744e41f4b71Sopenharmony_ci### Analyzing CppCrash Based on Scenarios
745e41f4b71Sopenharmony_ci
746e41f4b71Sopenharmony_ci#### Type 1: Memory Access Crash
747e41f4b71Sopenharmony_ci
748e41f4b71Sopenharmony_ci**Background**
749e41f4b71Sopenharmony_ciThe crash address **0x7f82764b70** is in the readable and executable segment of **libace_napi_ark.z.so**. The cause is that the address needs to be written, but the corresponding **maps** segment has only the read and execute permissions. In other words, when a process attempts to access a memory area that is not allowed to be accessed, the process crashes.
750e41f4b71Sopenharmony_ci
751e41f4b71Sopenharmony_ci```
752e41f4b71Sopenharmony_ci7f82740000-7f8275c000 r--p 00000000 /system/lib64/libace_napi_ark.z.so
753e41f4b71Sopenharmony_ci7f8275c000-7f8276e000 r-xp 0001b000 /system/lib64/libace_napi_ark.z.so <- The crash address locates within this address range.
754e41f4b71Sopenharmony_ci7f8276e000-7f82773000 r--p 0002c000 /system/lib64/libace_napi_ark.z.so
755e41f4b71Sopenharmony_ci7f82773000-7f82774000 rw-p 00030000 /system/lib64/libace_napi_ark.z.so
756e41f4b71Sopenharmony_ci```
757e41f4b71Sopenharmony_ci
758e41f4b71Sopenharmony_ciThe following figure shows the crash call stack.
759e41f4b71Sopenharmony_ci
760e41f4b71Sopenharmony_ci![cppcrash-demo6](figures/cppcrash_image_010.png)
761e41f4b71Sopenharmony_ci
762e41f4b71Sopenharmony_ci**Fault Analysis**
763e41f4b71Sopenharmony_ciThis address error is regular, but it is abnormal that the node address fall in **libace_napi_ark.z.so**. In this case, this may be memory corruption error. You can use [ASan Check](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-asan-0000001545528013-V5) to locate the memory corruption error. By performing stress tests to reproduce the problem, ASan can also be used to find the regular crash scenario. The fault detected by ASan is the same as that in the crash stack above. The stack reports **heap-use-after-free**, which was actually a double free of the same address. During the second free operation, the address is used to access to its object member, resulting in a UAF fault. 
764e41f4b71Sopenharmony_ciThe key logs of ASan are as follows:
765e41f4b71Sopenharmony_ci
766e41f4b71Sopenharmony_ci```
767e41f4b71Sopenharmony_ci=================================================================
768e41f4b71Sopenharmony_ci==appspawn==2029==ERROR: AddressSanitizer: heap-use-after-free on address 0x003a375eb724 at pc 0x002029ba8514 bp 0x007fd8175710 sp 0x007fd8175708
769e41f4b71Sopenharmony_ciREAD of size 1 at 0x003a375eb724 thread T0 (thread name)
770e41f4b71Sopenharmony_ci    # 0 0x2029ba8510  (/system/asan/lib64/platformsdk/libark_jsruntime.so+0xca8510) panda::ecmascript::Node::IsUsing() const at arkcompiler/ets_runtime/ecmascript/ecma_global_storage.h:82:16
771e41f4b71Sopenharmony_ci(inlined by) panda::JSNApi::DisposeGlobalHandleAddr(panda::ecmascript::EcmaVM const*, unsigned long) at arkcompiler/ets_runtime/ecmascript/napi/jsnapi.cpp:749:67 BuildID[md5/uuid]=9a18e2ec0dc8a83216800b2f0dd7b76a
772e41f4b71Sopenharmony_ci    # 1 0x403ee94d30  (/system/asan/lib64/libace.z.so+0x6194d30) panda::CopyableGlobal<panda::ObjectRef>::Free() at arkcompiler/ets_runtime/ecmascript/napi/include/jsnapi.h:1520:9
773e41f4b71Sopenharmony_ci(inlined by) panda::CopyableGlobal<panda::ObjectRef>::Reset() at arkcompiler/ets_runtime/ecmascript/napi/include/jsnapi.h:189:9
774e41f4b71Sopenharmony_ci(inlined by) OHOS::Ace::Framework::JsiType<panda::ObjectRef>::Reset() at foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.inl:112:13
775e41f4b71Sopenharmony_ci(inlined by) OHOS::Ace::Framework::JsiWeak<OHOS::Ace::Framework::JsiObject>::~JsiWeak() at foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/jsi/jsi_ref.h:167:16
776e41f4b71Sopenharmony_ci(inlined by) OHOS::Ace::Framework::ViewFunctions::~ViewFunctions() at foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/jsview/js_view_functions.h:44:5 BuildID[md5/uuid]=1330f8b9be73bdb76ae18107c2a60ca1
777e41f4b71Sopenharmony_ci    # 2 0x403ee9296c  (/system/asan/lib64/libace.z.so+0x619296c) OHOS::Ace::Framework::ViewFunctions::~ViewFunctions() at foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/jsview/js_view_functions.h:42:5
778e41f4b71Sopenharmony_ci(inlined by) OHOS::Ace::Framework::ViewFunctions::~ViewFunctions() at foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/jsview/js_view_functions.h:42:5 BuildID[md5/uuid]=1330f8b9be73bdb76ae18107c2a60ca1
779e41f4b71Sopenharmony_ci    # 3 0x403ed9b130  (/system/asan/lib64/libace.z.so+0x609b130) OHOS::Ace::Referenced::DecRefCount() at foundation/arkui/ace_engine/frameworks/base/memory/referenced.h:76:13
780e41f4b71Sopenharmony_ci(inlined by) OHOS::Ace::RefPtr<OHOS::Ace::Framework::ViewFunctions>::~RefPtr() at foundation/arkui/ace_engine/frameworks/base/memory/referenced.h:148:22 BuildID[md5/uuid]=1330f8b9be73bdb76ae18107c2a60ca1
781e41f4b71Sopenharmony_ci    # 4 0x403ed9b838  (/system/asan/lib64/libace.z.so+0x609b838) OHOS::Ace::RefPtr<OHOS::Ace::Framework::ViewFunctions>::Reset() at foundation/arkui/ace_engine/frameworks/base/memory/referenced.h:163:9
782e41f4b71Sopenharmony_ci(inlined by) OHOS::Ace::Framework::JSViewFullUpdate::~JSViewFullUpdate() at foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/jsview/js_view.cpp:159:21 BuildID[md5/uuid]=1330f8b9be73bdb76ae18107c2a60ca1
783e41f4b71Sopenharmony_ci    # 5 0x403ed9bf24  (/system/asan/lib64/libace.z.so+0x609bf24) OHOS::Ace::Framework::JSViewFullUpdate::~JSViewFullUpdate() at foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/jsview/js_view.cpp:157:1
784e41f4b71Sopenharmony_ci(inlined by) OHOS::Ace::Framework::JSViewFullUpdate::~JSViewFullUpdate() at foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/jsview/js_view.cpp:157:1 BuildID[md5/uuid]=1330f8b9be73bdb76ae18107c2a60ca1
785e41f4b71Sopenharmony_ci...
786e41f4b71Sopenharmony_cifreed by thread T0 (thread name) here:
787e41f4b71Sopenharmony_ci    # 0 0x2024ed3abc  (/system/asan/lib64/libclang_rt.asan.so+0xd3abc)
788e41f4b71Sopenharmony_ci    # 1 0x2029ba8424  (/system/asan/lib64/platformsdk/libark_jsruntime.so+0xca8424) std::__h::__function::__value_func<void (unsigned long)>::operator()[abi:v15004](unsigned long&&) const at prebuilts/clang/ohos/linux-x86_64/llvm/bin/../include/libcxx-ohos/include/c++/v1/__functional/function.h:512:16
789e41f4b71Sopenharmony_ci(inlined by) std::__h::function<void (unsigned long)>::operator()(unsigned long) const at prebuilts/clang/ohos/linux-x86_64/llvm/bin/../include/libcxx-ohos/include/c++/v1/__functional/function.h:1197:12
790e41f4b71Sopenharmony_ci(inlined by) panda::ecmascript::JSThread::DisposeGlobalHandle(unsigned long) at arkcompiler/ets_runtime/ecmascript/js_thread.h:604:9
791e41f4b71Sopenharmony_ci(inlined by) panda::JSNApi::DisposeGlobalHandleAddr(panda::ecmascript::EcmaVM const*, unsigned long) at arkcompiler/ets_runtime/ecmascript/napi/jsnapi.cpp:752:24 BuildID[md5/uuid]=9a18e2ec0dc8a83216800b2f0dd7b76a
792e41f4b71Sopenharmony_ci    # 2 0x403ee94b68  (/system/asan/lib64/libace.z.so+0x6194b68) panda::CopyableGlobal<panda::FunctionRef>::Free() at arkcompiler/ets_runtime/ecmascript/napi/include/jsnapi.h:1520:9
793e41f4b71Sopenharmony_ci(inlined by) panda::CopyableGlobal<panda::FunctionRef>::Reset() at arkcompiler/ets_runtime/ecmascript/napi/include/jsnapi.h:189:9
794e41f4b71Sopenharmony_ci(inlined by) OHOS::Ace::Framework::JsiType<panda::FunctionRef>::Reset() at foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.inl:112:13
795e41f4b71Sopenharmony_ci(inlined by) OHOS::Ace::Framework::JsiWeak<OHOS::Ace::Framework::JsiFunction>::~JsiWeak() at foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/jsi/jsi_ref.h:167:16
796e41f4b71Sopenharmony_ci(inlined by) OHOS::Ace::Framework::ViewFunctions::~ViewFunctions() at foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/jsview/js_view_functions.h:44:5 BuildID[md5/uuid]=1330f8b9be73bdb76ae18107c2a60ca1
797e41f4b71Sopenharmony_ci    # 3 0x403ee9296c  (/system/asan/lib64/libace.z.so+0x619296c) OHOS::Ace::Framework::ViewFunctions::~ViewFunctions() at foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/jsview/js_view_functions.h:42:5
798e41f4b71Sopenharmony_ci(inlined by) OHOS::Ace::Framework::ViewFunctions::~ViewFunctions() at foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/jsview/js_view_functions.h:42:5 BuildID[md5/uuid]=1330f8b9be73bdb76ae18107c2a60ca1
799e41f4b71Sopenharmony_ci    # 4 0x403ed9b130  (/system/asan/lib64/libace.z.so+0x609b130) OHOS::Ace::Referenced::DecRefCount() at foundation/arkui/ace_engine/frameworks/base/memory/referenced.h:76:13
800e41f4b71Sopenharmony_ci(inlined by) OHOS::Ace::RefPtr<OHOS::Ace::Framework::ViewFunctions>::~RefPtr() at foundation/arkui/ace_engine/frameworks/base/memory/referenced.h:148:22 BuildID[md5/uuid]=1330f8b9be73bdb76ae18107c2a60ca1
801e41f4b71Sopenharmony_ci...
802e41f4b71Sopenharmony_cipreviously allocated by thread T0 (thread name) here:
803e41f4b71Sopenharmony_ci    # 0 0x2024ed3be4  (/system/asan/lib64/libclang_rt.asan.so+0xd3be4)
804e41f4b71Sopenharmony_ci    # 1 0x2029ade778  (/system/asan/lib64/platformsdk/libark_jsruntime.so+0xbde778) panda::ecmascript::NativeAreaAllocator::AllocateBuffer(unsigned long) at arkcompiler/ets_runtime/ecmascript/mem/native_area_allocator.cpp:98:17 BuildID[md5/uuid]=9a18e2ec0dc8a83216800b2f0dd7b76a
805e41f4b71Sopenharmony_ci    # 2 0x2029a39064  (/system/asan/lib64/platformsdk/libark_jsruntime.so+0xb39064) std::__h::enable_if<!std::is_array_v<panda::ecmascript::NodeList<panda::ecmascript::WeakNode>>, panda::ecmascript::NodeList<panda::ecmascript::WeakNode>*>::type panda::ecmascript::NativeAreaAllocator::New<panda::ecmascript::NodeList<panda::ecmascript::WeakNode>>() at arkcompiler/ets_runtime/ecmascript/mem/native_area_allocator.h:61:19
806e41f4b71Sopenharmony_ci(inlined by) unsigned long panda::ecmascript::EcmaGlobalStorage<panda::ecmascript::Node>::NewGlobalHandleImplement<panda::ecmascript::WeakNode>(panda::ecmascript::NodeList<panda::ecmascript::WeakNode>**, panda::ecmascript::NodeList<panda::ecmascript::WeakNode>**, unsigned long) at arkcompiler/ets_runtime/ecmascript/ecma_global_storage.h:565:34
807e41f4b71Sopenharmony_ci(inlined by) panda::ecmascript::EcmaGlobalStorage<panda::ecmascript::Node>::SetWeak(unsigned long, void*, void (*)(void*), void (*)(void*)) at arkcompiler/ets_runtime/ecmascript/ecma_global_storage.h:455:26 BuildID[md5/uuid]=9a18e2ec0dc8a83216800b2f0dd7b76a
808e41f4b71Sopenharmony_ci    # 3 0x2029ba5620  (/system/asan/lib64/platformsdk/libark_jsruntime.so+0xca5620) std::__h::__function::__value_func<unsigned long (unsigned long, void*, void (*)(void*), void (*)(void*))>::operator()[abi:v15004](unsigned long&&, void*&&, void (*&&)(void*), void (*&&)(void*)) const at prebuilts/clang/ohos/linux-x86_64/llvm/bin/../include/libcxx-ohos/include/c++/v1/__functional/function.h:512:16
809e41f4b71Sopenharmony_ci(inlined by) std::__h::function<unsigned long (unsigned long, void*, void (*)(void*), void (*)(void*))>::operator()(unsigned long, void*, void (*)(void*), void (*)(void*)) const at prebuilts/clang/ohos/linux-x86_64/llvm/bin/../include/libcxx-ohos/include/c++/v1/__functional/function.h:1197:12
810e41f4b71Sopenharmony_ci(inlined by) panda::ecmascript::JSThread::SetWeak(unsigned long, void*, void (*)(void*), void (*)(void*)) at arkcompiler/ets_runtime/ecmascript/js_thread.h:610:16
811e41f4b71Sopenharmony_ci(inlined by) panda::JSNApi::SetWeak(panda::ecmascript::EcmaVM const*, unsigned long) at arkcompiler/ets_runtime/ecmascript/napi/jsnapi.cpp:711:31 BuildID[md5/uuid]=9a18e2ec0dc8a83216800b2f0dd7b76a
812e41f4b71Sopenharmony_ci...
813e41f4b71Sopenharmony_ci```
814e41f4b71Sopenharmony_ci
815e41f4b71Sopenharmony_ciContinue the analysis based on the stack.
816e41f4b71Sopenharmony_ciWhen **JsiWeak** is destructed or reset, **CopyableGlobal** in the parent class **JsiType** of its member (**JsiObject**/**JsiValue**/**JsiFunction**) is released, as shown in the following figure.
817e41f4b71Sopenharmony_ci
818e41f4b71Sopenharmony_ci![cppcrash-demo5](figures/cppcrash_image_011.png)
819e41f4b71Sopenharmony_ci
820e41f4b71Sopenharmony_ciDuring Garbage Collection (GC), **IterateWeakEcmaGlobalStorage** calls **DisposeGlobalHandle** on **WeakNode** without a callback, and releases it, as shown in the following figure.
821e41f4b71Sopenharmony_ci
822e41f4b71Sopenharmony_ci![cppcrash-demo6](figures/cppcrash_image_012.png)
823e41f4b71Sopenharmony_ci
824e41f4b71Sopenharmony_ciTherefore, for the same **WeakNode**, there may be two functions for release. If **IterateWeakEcmaGlobalStorage** releases it first during GC, without a callback notification to **JsiWeak** for cleanup, **JsiWeak** still retains a reference **CopyableGlobal** to the released **WeakNode**. When the **NodeList** containing the **WeakNode** is released and returned to the operating system, the retained **CopyableGlobal** in **JsiWeak** is released again, leading to a double-free error. 
825e41f4b71Sopenharmony_ci
826e41f4b71Sopenharmony_ci![cppcrash-demo7](figures/cppcrash_image_013.png)
827e41f4b71Sopenharmony_ci
828e41f4b71Sopenharmony_ci**Solutions**
829e41f4b71Sopenharmony_ciInvoke a callback when **JsiWeak** calls **SetWeakCallback**. Therefore, the callback can notify **JsiWeak** to reset **CopyableGlobal** when **IterateWeakEcmaGlobalStorage** releases the **WeakNode**, ensuring the same address is not double-freed.
830e41f4b71Sopenharmony_ci
831e41f4b71Sopenharmony_ci**Suggestions**
832e41f4b71Sopenharmony_ciWhen using memory, consider whether the memory is double-freed or not freed. Additionally, when locating memory access crashes(usually **SIGSEGV** crashes),  run the ASan to reproduce the fault if there is no clue based on the crash stack analysis.
833e41f4b71Sopenharmony_ci
834e41f4b71Sopenharmony_ci#### Type 2: Multi-thread Crash
835e41f4b71Sopenharmony_ci
836e41f4b71Sopenharmony_ci**Background**
837e41f4b71Sopenharmony_ci**napi_env** is still used after being released.
838e41f4b71Sopenharmony_ci
839e41f4b71Sopenharmony_ci**Symptom**
840e41f4b71Sopenharmony_ciThe **env** of a **napi** API is invalid. The crash stack is mounted to **NativeEngineInterface::ClearLastError()**. Based on the log of **env** address, it is found that the **env** is used after being released. .
841e41f4b71Sopenharmony_ci
842e41f4b71Sopenharmony_ci![cppcrash-demo9](figures/cppcrash_image_015.png)
843e41f4b71Sopenharmony_ci
844e41f4b71Sopenharmony_ciThe key crash stack is as follows:
845e41f4b71Sopenharmony_ci
846e41f4b71Sopenharmony_ci![cppcrash-demo8](figures/cppcrash_image_014.png)
847e41f4b71Sopenharmony_ci
848e41f4b71Sopenharmony_ci**Solutions**
849e41f4b71Sopenharmony_ciThe **env** created by a thread should not be transferred to another thread.
850e41f4b71Sopenharmony_ci
851e41f4b71Sopenharmony_ci**Suggestions**
852e41f4b71Sopenharmony_ciYou can select the **Multi Thread Check** option to locate multi thread faults. For details, see "Ark Multi Thread Check" in guideline.
853e41f4b71Sopenharmony_ci
854e41f4b71Sopenharmony_ciNote: **env** in the **napi** interface is the **arkNativeEngine** when the engine is created.
855e41f4b71Sopenharmony_ci
856e41f4b71Sopenharmony_ci#### Type 3: Lifecycle Crash
857e41f4b71Sopenharmony_ci
858e41f4b71Sopenharmony_ci**Background**
859e41f4b71Sopenharmony_ciWhen you create a native **napi_value**, it needs to be used with **napi_handle_scope**. The **napi_handle_scope** is used to manage the lifecycle of **napi_value**. **napi_value** can be used only within **napi_handle_scope**, otherwise, the lifecycle of **napi_value** and its JS objects is no longer protected. If the reference count is 0, **napi_value** is collected by GC. Using **napi_value** at this point indicates accessing freed memory, which results in faults. 
860e41f4b71Sopenharmony_ci
861e41f4b71Sopenharmony_ci**Symptom**
862e41f4b71Sopenharmony_ci**napi_value** is a raw pointer (a struct pointer). It is used to hold JS objects and maintain the lifecycle of JS objects to ensure that JS objects are not collected by GC. **napi_handle_scope** is used to manage **napi_value**. Once out of **napi_handle_scope**, **napi_value** is collected by GC, and **napi_value** no longer holds the JS object (no longer protects the JS object's lifecycle)
863e41f4b71Sopenharmony_ci
864e41f4b71Sopenharmony_ci**Fault Analysis**
865e41f4b71Sopenharmony_ciBy decompiling the crash stack, the upper-level interface of the problematic **napi** interface can be located, in which the problematic **napi_value** can be found. In this case, you need to check if the **napi_value** is called out of **napi_handle_scope**. 
866e41f4b71Sopenharmony_ci
867e41f4b71Sopenharmony_ci**Cases**
868e41f4b71Sopenharmony_ciThe **napi_value** is called out of the scope of the NAPI framework.
869e41f4b71Sopenharmony_ci
870e41f4b71Sopenharmony_ci![cppcrash-demo9](figures/cppcrash_image_016.png)
871e41f4b71Sopenharmony_ci
872e41f4b71Sopenharmony_ciOn the JS side, data is added using the **Add()**, and on the native side, **napi_value** is saved to a **vector**. On the JS side, data is obtained using the **get** API, and on the native side, the saved **napi_value** is returned as an array. The JS side then reads the properties of the data. The error message "Can not get Prototype on non ECMA Object" is displayed. The **native_value** across **napi** is not saved using **napi_ref**. As a result, the **native_value** is invalid.
873e41f4b71Sopenharmony_ciNote: The scope of the NAPI framework is **napi_handle_scope**. You can use **napi_handle_scope** to manage the lifecycle of **napi_value**. The scope of the framework layer is embedded in the end-to-end process of the JS call native. That is, the scope is opened when the native method is entered, and the scope is closed when the native method ends.
874e41f4b71Sopenharmony_ci
875e41f4b71Sopenharmony_ci#### Type 4: Pointer Crash
876e41f4b71Sopenharmony_ci
877e41f4b71Sopenharmony_ci**Background**
878e41f4b71Sopenharmony_ciSmart pointers are used without null checks, causing null pointer dereference crashes during process execution. 
879e41f4b71Sopenharmony_ci
880e41f4b71Sopenharmony_ci**Impact**
881e41f4b71Sopenharmony_ciThe process crashes, causing unexpected exit.
882e41f4b71Sopenharmony_ci
883e41f4b71Sopenharmony_ci**Fault Analysis**
884e41f4b71Sopenharmony_ci![cppcrash-demo10](figures/cppcrash_image_017.png)
885e41f4b71Sopenharmony_ci
886e41f4b71Sopenharmony_ciNull pointer crashes can be identified based on the fault cause. Run the llvm-addr2line command to parse the line number. It is found that the service code does not check whether the smart pointer is null before using it. As a result, the service code accesses the null address, causing the crash.
887e41f4b71Sopenharmony_ci
888e41f4b71Sopenharmony_ci**Solution**
889e41f4b71Sopenharmony_ciAdd protective null checks for the pointer. 
890e41f4b71Sopenharmony_ci
891e41f4b71Sopenharmony_ci**Suggestions**
892e41f4b71Sopenharmony_ciPointers should be null-checked before using it to prevent null pointers and process crashes and exits.
893e41f4b71Sopenharmony_ci
894e41f4b71Sopenharmony_ci### Analyzing CppCrash Based on Tools
895e41f4b71Sopenharmony_ci
896e41f4b71Sopenharmony_ci#### Tool 1: ASAN
897e41f4b71Sopenharmony_ci
898e41f4b71Sopenharmony_ci[ASan Check](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-asan-0000001545528013-V5)
899e41f4b71Sopenharmony_ci
900e41f4b71Sopenharmony_ci#### Tool 2: Ark Multi Thread Check
901e41f4b71Sopenharmony_ci
902e41f4b71Sopenharmony_ci**Fundamentals**
903e41f4b71Sopenharmony_ciJS is single-threaded. Operations on JS objects can be performed only on the JS thread. Otherwise, multi-thread security problems may occur. (JS objects created on the main thread can be operated only on the main thread, and JS objects created on the worker thread can be operated only on the worker thread.) The napi APIs involve object operations. Therefore, 95% napi APIs can be used only on the JS thread. The multi-thread detection mechanism checks whether the **JS thread ID** of the calling thread is the same as that of the used **VM/Env**. If they are different, the **VM/Env** is used across threads, causing multi-thread security problems. Common problems: 1. Napi APIs are used in non-JS threads. 2. **env** of other threads are used in napi APIs.
904e41f4b71Sopenharmony_ci
905e41f4b71Sopenharmony_ci**How to Use**
906e41f4b71Sopenharmony_ci![cppcrash-demo13](figures/cppcrash_image_020.png)
907e41f4b71Sopenharmony_ci
908e41f4b71Sopenharmony_ciSelect **Multi Thread Check** on DevEco to enable Ark multi-thread detection.
909e41f4b71Sopenharmony_ci
910e41f4b71Sopenharmony_ci**Scenario**
911e41f4b71Sopenharmony_ciIf the stack of crash logs is difficult to analyze and the probability of this problem is high, you need to enable multi-thread detection. When the multi-thread detection is enabled, if the fatal information in the **cpp_crash** log is "Fatal: ecma_vm cannot run in multi-thread! thread:3096 currentThread:3550", it indicates that a multi-thread security problem occurs. That is, the calling thread ID is **3550**, but the JS thread is created by thread **3096**. The **vm** is used across threads.
912e41f4b71Sopenharmony_ci
913e41f4b71Sopenharmony_ci**Cases**
914e41f4b71Sopenharmony_ciAfter the function is enabled, the system crashes again. If the problem is caused by multiple threads, fatal information is displayed.
915e41f4b71Sopenharmony_ci
916e41f4b71Sopenharmony_ci```
917e41f4b71Sopenharmony_ciFatal: ecma_vm cannot run in multi-thread! thread:xxx currentThread:yyy
918e41f4b71Sopenharmony_ci```
919e41f4b71Sopenharmony_ci
920e41f4b71Sopenharmony_ciThe preceding information indicates that the calling thread ID is **17585**, but the JS thread is created by thread **17688**. The **vm** is used across threads. The **vm** is the **napi_env__*** of the JS thread. It is the environment for running thread code. One thread uses one **vm**.
921e41f4b71Sopenharmony_ciThe key crash log is as follows:
922e41f4b71Sopenharmony_ci
923e41f4b71Sopenharmony_ci```
924e41f4b71Sopenharmony_ci
925e41f4b71Sopenharmony_ciReason:Signal:SIGABRT(SI_TKILL)@0x01317b9f000044b1 from:17585: 20020127
926e41f4b71Sopenharmony_ciLastFatalMessage: [default] CheckThread:177 Fatal: ecma_vm cannot run in multi-thread! thread:17688 currentThread:17585
927e41f4b71Sopenharmony_ciFault thread Info:
928e41f4b71Sopenharmony_ciTid:17585, Name:xxxxx
929e41f4b71Sopenharmony_ci# 00 pc 00000000000f157c /system/lib/ld-musl-aarch64-asan.so.1(__restore_sigs+52)(38eb4ca904ae601d4b4dca502e948960)
930e41f4b71Sopenharmony_ci# 01 pc 00000000000f1800 /system/lib/ld-musl-aarch64-asan.so.1(raise+112) (38eb4ca904aeó01d4b4dca502e948960)
931e41f4b71Sopenharmony_ci# 02 pc 00000000000adc74 /system/lib/ld-musl-aarch64-asan.so.1(abort.+20) (38eb4ca904ae601d4b4dca502e948960)
932e41f4b71Sopenharmony_ci# 03 pc 0000000000844fdc /system/asan/libó4/platformsdk/libark_jsruntime.so(panda::ecmascript::EcmaVM::CheckThread() const+2712)(1df055932338c14060b864435aec88ab)
933e41f4b71Sopenharmony_ci# 04 pc 0000000000f3d930 /system/asan/libó4/platformsdk/libark_jsruntime.so(panda::0bjectRef:: New(panda::ecmascript::EcmaVM const*)+908)(1df055932338c14060b864435aec88
934e41f4b71Sopenharmony_ci# 05 pC 0000000000095048 /sYstem/asan/lib64/platformsdk/libace_napi.z.so(napi_create_object+80)(efc1b3d1378f56b4b800489fb30dcded)
935e41f4b71Sopenharmony_ci# 06 pc 00000000005d9770 /data/ storage/el1/bundle/libs/arm64/xxxxx.so (c0f1735eada49fadc5197745f5afOc0a52246270)
936e41f4b71Sopenharmony_ci```
937e41f4b71Sopenharmony_ci
938e41f4b71Sopenharmony_ciTo analyze the multi-thread problem, perform the following steps:
939e41f4b71Sopenharmony_cii. Check the first stack frame under **libace_napi.z.so**. The preceding figure shows **xxxxx.so**. Check whether the **napi_env** of thread **17688** is transferred to thread **17585**.
940e41f4b71Sopenharmony_ciii. If the stack frame under **libace_napi.z.so** does not transfer the **napi_env** parameter, check whether the parameter is transferred as a struct member variable.
941e41f4b71Sopenharmony_ci
942e41f4b71Sopenharmony_ci#### Tool 3: objdump
943e41f4b71Sopenharmony_ci
944e41f4b71Sopenharmony_ci**How to Use**
945e41f4b71Sopenharmony_ciobjdump binary is a system-side tool. Developers must have the OpenHarmony compilation environment. The project code can be obtained from Gitee.
946e41f4b71Sopenharmony_ci
947e41f4b71Sopenharmony_ci```
948e41f4b71Sopenharmony_cirepo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify --no-clone-bundle --depth=1
949e41f4b71Sopenharmony_cirepo sync -c
950e41f4b71Sopenharmony_ci./build/prebuilts_download.sh
951e41f4b71Sopenharmony_ci```
952e41f4b71Sopenharmony_ci
953e41f4b71Sopenharmony_ciThe tool is stored in the project directory **prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-objdump**.
954e41f4b71Sopenharmony_ci
955e41f4b71Sopenharmony_ci```
956e41f4b71Sopenharmony_ciprebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-objdump -d libark_jsruntime.so > dump.txt
957e41f4b71Sopenharmony_ci```
958e41f4b71Sopenharmony_ci
959e41f4b71Sopenharmony_ci**Scenario**
960e41f4b71Sopenharmony_ciIn some cases, addr2line can only be used to check whether a line of the code is faulty but cannot determine which variable is abnormal. In this case, you can use objdump to disassemble the code and combine the information from the cppcrash register to further determine the crash cause.
961e41f4b71Sopenharmony_ci
962e41f4b71Sopenharmony_ci**Cases**
963e41f4b71Sopenharmony_ciThe log is as follows:
964e41f4b71Sopenharmony_ci
965e41f4b71Sopenharmony_ci```
966e41f4b71Sopenharmony_ciTid:6655, Name:GC_WorkerThread
967e41f4b71Sopenharmony_ci# 00 pc 00000000004492d4 /system/lib64/platformsdk/libark_jsruntime.so(panda::ecmascript::NonMovableMarker::MarkObject(unsigned int, panda::ecmascript::TaggedObject*)+124)(21cf5411626d5986a4ba6383e959b3cc)
968e41f4b71Sopenharmony_ci# 01 pc 000000000044b580 /system/lib64/platformsdk/libark_jsruntime.so(panda::ecmascript::NonMovableMarker::MarkValue(unsigned int, panda::ecmascript::ObjectSlot&, panda::ecmascript::Region*, bool)+72)(21cf5411626d5986a4ba6383e959b3cc)
969e41f4b71Sopenharmony_ci# 02 pc 000000000044b4e8 /system/lib64/platformsdk/libark_jsruntime.so(std::__h::__function::__func<panda::ecmascript::NonMovableMarker::ProcessMarkStack(unsigned int)::$_2, std::__h::allocator<panda::ecmascript::NonMovableMarker::ProcessMarkStack(unsigned int)::$_2>, void (panda::ecmascript::TaggedObject*, panda::ecmascript::ObjectSlot, panda::ecmascript::ObjectSlot, panda::ecmascript::VisitObjectArea)>::operator()(panda::ecmascript::TaggedObject*&&, panda::ecmascript::ObjectSlot&&, panda::ecmascript::ObjectSlot&&, panda::ecmascript::VisitObjectArea&&)+256)(21cf5411626d5986a4ba6383e959b3cc)
970e41f4b71Sopenharmony_ci# 03 pc 0000000000442ac0 /system/lib64/platformsdk/libark_jsruntime.so(void panda::ecmascript::ObjectXRay::VisitObjectBody<(panda::ecmascript::VisitType)1>(panda::ecmascript::TaggedObject*, panda::ecmascript::JSHClass*, std::__h::function<void (panda::ecmascript::TaggedObject*, panda::ecmascript::ObjectSlot, panda::ecmascript::ObjectSlot, panda::ecmascript::VisitObjectArea)> const&)+216)(21cf5411626d5986a4ba6383e959b3cc)
971e41f4b71Sopenharmony_ci# 04 pc 0000000000447ccc /system/lib64/platformsdk/libark_jsruntime.so(panda::ecmascript::NonMovableMarker::ProcessMarkStack(unsigned int)+248)(21cf5411626d5986a4ba6383e959b3cc)
972e41f4b71Sopenharmony_ci# 05 pc 0000000000438588 /system/lib64/platformsdk/libark_jsruntime.so(panda::ecmascript::Heap::ParallelGCTask::Run(unsigned int)+148)(21cf5411626d5986a4ba6383e959b3cc)
973e41f4b71Sopenharmony_ci# 06 pc 00000000004e31c8 /system/lib64/platformsdk/libark_jsruntime.so(panda::ecmascript::Runner::Run(unsigned int)+144)(21cf5411626d5986a4ba6383e959b3cc)
974e41f4b71Sopenharmony_ci# 07 pc 00000000004e3780 /system/lib64/platformsdk/libark_jsruntime.so(void* std::__h::__thread_proxy[abi:v15004]<std::__h::tuple<std::__h::unique_ptr<std::__h::__thread_struct, std::__h::default_delete<std::__h::__thread_struct>>, void (panda::ecmascript::Runner::*)(unsigned int), panda::ecmascript::Runner*, unsigned int>>(void*)+64)(21cf5411626d5986a4ba6383e959b3cc)
975e41f4b71Sopenharmony_ci# 08 pc 000000000014d894 /system/lib/ld-musl-aarch64.so.1
976e41f4b71Sopenharmony_ci# 09 pc 0000000000085d04 /system/lib/ld-musl-aarch64.so.1
977e41f4b71Sopenharmony_ci```
978e41f4b71Sopenharmony_ci
979e41f4b71Sopenharmony_ciRun the addr2line to locate the error codes.
980e41f4b71Sopenharmony_ci
981e41f4b71Sopenharmony_ci![cppcrash-demo14](figures/cppcrash_image_021.png)
982e41f4b71Sopenharmony_ci
983e41f4b71Sopenharmony_ciThe preceding information indicates that a null pointer is accessed and the process is suspended when  **InYoungSpace** is accessed. Therefore, it can be suspected that the **Region** is a null pointer.
984e41f4b71Sopenharmony_ciUse objdump to disassemble and search for the error address **4492d4**. The command is as follows:
985e41f4b71Sopenharmony_ci
986e41f4b71Sopenharmony_ci![cppcrash-demo15](figures/cppcrash_image_022.png)
987e41f4b71Sopenharmony_ci
988e41f4b71Sopenharmony_ciCheck the **x20** register, and the value is **0x000000000000000**. The preceding information shows that the **x20** performs bitwise operation based on **x2** (the last 18 bits are cleared, which is a typical **Region::ObjectAddressToRange** operation). The analysis shows that **x2** is the second parameter object of the **MarkObject** function, and **x20** is the variable **objectRegion**.
989e41f4b71Sopenharmony_ci
990e41f4b71Sopenharmony_ci```
991e41f4b71Sopenharmony_ciRegisters: x0:0000007f0fe31560 x1:0000000000000003 x2:0000000000000000 x3:0000005593100000
992e41f4b71Sopenharmony_ci        x4:0000000000000000 x5:0000000000000000 x6:0000000000000000 x7:0000005596374fa0
993e41f4b71Sopenharmony_ci        x8:0000000000000000 x9:0000000000000000 x10:0000000000000000 x11:0000007f9cb42bb8
994e41f4b71Sopenharmony_ci        x12:000000000000005e x13:000000000061f59e x14:00000005d73d60fb x15:0000000000000000
995e41f4b71Sopenharmony_ci        x16:0000007f9cc5f200 x17:0000007f9f201f68 x18:0000000000000000 x19:0000000000000000
996e41f4b71Sopenharmony_ci        x20:0000000000000000 x21:0000000000000000 x22:0000000000000000 x23:000000559313f860
997e41f4b71Sopenharmony_ci        x24:000000559313f868 x25:0000000000000003 x26:00000055a0e19960 x27:0000007f9cc57b38
998e41f4b71Sopenharmony_ci        x28:0000007f9f21a1c0 x29:00000055a0e19700 lr:0000007f9cb4b584 sp:00000055a0e19700 pc:0000007f9cb492d4
999e41f4b71Sopenharmony_ci```
1000e41f4b71Sopenharmony_ci
1001e41f4b71Sopenharmony_ci**ldrb w8, [x20]** corresponds to **packedData_.flags_.spaceFlag_** because **packedData_** is the first field of **region**, **flags_** is the first field of **packedData_**, and **spaceFlag_** is the first field of **flags_**. Therefore, the first byte corresponding to the **objectRegion** address is used.
1002e41f4b71Sopenharmony_ciTo view assembly code, you need to be familiar with common assembly instructions and parameter transfer rules. For example, the non-inline member function **r0** in C++ stores the **this** pointer. In addition, due to compiler optimization, the mapping between source code and assembly code may not be clear. The mapping can be quickly obtained based on some feature values (constants) in the code.
1003