1e41f4b71Sopenharmony_ci# Memory Debugging
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ciThe purpose of memory debugging is to locate problems related to dynamic memory. The kernel provides a variety of memory debugging methods. Dynamic memory pool statistics helps you learn the memory pool waterline and fragmentation rate. Memory leak check helps you accurately locate the code where memory leak occurs and analyze the memory usage of each module. Memory corruption check helps you locate memory corruptions.
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci## Memory Information Statistics
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci### Basic Concepts
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ciMemory information includes the memory pool size, memory usage, remaining memory size, maximum free memory, memory waterline, number of memory nodes, and fragmentation rate.
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ci- Memory waterline indicates the maximum memory used in a memory pool. The waterline value is updated upon each memory allocation and release. The memory pool size can be optimized based on this value.
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ci- Fragmentation rate indicates the fragmentation degree of the memory pool. If the fragmentation rate is high, there are a large number of free memory blocks in the memory pool but each block is small. You can use the following formula to calculate the fragmentation rate:<br>Fragmentation rate = 100 – 100 x Maximum free memory block size/Remaining memory size
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci- You can use [APIs for memory management](kernel-mini-basic-memory.md) to scan node information in the memory pool and collect statistics.
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci### Function Configuration
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci**LOSCFG_MEM_WATERLINE** specifies the setting of the memory information statistics function. This function is enabled by default. To disable the function, set this macro to **0** in **target_config.h**. If you want to obtain the memory waterline, you must enable this macro.
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci### Development Guidelines
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_ci#### How to Develop
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ciKey structure:
32e41f4b71Sopenharmony_ci
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ci```
35e41f4b71Sopenharmony_citypedef struct {
36e41f4b71Sopenharmony_ci    UINT32 totalUsedSize;       // Memory usage of the memory pool.
37e41f4b71Sopenharmony_ci    UINT32 totalFreeSize;       // Remaining size of the memory pool.
38e41f4b71Sopenharmony_ci    UINT32 maxFreeNodeSize;     // Maximum size of the free memory block in the memory pool.
39e41f4b71Sopenharmony_ci    UINT32 usedNodeNum;         // Number of non-free memory blocks in the memory pool.
40e41f4b71Sopenharmony_ci    UINT32 freeNodeNum;         // Number of free memory blocks in the memory pool.
41e41f4b71Sopenharmony_ci#if (LOSCFG_MEM_WATERLINE == 1) // The function is enabled by default. To disable it, set this macro to 0 in target_config.h.
42e41f4b71Sopenharmony_ci    UINT32 usageWaterLine;      // Waterline of the memory pool.
43e41f4b71Sopenharmony_ci#endif
44e41f4b71Sopenharmony_ci} LOS_MEM_POOL_STATUS;
45e41f4b71Sopenharmony_ci```
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ciTo obtain the memory waterline, call **LOS_MemInfoGet**. The first parameter in the API is the start address of the memory pool, and the second parameter is the handle of the **LOS_MEM_POOL_STATUS** type. The **usageWaterLine** field indicates the waterline.
48e41f4b71Sopenharmony_ci
49e41f4b71Sopenharmony_ciTo calculate the memory fragmentation rate, call **LOS_MemInfoGet** to obtain the remaining memory size and the maximum free memory block size in the memory pool, and then calculate the fragmentation rate of the dynamic memory pool as follows:<br>Fragmentation rate = 100 – 100 x Maximum free memory block size/Remaining memory size
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_ci#### Development Example
53e41f4b71Sopenharmony_ci
54e41f4b71Sopenharmony_ciThis example implements the following:
55e41f4b71Sopenharmony_ci
56e41f4b71Sopenharmony_ci1. Create a monitoring task to obtain information about the memory pool.
57e41f4b71Sopenharmony_ci
58e41f4b71Sopenharmony_ci2. Calls **LOS_MemInfoGet** to obtain the basic information about the memory pool.
59e41f4b71Sopenharmony_ci
60e41f4b71Sopenharmony_ci3. Calculate the memory usage and fragmentation rate.
61e41f4b71Sopenharmony_ci
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ci#### Sample Code
64e41f4b71Sopenharmony_ci
65e41f4b71Sopenharmony_ciThe sample code is as follows:
66e41f4b71Sopenharmony_ci
67e41f4b71Sopenharmony_ciThe sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **MemTest** function is called in **TestTaskEntry**.
68e41f4b71Sopenharmony_ci
69e41f4b71Sopenharmony_ci```
70e41f4b71Sopenharmony_ci#include <stdio.h>
71e41f4b71Sopenharmony_ci#include <string.h>
72e41f4b71Sopenharmony_ci#include "los_task.h"
73e41f4b71Sopenharmony_ci#include "los_memory.h"
74e41f4b71Sopenharmony_ci#include "los_config.h"
75e41f4b71Sopenharmony_ci
76e41f4b71Sopenharmony_ci#define TEST_TASK_PRIO  5
77e41f4b71Sopenharmony_civoid MemInfoTaskFunc(void)
78e41f4b71Sopenharmony_ci{
79e41f4b71Sopenharmony_ci    LOS_MEM_POOL_STATUS poolStatus = {0};
80e41f4b71Sopenharmony_ci
81e41f4b71Sopenharmony_ci    /* pool is the memory address of the information to be collected. OS_SYS_MEM_ADDR is used as an example. */
82e41f4b71Sopenharmony_ci    void *pool = OS_SYS_MEM_ADDR;
83e41f4b71Sopenharmony_ci    LOS_MemInfoGet(pool, &poolStatus);
84e41f4b71Sopenharmony_ci    /* Calculate the fragmentation rate of the memory pool. */
85e41f4b71Sopenharmony_ci    float fragment = 100 - poolStatus.maxFreeNodeSize * 100.0 / poolStatus.totalFreeSize;
86e41f4b71Sopenharmony_ci    /* Calculate the memory usage of the memory pool. */
87e41f4b71Sopenharmony_ci    float usage = LOS_MemTotalUsedGet(pool) * 100.0 / LOS_MemPoolSizeGet(pool);
88e41f4b71Sopenharmony_ci    printf("usage = %f, fragment = %f, maxFreeSize = %d, totalFreeSize = %d, waterLine = %d\n", usage, fragment, 
89e41f4b71Sopenharmony_ci    		poolStatus.maxFreeNodeSize, poolStatus.totalFreeSize, poolStatus.usageWaterLine);
90e41f4b71Sopenharmony_ci}
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ciint MemTest(void)
93e41f4b71Sopenharmony_ci{
94e41f4b71Sopenharmony_ci    unsigned int ret;
95e41f4b71Sopenharmony_ci    unsigned int taskID;
96e41f4b71Sopenharmony_ci    TSK_INIT_PARAM_S taskStatus = {0};
97e41f4b71Sopenharmony_ci    taskStatus.pfnTaskEntry = (TSK_ENTRY_FUNC)MemInfoTaskFunc;
98e41f4b71Sopenharmony_ci    taskStatus.uwStackSize  = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
99e41f4b71Sopenharmony_ci    taskStatus.pcName       = "memInfo";
100e41f4b71Sopenharmony_ci    taskStatus.usTaskPrio   = TEST_TASK_PRIO;
101e41f4b71Sopenharmony_ci    ret = LOS_TaskCreate(&taskID, &taskStatus);
102e41f4b71Sopenharmony_ci    if (ret != LOS_OK) {
103e41f4b71Sopenharmony_ci        printf("task create failed\n");
104e41f4b71Sopenharmony_ci        return -1;
105e41f4b71Sopenharmony_ci    }
106e41f4b71Sopenharmony_ci    return 0;
107e41f4b71Sopenharmony_ci}
108e41f4b71Sopenharmony_ci```
109e41f4b71Sopenharmony_ci
110e41f4b71Sopenharmony_ci
111e41f4b71Sopenharmony_ci#### Verification
112e41f4b71Sopenharmony_ci
113e41f4b71Sopenharmony_ciThe result is as follows:
114e41f4b71Sopenharmony_ci
115e41f4b71Sopenharmony_ci
116e41f4b71Sopenharmony_ci```
117e41f4b71Sopenharmony_ciusage = 0.458344, fragment = 0.000000, maxFreeSize = 16474928, totalFreeSize = 16474928, waterLine = 76816
118e41f4b71Sopenharmony_ci
119e41f4b71Sopenharmony_ciThe preceding data may vary depending on the running environment.
120e41f4b71Sopenharmony_ci```
121e41f4b71Sopenharmony_ci## Memory Leak Check
122e41f4b71Sopenharmony_ci
123e41f4b71Sopenharmony_ci
124e41f4b71Sopenharmony_ci### Basic Concepts
125e41f4b71Sopenharmony_ci
126e41f4b71Sopenharmony_ciAs an optional function of the kernel, memory leak check is used to locate dynamic memory leak problems. After this function is enabled, the dynamic memory automatically records the link registers (LRs) used when memory is allocated. If a memory leak occurs, the recorded information helps locate the memory allocated for further analysis.
127e41f4b71Sopenharmony_ci
128e41f4b71Sopenharmony_ci
129e41f4b71Sopenharmony_ci### Function Configuration
130e41f4b71Sopenharmony_ci
131e41f4b71Sopenharmony_ci**LOSCFG_MEM_LEAKCHECK** specifies the setting of the memory leak check. This function is disabled by default. To enable the function, set this macro to **1** in **target_config.h**.
132e41f4b71Sopenharmony_ci
133e41f4b71Sopenharmony_ci**LOSCFG_MEM_RECORD_LR_CNT** specifies the number of LRs recorded. The default value is **3**. Each LR consumes the memory of **sizeof(void \*)** bytes.
134e41f4b71Sopenharmony_ci
135e41f4b71Sopenharmony_ci**LOSCFG_MEM_OMIT_LR_CNT** specifies the number of ignored LRs. The default value is **4**, which indicates that LRs are recorded from the time when **LOS_MemAlloc** is called. You can change the value based on actual requirements. This macro is configured because:
136e41f4b71Sopenharmony_ci
137e41f4b71Sopenharmony_ci- **LOS_MemAlloc** is also called internally.
138e41f4b71Sopenharmony_ci- **LOS_MemAlloc** may be encapsulated externally.
139e41f4b71Sopenharmony_ci- The number of LRs configured by **LOSCFG_MEM_RECORD_LR_CNT** is limited.
140e41f4b71Sopenharmony_ci
141e41f4b71Sopenharmony_ciCorrectly setting this macro can ignore invalid LRs and reduce memory consumption.
142e41f4b71Sopenharmony_ci
143e41f4b71Sopenharmony_ci
144e41f4b71Sopenharmony_ci### Development Guidelines
145e41f4b71Sopenharmony_ci
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ci#### How to Develop
148e41f4b71Sopenharmony_ci
149e41f4b71Sopenharmony_ciMemory leak check provides a method to check for memory leak in key code logic. If this function is enabled, LR information is recorded each time when memory is allocated. When **LOS_MemUsedNodeShow** is called before and after the code snippet is checked, information about all nodes that have been used in the specified memory pool is printed. You can compare the node information. The newly added node information indicates the node where the memory leak may occur. You can locate the code based on the LR and further check whether a memory leak occurs.
150e41f4b71Sopenharmony_ci
151e41f4b71Sopenharmony_ciThe node information output by calling **LOS_MemUsedNodeShow** is in the following format: <br>Each line contains information about a node. The first column indicates the node address, based on which you can obtain complete node information using a tool such as a GNU Debugger (GDB). The second column indicates the node size, which is equal to the node header size plus the data field size. Columns 3 to 5 list the LR addresses. You can determine the specific memory location of the node based on the LR addresses and the assembly file.
152e41f4b71Sopenharmony_ci
153e41f4b71Sopenharmony_ci
154e41f4b71Sopenharmony_ci```
155e41f4b71Sopenharmony_cinode        size   LR[0]      LR[1]       LR[2]  
156e41f4b71Sopenharmony_ci0x10017320: 0x528 0x9b004eba  0x9b004f60  0x9b005002 
157e41f4b71Sopenharmony_ci0x10017848: 0xe0  0x9b02c24e  0x9b02c246  0x9b008ef0 
158e41f4b71Sopenharmony_ci0x10017928: 0x50  0x9b008ed0  0x9b068902  0x9b0687c4 
159e41f4b71Sopenharmony_ci0x10017978: 0x24  0x9b008ed0  0x9b068924  0x9b0687c4
160e41f4b71Sopenharmony_ci0x1001799c: 0x30  0x9b02c24e  0x9b02c246  0x9b008ef0 
161e41f4b71Sopenharmony_ci0x100179cc: 0x5c  0x9b02c24e  0x9b02c246  0x9b008ef0 
162e41f4b71Sopenharmony_ci```
163e41f4b71Sopenharmony_ci
164e41f4b71Sopenharmony_ci> **CAUTION**
165e41f4b71Sopenharmony_ci>
166e41f4b71Sopenharmony_ci> Enabling memory leak check affects memory application performance. LR addresses will be recorded for each memory node, increasing memory overhead.
167e41f4b71Sopenharmony_ci
168e41f4b71Sopenharmony_ci
169e41f4b71Sopenharmony_ci#### Development Example
170e41f4b71Sopenharmony_ci
171e41f4b71Sopenharmony_ciThis example implements the following:
172e41f4b71Sopenharmony_ci
173e41f4b71Sopenharmony_ci1. Call **LOS_MemUsedNodeShow** to print information about all nodes.
174e41f4b71Sopenharmony_ci
175e41f4b71Sopenharmony_ci2. Simulate a memory leak by requesting memory without releasing it.
176e41f4b71Sopenharmony_ci
177e41f4b71Sopenharmony_ci3. Call **LOS_MemUsedNodeShow** to print information about all nodes.
178e41f4b71Sopenharmony_ci
179e41f4b71Sopenharmony_ci4. Compare the logs to obtain information about the node where a memory leak occurred.
180e41f4b71Sopenharmony_ci
181e41f4b71Sopenharmony_ci5. Locate the code based on the LR address.
182e41f4b71Sopenharmony_ci
183e41f4b71Sopenharmony_ci
184e41f4b71Sopenharmony_ci#### Sample Code
185e41f4b71Sopenharmony_ci
186e41f4b71Sopenharmony_ciThe sample code is as follows:
187e41f4b71Sopenharmony_ci
188e41f4b71Sopenharmony_ciThe sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **MemLeakTest** function is called in **TestTaskEntry**.
189e41f4b71Sopenharmony_ci
190e41f4b71Sopenharmony_ciWhen QEMU is running, ensure that the value of **LOSCFG_MEM_FREE_BY_TASKID** in **target_config.h** is **0**.
191e41f4b71Sopenharmony_ci
192e41f4b71Sopenharmony_ciAfter the memory check function is enabled, other tasks running on certain platforms may frequently print memory-related information such as "psp, start = xxxxx, end = xxxxxxx". Ignore the information or delete the print information called by **OsStackAddrGet**.
193e41f4b71Sopenharmony_ci
194e41f4b71Sopenharmony_ci
195e41f4b71Sopenharmony_ci```
196e41f4b71Sopenharmony_ci#include <stdio.h>
197e41f4b71Sopenharmony_ci#include <string.h>
198e41f4b71Sopenharmony_ci#include "los_memory.h"
199e41f4b71Sopenharmony_ci#include "los_config.h"
200e41f4b71Sopenharmony_ci
201e41f4b71Sopenharmony_civoid MemLeakTest(void)
202e41f4b71Sopenharmony_ci{
203e41f4b71Sopenharmony_ci    LOS_MemUsedNodeShow(LOSCFG_SYS_HEAP_ADDR);
204e41f4b71Sopenharmony_ci    void *ptr1 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8);
205e41f4b71Sopenharmony_ci    void *ptr2 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8);
206e41f4b71Sopenharmony_ci    LOS_MemUsedNodeShow(LOSCFG_SYS_HEAP_ADDR);
207e41f4b71Sopenharmony_ci}
208e41f4b71Sopenharmony_ci```
209e41f4b71Sopenharmony_ci
210e41f4b71Sopenharmony_ci
211e41f4b71Sopenharmony_ci#### Verification
212e41f4b71Sopenharmony_ci
213e41f4b71Sopenharmony_ciThe log is as follows:
214e41f4b71Sopenharmony_ci
215e41f4b71Sopenharmony_ci
216e41f4b71Sopenharmony_ci```
217e41f4b71Sopenharmony_cinode         size   LR[0]       LR[1]       LR[2]   
218e41f4b71Sopenharmony_ci0x20001b04:  0x24   0x08001a10  0x080035ce  0x080028fc 
219e41f4b71Sopenharmony_ci0x20002058:  0x40   0x08002fe8  0x08003626  0x080028fc 
220e41f4b71Sopenharmony_ci0x200022ac:  0x40   0x08000e0c  0x08000e56  0x0800359e 
221e41f4b71Sopenharmony_ci0x20002594:  0x120  0x08000e0c  0x08000e56  0x08000c8a 
222e41f4b71Sopenharmony_ci0x20002aac:  0x56   0x08000e0c  0x08000e56  0x08004220 
223e41f4b71Sopenharmony_ci
224e41f4b71Sopenharmony_cinode         size   LR[0]       LR[1]       LR[2]   
225e41f4b71Sopenharmony_ci0x20001b04:  0x24   0x08001a10  0x080035ce  0x080028fc 
226e41f4b71Sopenharmony_ci0x20002058:  0x40   0x08002fe8  0x08003626  0x080028fc 
227e41f4b71Sopenharmony_ci0x200022ac:  0x40   0x08000e0c  0x08000e56  0x0800359e 
228e41f4b71Sopenharmony_ci0x20002594:  0x120  0x08000e0c  0x08000e56  0x08000c8a 
229e41f4b71Sopenharmony_ci0x20002aac:  0x56   0x08000e0c  0x08000e56  0x08004220 
230e41f4b71Sopenharmony_ci0x20003ac4:  0x1d   0x08001458  0x080014e0  0x080041e6 
231e41f4b71Sopenharmony_ci0x20003ae0:  0x1d   0x080041ee  0x08000cc2  0x00000000
232e41f4b71Sopenharmony_ci
233e41f4b71Sopenharmony_ciThe preceding data may vary depending on the running environment.
234e41f4b71Sopenharmony_ci```
235e41f4b71Sopenharmony_ci
236e41f4b71Sopenharmony_ciThe difference between the two logs is as follows. The following memory nodes are suspected to have blocks with a memory leak.
237e41f4b71Sopenharmony_ci
238e41f4b71Sopenharmony_ci
239e41f4b71Sopenharmony_ci```
240e41f4b71Sopenharmony_ci0x20003ac4:  0x1d   0x08001458  0x080014e0  0x080041e6 
241e41f4b71Sopenharmony_ci0x20003ae0:  0x1d   0x080041ee  0x08000cc2  0x00000000
242e41f4b71Sopenharmony_ci
243e41f4b71Sopenharmony_ciThe preceding data may vary depending on the running environment.
244e41f4b71Sopenharmony_ci```
245e41f4b71Sopenharmony_ci
246e41f4b71Sopenharmony_ciThe following is part of the assembly file:
247e41f4b71Sopenharmony_ci
248e41f4b71Sopenharmony_ci
249e41f4b71Sopenharmony_ci```
250e41f4b71Sopenharmony_ci                MemLeakTest:
251e41f4b71Sopenharmony_ci  0x80041d4: 0xb510         PUSH     {R4, LR}
252e41f4b71Sopenharmony_ci  0x80041d6: 0x4ca8         LDR.N    R4, [PC, #0x2a0]       ; g_memStart
253e41f4b71Sopenharmony_ci  0x80041d8: 0x0020         MOVS     R0, R4
254e41f4b71Sopenharmony_ci  0x80041da: 0xf7fd 0xf93e  BL       LOS_MemUsedNodeShow    ; 0x800145a
255e41f4b71Sopenharmony_ci  0x80041de: 0x2108         MOVS     R1, #8
256e41f4b71Sopenharmony_ci  0x80041e0: 0x0020         MOVS     R0, R4
257e41f4b71Sopenharmony_ci  0x80041e2: 0xf7fd 0xfbd9  BL       LOS_MemAlloc           ; 0x8001998
258e41f4b71Sopenharmony_ci  0x80041e6: 0x2108         MOVS     R1, #8
259e41f4b71Sopenharmony_ci  0x80041e8: 0x0020         MOVS     R0, R4
260e41f4b71Sopenharmony_ci  0x80041ea: 0xf7fd 0xfbd5  BL       LOS_MemAlloc           ; 0x8001998
261e41f4b71Sopenharmony_ci  0x80041ee: 0x0020         MOVS     R0, R4
262e41f4b71Sopenharmony_ci  0x80041f0: 0xf7fd 0xf933  BL       LOS_MemUsedNodeShow    ; 0x800145a
263e41f4b71Sopenharmony_ci  0x80041f4: 0xbd10         POP      {R4, PC}
264e41f4b71Sopenharmony_ci  0x80041f6: 0x0000         MOVS     R0, R0
265e41f4b71Sopenharmony_ci  
266e41f4b71Sopenharmony_ci  The preceding data may vary depending on the running environment.
267e41f4b71Sopenharmony_ci```
268e41f4b71Sopenharmony_ci
269e41f4b71Sopenharmony_ciThe memory node addressed by **0x080041ee** is not released after being requested in **MemLeakTest**.
270e41f4b71Sopenharmony_ci
271e41f4b71Sopenharmony_ci## Memory Corruption Check
272e41f4b71Sopenharmony_ci
273e41f4b71Sopenharmony_ci
274e41f4b71Sopenharmony_ci### Basic Concepts
275e41f4b71Sopenharmony_ci
276e41f4b71Sopenharmony_ciAs an optional function of the kernel, memory corruption check is used to check the integrity of a dynamic memory pool. This mechanism can detect memory corruption errors in the memory pool in a timely manner and provide alerts. It helps reduce problem locating costs and increase troubleshooting efficiency.
277e41f4b71Sopenharmony_ci
278e41f4b71Sopenharmony_ci
279e41f4b71Sopenharmony_ci### Function Configuration
280e41f4b71Sopenharmony_ci
281e41f4b71Sopenharmony_ci**LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK** specifies the setting of the memory corruption check. This function is disabled by default. To enable the function, set this macro to **1** in **target_config.h**.
282e41f4b71Sopenharmony_ci
283e41f4b71Sopenharmony_ci1. If this macro is enabled, the memory pool integrity will be checked in real time upon each memory allocation.
284e41f4b71Sopenharmony_ci
285e41f4b71Sopenharmony_ci2. If this macro is not enabled, you can call **LOS_MemIntegrityCheck** to check the memory pool integrity when required. Using **LOS_MemIntegrityCheck** does not affect the system performance. However, the check accuracy decreases because the node header does not contain the magic number (which is available only when **LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK** is enabled).
286e41f4b71Sopenharmony_ci
287e41f4b71Sopenharmony_ciThis check only detects the corrupted memory node and provides information about the previous node (because memory is contiguous, a node is most likely corrupted by the previous node). To further determine the location where the previous node is requested, you need to enable the memory leak check and use LRs to locate the fault.
288e41f4b71Sopenharmony_ci
289e41f4b71Sopenharmony_ci> **CAUTION**
290e41f4b71Sopenharmony_ci>
291e41f4b71Sopenharmony_ci> If memory corruption check is enabled, a magic number is added to the node header, which increases the size of the node header.  The real-time integrity check has a great impact on the performance. In performance-sensitive scenarios, you are advised to disable this function and use **LOS_MemIntegrityCheck** to check the memory pool integrity.
292e41f4b71Sopenharmony_ci
293e41f4b71Sopenharmony_ci
294e41f4b71Sopenharmony_ci### Development Guidelines
295e41f4b71Sopenharmony_ci
296e41f4b71Sopenharmony_ci
297e41f4b71Sopenharmony_ci#### How to Develop
298e41f4b71Sopenharmony_ci
299e41f4b71Sopenharmony_ciCheck for memory corruption by calling **LOS_MemIntegrityCheck**. If no memory corruption occurs, **0** is returned and no log is output. If memory corruption occurs, the related log is output. For details, see the output of the following example.
300e41f4b71Sopenharmony_ci
301e41f4b71Sopenharmony_ci
302e41f4b71Sopenharmony_ci#### Development Example
303e41f4b71Sopenharmony_ci
304e41f4b71Sopenharmony_ciThis example implements the following:
305e41f4b71Sopenharmony_ci
306e41f4b71Sopenharmony_ci1. Request two physically adjacent memory blocks.
307e41f4b71Sopenharmony_ci
308e41f4b71Sopenharmony_ci2. Use **memset** to construct an out-of-bounds access and overwrites the first four bytes of the next node.
309e41f4b71Sopenharmony_ci
310e41f4b71Sopenharmony_ci3. Call **LOS_MemIntegrityCheck** to check whether memory corruption occurs.
311e41f4b71Sopenharmony_ci
312e41f4b71Sopenharmony_ci
313e41f4b71Sopenharmony_ci#### Sample Code
314e41f4b71Sopenharmony_ci
315e41f4b71Sopenharmony_ciThe sample code is as follows:
316e41f4b71Sopenharmony_ci
317e41f4b71Sopenharmony_ciThe sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **MemIntegrityTest** function is called in **TestTaskEntry**.
318e41f4b71Sopenharmony_ci
319e41f4b71Sopenharmony_ciWhen QEMU is running, ensure that the value of **LOSCFG_MEM_FREE_BY_TASKID** in **target_config.h** is **0**.
320e41f4b71Sopenharmony_ci
321e41f4b71Sopenharmony_ciBecause the exception is triggered intentionally, you need to restart QEMU when the execution is complete. For example, open a new terminal and run **killall qemu-system-arm**.
322e41f4b71Sopenharmony_ci
323e41f4b71Sopenharmony_ci
324e41f4b71Sopenharmony_ci```
325e41f4b71Sopenharmony_ci#include <stdio.h>
326e41f4b71Sopenharmony_ci#include <string.h>
327e41f4b71Sopenharmony_ci#include "los_memory.h"
328e41f4b71Sopenharmony_ci#include "los_config.h"
329e41f4b71Sopenharmony_ci
330e41f4b71Sopenharmony_civoid MemIntegrityTest(void)
331e41f4b71Sopenharmony_ci{
332e41f4b71Sopenharmony_ci    /* Request two physically adjacent memory blocks. */
333e41f4b71Sopenharmony_ci    void *ptr1 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8);
334e41f4b71Sopenharmony_ci    void *ptr2 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8);
335e41f4b71Sopenharmony_ci    /* Construct an out-of-bounds access to cause memory corruption. The memory block of the first node is 8 bytes. Clearing 12 bytes overwrites the header of the second memory node. */
336e41f4b71Sopenharmony_ci    memset(ptr1, 0, 8 + 4);
337e41f4b71Sopenharmony_ci    LOS_MemIntegrityCheck(LOSCFG_SYS_HEAP_ADDR);
338e41f4b71Sopenharmony_ci}
339e41f4b71Sopenharmony_ci```
340e41f4b71Sopenharmony_ci
341e41f4b71Sopenharmony_ci
342e41f4b71Sopenharmony_ci#### Verification
343e41f4b71Sopenharmony_ci
344e41f4b71Sopenharmony_ciThe log is as follows:
345e41f4b71Sopenharmony_ci
346e41f4b71Sopenharmony_ci
347e41f4b71Sopenharmony_ci```
348e41f4b71Sopenharmony_ci
349e41f4b71Sopenharmony_ci/* Error information indicating the field corrupted. In this example, the first four bytes of the next node are cleared, that is, the magic number field is corrupted. */
350e41f4b71Sopenharmony_ci[ERR][IT_TST_INI][OsMemMagicCheckPrint], 1664, memory check error!
351e41f4b71Sopenharmony_cimemory used but magic num wrong, magic num = 0x0
352e41f4b71Sopenharmony_ci
353e41f4b71Sopenharmony_ci /* Key information about the corrupted node and its previous node, including the address of the previous node, magic number of the node, and sizeAndFlag of the node. In this example, the magic number of the corrupted node is cleared. */
354e41f4b71Sopenharmony_ci broken node head: 0x2103d7e8  0x0  0x80000020, prev node head: 0x2103c7cc  0xabcddcba  0x80000020
355e41f4b71Sopenharmony_ci
356e41f4b71Sopenharmony_ci /*The node LR information can be output only after the memory leak check is enabled. */
357e41f4b71Sopenharmony_ci broken node head LR info:
358e41f4b71Sopenharmony_ci LR[0]:0x2101906c
359e41f4b71Sopenharmony_ci LR[1]:0x0
360e41f4b71Sopenharmony_ci LR[2]:0x0
361e41f4b71Sopenharmony_ci
362e41f4b71Sopenharmony_ci /* Based on the LR information, you can determine where the previous node in requsted in the assembly file and check the use of the node. */
363e41f4b71Sopenharmony_ci pre node head LR info:
364e41f4b71Sopenharmony_ci LR[0]:0x2101906c
365e41f4b71Sopenharmony_ci LR[1]:0x0
366e41f4b71Sopenharmony_ci LR[2]:0x0
367e41f4b71Sopenharmony_ci 
368e41f4b71Sopenharmony_ci /* Addresses of the corrupted node and its previous node. */
369e41f4b71Sopenharmony_ci[ERR][IT_TST_INI]Memory integrity check error, cur node: 0x2103d784, pre node: 0x0
370e41f4b71Sopenharmony_ci
371e41f4b71Sopenharmony_ci The preceding data may vary depending on the running environment.
372e41f4b71Sopenharmony_ci```
373