1e41f4b71Sopenharmony_ci# Memory Leak Check 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ci## Basic Concepts 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_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 mechanism 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. 7e41f4b71Sopenharmony_ci 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci## Function Configuration 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci**LOSCFG_MEM_LEAKCHECK** specifies the setting of the memory leak check. This function is disabled by default. You can enable it in **Debug-> Enable MEM Debug-> Enable Function call stack of Mem operation recorded**. 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci**LOS_RECORD_LR_CNT** specifies the number of LRs recorded. The default value is **3**. Each LR consumes the memory of **sizeof(void *)** bytes. 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci**LOS_OMIT_LR_CNT** specifies the number of ignored LRs. The default value is **2**, which indicates that LRs are recorded from the time when **LOS_MemAlloc** is called. You can change the value based on actual requirements. The reasons for this configuration are as follows: 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ci- **LOS_MemAlloc** is also called internally. 18e41f4b71Sopenharmony_ci- **LOS_MemAlloc** may be encapsulated externally. 19e41f4b71Sopenharmony_ci- The number of LRs configured by **LOS_RECORD_LR_CNT** is limited. 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ciCorrectly setting this macro can ignore invalid LRs and reduce memory consumption. 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ci 24e41f4b71Sopenharmony_ci## Development Guidelines 25e41f4b71Sopenharmony_ci 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ci### How to Develop 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_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. 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_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. 32e41f4b71Sopenharmony_ci 33e41f4b71Sopenharmony_ci 34e41f4b71Sopenharmony_ci``` 35e41f4b71Sopenharmony_cinode size LR[0] LR[1] LR[2] 36e41f4b71Sopenharmony_ci0x10017320: 0x528 0x9b004eba 0x9b004f60 0x9b005002 37e41f4b71Sopenharmony_ci0x10017848: 0xe0 0x9b02c24e 0x9b02c246 0x9b008ef0 38e41f4b71Sopenharmony_ci0x10017928: 0x50 0x9b008ed0 0x9b068902 0x9b0687c4 39e41f4b71Sopenharmony_ci0x10017978: 0x24 0x9b008ed0 0x9b068924 0x9b0687c4 40e41f4b71Sopenharmony_ci0x1001799c: 0x30 0x9b02c24e 0x9b02c246 0x9b008ef0 41e41f4b71Sopenharmony_ci0x100179cc: 0x5c 0x9b02c24e 0x9b02c246 0x9b008ef0 42e41f4b71Sopenharmony_ci``` 43e41f4b71Sopenharmony_ci 44e41f4b71Sopenharmony_ci> **CAUTION** 45e41f4b71Sopenharmony_ci> Enabling memory leak check affects memory application performance. LR addresses will be recorded for each memory node, increasing memory overhead. 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ci 48e41f4b71Sopenharmony_ci### Development Example 49e41f4b71Sopenharmony_ci 50e41f4b71Sopenharmony_ciThis example implements the following: 51e41f4b71Sopenharmony_ci 52e41f4b71Sopenharmony_ci1. Call **OsMemUsedNodeShow** to print information about all nodes. 53e41f4b71Sopenharmony_ci 54e41f4b71Sopenharmony_ci2. Simulate a memory leak by requesting memory without releasing it. 55e41f4b71Sopenharmony_ci 56e41f4b71Sopenharmony_ci3. Call **OsMemUsedNodeShow** to print information about all nodes. 57e41f4b71Sopenharmony_ci 58e41f4b71Sopenharmony_ci4. Compare the logs to obtain information about the node where a memory leak occurred. 59e41f4b71Sopenharmony_ci 60e41f4b71Sopenharmony_ci5. Locate the code based on the LR address. 61e41f4b71Sopenharmony_ci 62e41f4b71Sopenharmony_ci 63e41f4b71Sopenharmony_ci**Sample Code** 64e41f4b71Sopenharmony_ci 65e41f4b71Sopenharmony_ciYou can compile and verify the sample code in **kernel/liteos_a/testsuites/kernel/src/osTest.c**. The **MemLeakTest()** function is called in **TestTaskEntry**. 66e41f4b71Sopenharmony_ci 67e41f4b71Sopenharmony_ciIn this example, a memory pool is created. To achieve this purpose, you need to define **LOSCFG_MEM_MUL_POOL** in **target_config.h**. 68e41f4b71Sopenharmony_ci 69e41f4b71Sopenharmony_ciThe sample code is as follows: 70e41f4b71Sopenharmony_ci 71e41f4b71Sopenharmony_ci```c 72e41f4b71Sopenharmony_ci#include <stdio.h> 73e41f4b71Sopenharmony_ci#include <string.h> 74e41f4b71Sopenharmony_ci#include "los_memory.h" 75e41f4b71Sopenharmony_ci#include "los_config.h" 76e41f4b71Sopenharmony_ci 77e41f4b71Sopenharmony_ci#define TEST_NEW_POOL_SIZE 2000 78e41f4b71Sopenharmony_ci#define TEST_MALLOC_SIZE 8 79e41f4b71Sopenharmony_ci 80e41f4b71Sopenharmony_civoid MemLeakTest(void) 81e41f4b71Sopenharmony_ci{ 82e41f4b71Sopenharmony_ci VOID *pool = NULL; 83e41f4b71Sopenharmony_ci 84e41f4b71Sopenharmony_ci /* Create a memory pool. */ 85e41f4b71Sopenharmony_ci pool = LOS_MemAlloc(OS_SYS_MEM_ADDR, TEST_NEW_POOL_SIZE); 86e41f4b71Sopenharmony_ci (VOID)LOS_MemInit(pool, TEST_NEW_POOL_SIZE); 87e41f4b71Sopenharmony_ci 88e41f4b71Sopenharmony_ci OsMemUsedNodeShow(pool); 89e41f4b71Sopenharmony_ci void *ptr1 = LOS_MemAlloc(pool, TEST_MALLOC_SIZE); 90e41f4b71Sopenharmony_ci void *ptr2 = LOS_MemAlloc(pool, TEST_MALLOC_SIZE); 91e41f4b71Sopenharmony_ci OsMemUsedNodeShow(pool); 92e41f4b71Sopenharmony_ci 93e41f4b71Sopenharmony_ci /* Release the memory pool. */ 94e41f4b71Sopenharmony_ci (VOID)LOS_MemDeInit(pool); 95e41f4b71Sopenharmony_ci} 96e41f4b71Sopenharmony_ci``` 97e41f4b71Sopenharmony_ci 98e41f4b71Sopenharmony_ci 99e41f4b71Sopenharmony_ci**Verification** 100e41f4b71Sopenharmony_ci 101e41f4b71Sopenharmony_ci 102e41f4b71Sopenharmony_ciThe log is as follows: 103e41f4b71Sopenharmony_ci 104e41f4b71Sopenharmony_ci``` 105e41f4b71Sopenharmony_ci/* Log for the first OsMemUsedNodeShow. Because the memory pool is not allocated, there is no memory node. */ 106e41f4b71Sopenharmony_cinode LR[0] LR[1] LR[2] 107e41f4b71Sopenharmony_ci 108e41f4b71Sopenharmony_ci 109e41f4b71Sopenharmony_ci/* Log for the second OsMemUsedNodeShow. There are two memory nodes. */ 110e41f4b71Sopenharmony_cinode LR[0] LR[1] LR[2] 111e41f4b71Sopenharmony_ci0x00402e0d90: 0x004009f040 0x0040037614 0x0040005480 112e41f4b71Sopenharmony_ci0x00402e0db0: 0x004009f04c 0x0040037614 0x0040005480 113e41f4b71Sopenharmony_ci 114e41f4b71Sopenharmony_ci``` 115e41f4b71Sopenharmony_ci 116e41f4b71Sopenharmony_ci 117e41f4b71Sopenharmony_ciThe difference between the two logs is as follows. The following memory nodes are suspected to have blocks with a memory leak. 118e41f4b71Sopenharmony_ci 119e41f4b71Sopenharmony_ci``` 120e41f4b71Sopenharmony_ci0x00402e0d90: 0x004009f040 0x0040037614 0x0040005480 121e41f4b71Sopenharmony_ci0x00402e0db0: 0x004009f04c 0x0040037614 0x0040005480 122e41f4b71Sopenharmony_ci``` 123e41f4b71Sopenharmony_ci 124e41f4b71Sopenharmony_ci 125e41f4b71Sopenharmony_ciThe following is part of the assembly file: 126e41f4b71Sopenharmony_ci 127e41f4b71Sopenharmony_ci``` 128e41f4b71Sopenharmony_ci4009f014: 7d 1e a0 e3 mov r1, #2000 129e41f4b71Sopenharmony_ci4009f018: 00 00 90 e5 ldr r0, [r0] 130e41f4b71Sopenharmony_ci4009f01c: 67 7a fe eb bl #-398948 <LOS_MemAlloc> 131e41f4b71Sopenharmony_ci4009f020: 7d 1e a0 e3 mov r1, #2000 132e41f4b71Sopenharmony_ci4009f024: 00 40 a0 e1 mov r4, r0 133e41f4b71Sopenharmony_ci4009f028: c7 79 fe eb bl #-399588 <LOS_MemInit> 134e41f4b71Sopenharmony_ci4009f02c: 04 00 a0 e1 mov r0, r4 135e41f4b71Sopenharmony_ci4009f030: 43 78 fe eb bl #-401140 <OsMemUsedNodeShow> 136e41f4b71Sopenharmony_ci4009f034: 04 00 a0 e1 mov r0, r4 137e41f4b71Sopenharmony_ci4009f038: 08 10 a0 e3 mov r1, #8 138e41f4b71Sopenharmony_ci4009f03c: 5f 7a fe eb bl #-398980 <LOS_MemAlloc> 139e41f4b71Sopenharmony_ci4009f040: 04 00 a0 e1 mov r0, r4 140e41f4b71Sopenharmony_ci4009f044: 08 10 a0 e3 mov r1, #8 141e41f4b71Sopenharmony_ci4009f048: 5c 7a fe eb bl #-398992 <LOS_MemAlloc> 142e41f4b71Sopenharmony_ci4009f04c: 04 00 a0 e1 mov r0, r4 143e41f4b71Sopenharmony_ci4009f050: 3b 78 fe eb bl #-401172 <OsMemUsedNodeShow> 144e41f4b71Sopenharmony_ci4009f054: 3c 00 9f e5 ldr r0, [pc, #60] 145e41f4b71Sopenharmony_ci4009f058: 40 b8 fe eb bl #-335616 <dprintf> 146e41f4b71Sopenharmony_ci4009f05c: 04 00 a0 e1 mov r0, r4 147e41f4b71Sopenharmony_ci4009f060: 2c 7a fe eb bl #-399184 <LOS_MemDeInit> 148e41f4b71Sopenharmony_ci``` 149e41f4b71Sopenharmony_ci 150e41f4b71Sopenharmony_ci 151e41f4b71Sopenharmony_ciThe memory node addressed by **0x4009f040** is not released after being allocated in **MemLeakTest**. 152