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