• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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