1# Memory Leak Check 2 3 4## Basic Concepts 5 6As 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. 7 8 9## Function Configuration 10 11**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**. 12 13**LOS_RECORD_LR_CNT** specifies the number of LRs recorded. The default value is **3**. Each LR consumes the memory of **sizeof(void *)** bytes. 14 15**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: 16 17- **LOS_MemAlloc** is also called internally. 18- **LOS_MemAlloc** may be encapsulated externally. 19- The number of LRs configured by **LOS_RECORD_LR_CNT** is limited. 20 21Correctly setting this macro can ignore invalid LRs and reduce memory consumption. 22 23 24## Development Guidelines 25 26 27### How to Develop 28 29Memory 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. 30 31The 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. 32 33 34``` 35node size LR[0] LR[1] LR[2] 360x10017320: 0x528 0x9b004eba 0x9b004f60 0x9b005002 370x10017848: 0xe0 0x9b02c24e 0x9b02c246 0x9b008ef0 380x10017928: 0x50 0x9b008ed0 0x9b068902 0x9b0687c4 390x10017978: 0x24 0x9b008ed0 0x9b068924 0x9b0687c4 400x1001799c: 0x30 0x9b02c24e 0x9b02c246 0x9b008ef0 410x100179cc: 0x5c 0x9b02c24e 0x9b02c246 0x9b008ef0 42``` 43 44> **CAUTION** 45> Enabling memory leak check affects memory application performance. LR addresses will be recorded for each memory node, increasing memory overhead. 46 47 48### Development Example 49 50This example implements the following: 51 521. Call **OsMemUsedNodeShow** to print information about all nodes. 53 542. Simulate a memory leak by requesting memory without releasing it. 55 563. Call **OsMemUsedNodeShow** to print information about all nodes. 57 584. Compare the logs to obtain information about the node where a memory leak occurred. 59 605. Locate the code based on the LR address. 61 62 63**Sample Code** 64 65You can compile and verify the sample code in **kernel/liteos_a/testsuites/kernel/src/osTest.c**. The **MemLeakTest()** function is called in **TestTaskEntry**. 66 67In this example, a memory pool is created. To achieve this purpose, you need to define **LOSCFG_MEM_MUL_POOL** in **target_config.h**. 68 69The sample code is as follows: 70 71```c 72#include <stdio.h> 73#include <string.h> 74#include "los_memory.h" 75#include "los_config.h" 76 77#define TEST_NEW_POOL_SIZE 2000 78#define TEST_MALLOC_SIZE 8 79 80void MemLeakTest(void) 81{ 82 VOID *pool = NULL; 83 84 /* Create a memory pool. */ 85 pool = LOS_MemAlloc(OS_SYS_MEM_ADDR, TEST_NEW_POOL_SIZE); 86 (VOID)LOS_MemInit(pool, TEST_NEW_POOL_SIZE); 87 88 OsMemUsedNodeShow(pool); 89 void *ptr1 = LOS_MemAlloc(pool, TEST_MALLOC_SIZE); 90 void *ptr2 = LOS_MemAlloc(pool, TEST_MALLOC_SIZE); 91 OsMemUsedNodeShow(pool); 92 93 /* Release the memory pool. */ 94 (VOID)LOS_MemDeInit(pool); 95} 96``` 97 98 99**Verification** 100 101 102The log is as follows: 103 104``` 105/* Log for the first OsMemUsedNodeShow. Because the memory pool is not allocated, there is no memory node. */ 106node LR[0] LR[1] LR[2] 107 108 109/* Log for the second OsMemUsedNodeShow. There are two memory nodes. */ 110node LR[0] LR[1] LR[2] 1110x00402e0d90: 0x004009f040 0x0040037614 0x0040005480 1120x00402e0db0: 0x004009f04c 0x0040037614 0x0040005480 113 114``` 115 116 117The difference between the two logs is as follows. The following memory nodes are suspected to have blocks with a memory leak. 118 119``` 1200x00402e0d90: 0x004009f040 0x0040037614 0x0040005480 1210x00402e0db0: 0x004009f04c 0x0040037614 0x0040005480 122``` 123 124 125The following is part of the assembly file: 126 127``` 1284009f014: 7d 1e a0 e3 mov r1, #2000 1294009f018: 00 00 90 e5 ldr r0, [r0] 1304009f01c: 67 7a fe eb bl #-398948 <LOS_MemAlloc> 1314009f020: 7d 1e a0 e3 mov r1, #2000 1324009f024: 00 40 a0 e1 mov r4, r0 1334009f028: c7 79 fe eb bl #-399588 <LOS_MemInit> 1344009f02c: 04 00 a0 e1 mov r0, r4 1354009f030: 43 78 fe eb bl #-401140 <OsMemUsedNodeShow> 1364009f034: 04 00 a0 e1 mov r0, r4 1374009f038: 08 10 a0 e3 mov r1, #8 1384009f03c: 5f 7a fe eb bl #-398980 <LOS_MemAlloc> 1394009f040: 04 00 a0 e1 mov r0, r4 1404009f044: 08 10 a0 e3 mov r1, #8 1414009f048: 5c 7a fe eb bl #-398992 <LOS_MemAlloc> 1424009f04c: 04 00 a0 e1 mov r0, r4 1434009f050: 3b 78 fe eb bl #-401172 <OsMemUsedNodeShow> 1444009f054: 3c 00 9f e5 ldr r0, [pc, #60] 1454009f058: 40 b8 fe eb bl #-335616 <dprintf> 1464009f05c: 04 00 a0 e1 mov r0, r4 1474009f060: 2c 7a fe eb bl #-399184 <LOS_MemDeInit> 148``` 149 150 151The memory node addressed by **0x4009f040** is not released after being allocated in **MemLeakTest**. 152