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