• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# User-Mode Memory Debugging
2## Basic Concepts
3
4The musl libc library of the debug version provides mechanisms, such as memory leak check, heap memory statistics, memory corruption check, and backtrace, to improve the efficiency in locating memory problems in user space.
5
6
7Instrumentation is performed in the **malloc** and **free** APIs to log key node information. The memory node integrity is checked when memory is requested and released by an application. When the application ends, memory statistics are provided to help identifying memory leaks.
8
9## Working Principles
10
11
12### Memory Leak Check
13
14The memory debugging module maintains 128 (that is the maximum number of threads supported in the system) linked lists for each process. The index of each linked list is the thread ID.
15
16When memory is requested, key information is saved to the memory node control block, which is inserted to the corresponding linked list based on the thread ID.
17
18When memory is released, the system matches the memory node control block based on the memory address to be released and deletes the control block.
19
20**Figure 1** Heap memory node linked list
21
22![](figures/heap-memory-node-linked-list.png "heap-memory-node-linked-list")
23
24When memory is allocated, the returned address is saved in a link register (LR). During the process running, the system adds information, such as the LR corresponding to the suspected leak, to the memory node control block. The following figure shows the heap memory node information.
25
26**Figure 2** Heap memory node information
27
28![](figures/heap-memory-node-information.png "heap-memory-node-information")
29
30**TID** indicates the thread ID; **PID** indicates the process ID; **ptr** indicates the address of the memory requested; **size** indicates the size of the requested memory; **lr[*n*]** indicates the address of the call stack, and *n* is configurable.
31
32When memory is released, the input parameter pointer in the **free** API is used to match the **ptr** field of the memory node. If the pointer is the same as the **ptr** field of the memory node, the memory node control block will be deleted.
33
34You can export the memory debugging information of each process through the serial port or file, and use the addr2line tool to convert the exported information into the code lines that cause memory leaks. In this way, the memory leakage problem can be solved.
35
36**Figure 3** Process of locating the code line for a memory leak
37
38![](figures/process-of-locating-the-code-lines-for-a-memory-leak.png "process-of-locating-the-code-lines-for-a-memory-leak")
39
40
41### Heap Memory Statistics
42
43You can collect statistics on the percentage of heap memory requested by each thread to provide data support for optimizing memory usage of user programs. The **malloc** and **free** APIs are involved in user-mode heap memory statistics. As shown in the figure above, each process maintains 128 linked lists, and the index of each linked list is a thread ID. When heap memory is requested, the **ptr** and **size** information is recorded in the memory node control block, which is inserted to a linked list with the thread ID as the header. When the heap memory is released, the corresponding heap memory block is removed from the linked list based on the **ptr**. In addition, the system calculates the total heap memory used by the current thread and updates its heap memory usage and peak heap memory usage.
44
45
46### Memory Integrity Check
47
48- Requested memory less than or equal to 0x1c000 bytes
49
50  When the requested memory is less than or equal to 0x1c000 bytes, **malloc** uses the heap allocation algorithm to allocate memory.
51
52  When a user program requests heap memory, information such as the check value is added to the heap memory node. If the check value is abnormal, it is probably that the previous heap memory block is overwritten. Currently, the scenario where the check value is damaged by a wild pointer cannot be identified. When memory is allocated or released, the memory node check value is verified. If the memory node is corrupted and the verification fails, the following information is output: TID, PID, and call stack information saved when the previous heap memory block of the corrupted node is allocated. You can use the addr2line tool to obtain the specific code line and rectify the fault.
53
54  **Figure 4** Adding a check value to the node header information
55
56  ![](figures/adding-a-check-value-to-the-node-header-information.png "adding-a-check-value-to-the-node-header-information")
57
58  When heap memory is released by **free**, the memory block is not released immediately. Instead, the magic number 0xFE is written into the memory block, which is then placed in the free queue to prevent the memory block from being allocated by **malloc** within a certain period of time. When a wild pointer or **use-after-free** operation is performed to read the memory, an exception can be detected. However, this mechanism does not apply to write operations.
59
60  **Figure 5** Process of releasing memory
61
62  ![](figures/process-of-releasing-memory.png "process-of-releasing-memory")
63
64
65
66- Requested memory greater than 0x1c000 bytes
67
68  When the requested memory is greater than 0x1c000 bytes, **malloc** uses **mmap** to allocate memory.
69
70  When **mmap** is used to allocate a large memory block, one more page is allocated at the start and end of the memory region. The current **PAGE_SIZE** of each page is **0x1000**. The permissions of the two pages are set to **PROT_NONE** (no read or write permission) by using the **mprotect** API to prevent out-of-bounds read and write of memory. If out-of-bounds read and write of memory occurs, the user program becomes abnormal because the user does not have the read or write permission. The code logic can be identified based on the abnormal call stack information.
71
72  **Figure 6** Layout of the memory allocated by using the **mmap** mechanism of **malloc**
73
74  ![](figures/layout-of-the-memory-allocated-by-using-the-mmap-mechanism-of-malloc.png "layout-of-the-memory-allocated-by-using-the-mmap-mechanism-of-malloc")
75
76### Usage Guide
77#### Available APIs
78
79
80  **Table 1** Memory debugging APIs
81
82| API| Description|
83| -------- | -------- |
84| mem_check_init | Initializes the memory check module.|
85| watch_mem | Obtains the thread-level heap memory usage.|
86| check_leak | Checks for heap memory leaks.|
87| check_heap_integrity | Checks the heap memory integrity.|
88| backtrace | Obtains the address information of the call stack.|
89| backtrace_symbols | Obtains symbol information based on address information.|
90| print_trace | Prints call stack information.|
91
92
93  **Table 2** Call stack backtracking APIs
94
95| API| Description|
96| -------- | -------- |
97| backtrace | Obtains the address information of the call stack.|
98| backtrace_symbols | Obtains symbol information based on address information.|
99| print_trace | Prints call stack information.|
100
101### How to Use
102
103
104By default, the OpenHarmony debug version is compiled when a project is built. The libc library of the debug version has integrated the APIs for memory debugging. You can enable memory debugging as required.
105
106
107You can perform heap memory debugging by using either of the following:
108
109
110- API: By calling APIs, you can accurately check the heap memory information of a specific code logic segment. However, you have to modify user code.
111
112- CLI: By using the CLI, you do not need to modify user code. However, you cannot accurately check the heap memory information of a specific logic segment.
113
114
115> **NOTE**<br>
116> After memory debugging is enabled, a heap memory leak check and a heap memory integrity check will be performed by default when a process exits. If memory debugging is disabled, the heap memory statistics, heap memory leak check, and heap memory integrity check cannot be enabled, and there is no response to the calling of any debug API.
117
118
119
120
121#### Calling APIs
122
123
124##### Sample Code
125
126The sample code explicitly calls the related APIs of the memory debugging module to check the memory.
127
128
129```c
130#include <pthread.h>
131#include <stdlib.h>
132#include <stdio.h>
133#include <debug.h> // Header file that includes the declaration of the memory debugging APIs
134
135#define MALLOC_LEAK_SIZE  0x300
136
137void func(void)
138{
139    char *ptr = malloc(MALLOC_LEAK_SIZE);
140    memset(ptr, '3', MALLOC_LEAK_SIZE);
141}
142
143int main()
144{
145    mem_check_init(NULL); // Output the memory debugging information through the serial port. This function must be called before the user program requests the heap memory for the first time (generally called at the entry of the main function). Otherwise, the debugging information is inaccurate.
146    // mem_check_init("/storage/mem_debug.txt"); // Output the memory debugging information to the /storage/mem_debug.txt file. If the file fails to be created, output the information through the serial port.
147    char *ptr = malloc(MALLOC_LEAK_SIZE);
148    memset(ptr, '1', MALLOC_LEAK_SIZE);
149
150    watch_mem(); // Obtain the thread-level memory statistics in the current code.
151    func();
152    check_heap_integrity(); // Check the integrity of the heap memory nodes.
153    check_leak(); // Check whether a heap memory leak occurs in the current code. (Generally, the check result is accurate before the application exits. If the check is performed after the calling of malloc and before the calling of free, the result is inaccurate.)
154    return 0;
155}
156```
157
158
159##### Compilation
160
161
162```
163$ clang -o mem_check mem_check.c -funwind-tables -rdynamic -g -mfloat-abi=softfp -mcpu=cortex-a7 -mfpu=neon-vfpv4 -target arm-liteos --sysroot=/home/<user-name>/directory/out/hispark_taurus/ipcamera_hispark_taurus/sysroot $(clang -mfloat-abi=softfp -mcpu=cortex-a7 -mfpu=neon-vfpv4 -target arm-liteos -print-file-name=libunwind.a)
164```
165
166
167> **NOTE**
168>
169> - In this example, the compiler path is written into an environment variable in the **.bashrc** file.
170>
171> - When compiling user programs and required libraries, add the option **-funwind-tables -rdynamic -g** for stack backtracking.
172>
173> - The **-mfloat-abi=softfp**, **-mcpu=cortex-a7**, and **-mfpu=neon-vfpv4** options specify the floating-point calculation optimization, chip architecture, and FPU, which must be the same as the compilation options used by the libc library. Otherwise, the libc library file cannot be found during the link time.
174>
175> - **-target arm-liteos** specifies the path of the library files related to the compiler.
176>
177> - **--sysroot=/home/<user-name>/harmony/out/hispark_taurus/ipcamera_hispark_taurus/sysroot** specifies the root directory of the compiler library files. In this example, the OpenHarmony project code is stored in **/home/<user-name>/harmony**. The **out/hispark_taurus/ipcamera_hispark_taurus** directory indicates the product specified by the **hb set** command during compilation. In this example, **ipcamera_hispark_taurus** is the product specified.
178>
179> - **$(clang -mfloat-abi=softfp -mcpu=cortex-a7 -mfpu=neon-vfpv4 -target arm-liteos -print-file-name=libunwind.a)** specifies the path of the unwind library.
180
181
182##### Debugging Information
183
184
185```
186OHOS # ./mem_check
187OHOS #
188==PID:4== Heap memory statistics(bytes): // Heap memory statistics
189    [Check point]: // Call stack of the check point
190        #00: <main+0x38>[0x86c] -> mem_check
191        #01: <(null)+0x24baf9dc>[0x219dc] -> /lib/libc.so
192
193    [TID: 18, Used: 0x320] // The heap memory is occupied by thread No. 18. The current process has only one thread.
194
195==PID:4== Total heap: 0x320 byte(s), Peak: 0x320 byte(s)
196
197Check heap integrity ok! // Heap memory integrity check
198
199==PID:4== Detected memory leak(s): // Memory leak information and call stack
200    [Check point]:
201        #00: <check_leak+0x1c4>[0x2da4c] -> /lib/libc.so
202        #01: <main+0x44>[0x878] -> mem_check
203
204    [TID:18 Leak:0x320 byte(s)] Allocated from:
205        #00: <main+0x1c>[0x850] -> mem_check
206        #01: <(null)+0x24baf9dc>[0x219dc] -> /lib/libc.so
207
208    [TID:18 Leak:0x320 byte(s)] Allocated from:
209        #00: <func+0x14>[0x810] -> mem_check
210        #01: <main+0x3c>[0x870] -> mem_check
211        #02: <(null)+0x24baf9dc>[0x219dc] -> /lib/libc.so
212
213==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s).
214
215==PID:4== Detected memory leak(s):
216    [Check point]:
217        #00: <check_leak+0x1c4>[0x2da4c] -> /lib/libc.so
218        #01: <exit+0x28>[0x111ec] -> /lib/libc.so
219
220    [TID:18 Leak:0x320 byte(s)] Allocated from:
221        #00: <main+0x1c>[0x850] -> mem_check
222        #01: <(null)+0x24baf9dc>[0x219dc] -> /lib/libc.so
223
224    [TID:18 Leak:0x320 byte(s)] Allocated from:
225        #00: <func+0x14>[0x810] -> mem_check
226        #01: <main+0x3c>[0x870] -> mem_check
227        #02: <(null)+0x24baf9dc>[0x219dc] -> /lib/libc.so
228
229==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s).
230
231Check heap integrity ok!
232```
233
234
235##### Call Stack Parsing
236
237The **parse_mem_info.sh** script in **kernel/liteos_a/tools/scripts/parse_memory/** can be used to parse the call stack. You can use the script to convert the debug information into specific source code line number. In the following command, **mem_debug.txt** stores the memory debugging information, and **elf1** and **elf2** are the executable and linkable format (ELF) files to parse.
238
239
240```
241$ ./parse_mem_info.sh mem_debug.txt elf1 elf2 elf3 ...
242```
243
244Example:
245
246
247```
248$ ./parse_mem_info.sh mem_debug.txt mem_check
249Compiler is [gcc/llvm]: llvm
250Now using addr2line ...
251
252==PID:4== Heap memory statistics(bytes):
253    [Check point]:
254        #00: <main+0x38>[0x86c] at /usr1/xxx/TEST_ELF/mem_check.c:22
255        #01: <(null)+0x24baf9dc>[0x219dc] -> /lib/libc.so
256
257    [TID: 18, Used: 0x320]
258
259==PID:4== Total heap: 0x320 byte(s), Peak: 0x320 byte(s)
260
261Check heap integrity ok!
262
263==PID:4== Detected memory leak(s):
264    [Check point]:
265        #00: <check_leak+0x1c4>[0x2da4c] -> /lib/libc.so
266        #01: <main+0x44>[0x878] at /usr1/xxx/TEST_ELF/mem_check.c:28
267
268    [TID:18 Leak:0x320 byte(s)] Allocated from:
269        #00: <main+0x1c>[0x850] at /usr1/xxx/TEST_ELF/mem_check.c:17
270        #01: <(null)+0x24baf9dc>[0x219dc] -> /lib/libc.so
271
272    [TID:18 Leak:0x320 byte(s)] Allocated from:
273        #00: <func+0x14>[0x810] at /usr1/xxx/TEST_ELF/mem_check.c:9
274        #01: <main+0x3c>[0x870] at /usr1/xxx/TEST_ELF/mem_check.c:24
275        #02: <(null)+0x24baf9dc>[0x219dc] -> /lib/libc.so
276
277==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s).
278```
279
280#### Using the CLI
281
282
283In addition to calling APIs to check the memory used by user-mode processes, you can run CLI commands to collect memory statistics, check for memory leaks, and check memory integrity.
284
285```
286--mwatch: initializes memory debugging, registers signals, and outputs memory debugging information through the serial port.
287--mrecord <f_path>: initializes memory debugging, registers signals, and saves the memory debugging information to the f_path file. If the f_path file fails to be created, output the memory debugging information through the serial port.
288```
289
290
291If the process to debug does not exit, you can use the signal mechanism to obtain the corresponding information:
292
293```
294kill -35 <pid> # Check the thread-level heap memory usage.
295kill -36 <pid> # Check for heap memory leaks.
296kill -37 <pid> # Check whether the head node of the heap memory is complete.
297```
298
299
300##### Sample Code
301
302The sample code constructs a memory problem and uses the command line to perform memory debugging.
303
304
305```c
306#include <pthread.h>
307#include <stdlib.h>
308#include <stdio.h>
309
310#define MALLOC_LEAK_SIZE  0x300
311
312void func(void)
313{
314    char *ptr = malloc(MALLOC_LEAK_SIZE);
315    memset(ptr, '3', MALLOC_LEAK_SIZE);
316}
317
318int main()
319{
320    char *ptr = malloc(MALLOC_LEAK_SIZE);
321    memset(ptr, '1', MALLOC_LEAK_SIZE);
322    func();
323    while (1);
324}
325```
326
327
328##### Compilation
329
330For details, see [Compilation](#compilation).
331
332
333##### Running the mwatch Command
334
335
336```
337OHOS # ./mem_check --mwatch // Run the task command to obtain the mem_check process PID, which is 4.
338OHOS #
339OHOS # kill -35 4 // Check heap memory statistics.
340OHOS #
341==PID:4== Heap memory statistics(bytes):
342    [Check point]:
343        #00: <arm_signal_process+0x5c>[0x58dfc] -> /lib/libc.so
344
345    [TID: 18, Used: 0x640]
346
347==PID:4== Total heap: 0x640 byte(s), Peak: 0x640 byte(s)
348
349OHOS # kill -36 4 // Check for heap memory leaks.
350OHOS #
351==PID:4== Detected memory leak(s):
352    [Check point]:
353        #00: <check_leak+0x1c4>[0x2da4c] -> /lib/libc.so
354        #01: <arm_signal_process+0x5c>[0x58dfc] -> /lib/libc.so
355
356    [TID:18 Leak:0x320 byte(s)] Allocated from:
357        #00: <main+0x14>[0x724] -> mem_check
358        #01: <(null)+0x2555a9dc>[0x219dc] -> /lib/libc.so
359
360    [TID:18 Leak:0x320 byte(s)] Allocated from:
361        #00: <func+0x14>[0x6ec] -> mem_check
362        #01: <main+0x30>[0x740] -> mem_check
363        #02: <(null)+0x2555a9dc>[0x219dc] -> /lib/libc.so
364
365==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s).
366
367OHOS # kill -37 4 // Check the integrity of the head node of the heap memory.
368OHOS #
369Check heap integrity ok!
370```
371
372
373##### Call Stack Parsing
374
375Save the debugging information to the **test.txt** file and use the script to parse the information to obtain the number of the line where the memory leak occurs.
376
377
378```
379$ ./parse_mem_info.sh test.txt mem_check
380Compiler is [gcc/llvm]: llvm
381Now using addr2line ...
382
383==PID:4== Detected memory leak(s):
384    [Check point]:
385        #00: <check_leak+0x1c4>[0x2da4c] -> /lib/libc.so
386        #01: <arm_signal_process+0x5c>[0x58dfc] -> /lib/libc.so
387
388    [TID:18 Leak:0x320 byte(s)] Allocated from:
389        #00: <main+0x14>[0x724] at /usr1/xxx/TEST_ELF/mem_check.c:14
390        #01: <(null)+0x2555a9dc>[0x219dc] -> /lib/libc.so
391
392    [TID:18 Leak:0x320 byte(s)] Allocated from:
393        #00: <func+0x14>[0x6ec] at /usr1/xxx/TEST_ELF/mem_check.c:8
394        #01: <main+0x30>[0x740] at /usr1/xxx/TEST_ELF/mem_check.c:19
395        #02: <(null)+0x2555a9dc>[0x219dc] -> /lib/libc.so
396
397==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s).
398```
399
400
401##### Running the mrecord Command
402
4031. Run the user program and specify the path of the file that stores the memory debugging information.
404
405   ```
406   OHOS # ./mem_check --mrecord /storage/check.txt
407   ```
408
4092. Run the **kill -35 <*pid*>** command to collect statistics on the memory information. The information is exported to a file. Run the **cat** command to view the information.
410
411   ```
412   OHOS # kill -35 4
413   OHOS # Memory statistics information saved in /storage/pid(4)_check.txt
414
415   OHOS # cat /storage/pid(4)_check.txt
416
417   ==PID:4== Heap memory statistics(bytes):
418       [Check point]:
419           #00: <arm_signal_process+0x5c>[0x5973c] -> /lib/libc.so
420
421       [TID: 18, Used: 0x640]
422
423   ==PID:4== Total heap: 0x640 byte(s), Peak: 0x640 byte(s)
424   ```
425
4263. Run the **kill -36 <*pid*>** command to check memory integrity. The information is exported to a file. Run the **cat** command to view the information.
427
428   ```
429   OHOS # kill -36 4
430   OHOS # Leak check information saved in /storage/pid(4)_check.txt
431
432   OHOS # cat /storage/pid(4)_check.txt
433
434   ==PID:4== Heap memory statistics(bytes):
435       [Check point]:
436           #00: <arm_signal_process+0x5c>[0x5973c] -> /lib/libc.so
437
438       [TID: 18, Used: 0x640]
439
440   ==PID:4== Total heap: 0x640 byte(s), Peak: 0x640 byte(s)
441
442   ==PID:4== Detected memory leak(s):
443       [Check point]:
444           #00: <check_leak+0x1c4>[0x2e38c] -> /lib/libc.so
445           #01: <arm_signal_process+0x5c>[0x5973c] -> /lib/libc.so
446
447       [TID:18 Leak:0x320 byte(s)] Allocated from:
448           #00: <main+0x14>[0x724] -> mem_check
449           #01: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so
450
451       [TID:18 Leak:0x320 byte(s)] Allocated from:
452           #00: <func+0x14>[0x6ec] -> mem_check
453           #01: <main+0x30>[0x740] -> mem_check
454           #02: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so
455
456   ==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s).
457   ```
458
4594. Run the **kill -9 <*pid*>** command to kill the current process. After the process exits, a memory integrity check is performed by default. The check result is output to a file. You can run the **cat** command to view it.
460
461   ```
462   OHOS # kill -9 4
463   OHOS # Leak check information saved in /storage/pid(4)_check.txt
464
465   Check heap integrity ok!
466
467   OHOS # cat /storage/pid(4)_check.txt
468   OHOS #
469   ==PID:4== Heap memory statistics(bytes):
470       [Check point]:
471           #00: <arm_signal_process+0x5c>[0x5973c] -> /lib/libc.so
472
473       [TID: 18, Used: 0x640]
474
475   ==PID:4== Total heap: 0x640 byte(s), Peak: 0x640 byte(s)
476
477   ==PID:4== Detected memory leak(s):
478       [Check point]:
479           #00: <check_leak+0x1c4>[0x2e38c] -> /lib/libc.so
480           #01: <arm_signal_process+0x5c>[0x5973c] -> /lib/libc.so
481
482       [TID:18 Leak:0x320 byte(s)] Allocated from:
483           #00: <main+0x14>[0x724] -> mem_check
484           #01: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so
485
486       [TID:18 Leak:0x320 byte(s)] Allocated from:
487           #00: <func+0x14>[0x6ec] -> mem_check
488           #01: <main+0x30>[0x740] -> mem_check
489           #02: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so
490
491   ==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s).
492
493   ==PID:4== Detected memory leak(s):
494       [Check point]:
495           #00: <check_leak+0x1c4>[0x2e38c] -> /lib/libc.so
496           #01: <exit+0x28>[0x11b2c] -> /lib/libc.so
497
498       [TID:18 Leak:0x320 byte(s)] Allocated from:
499           #00: <main+0x14>[0x724] -> mem_check
500           #01: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so
501
502       [TID:18 Leak:0x320 byte(s)] Allocated from:
503           #00: <func+0x14>[0x6ec] -> mem_check
504           #01: <main+0x30>[0x740] -> mem_check
505           #02: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so
506
507   ==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s).
508   ```
509
510> **NOTE**<br>
511> The preceding information recorded gradually is added to the file specified during initialization. Therefore, running the **cat** command can also display the historical information in the file.
512## Common Problems
513
514
515### Use After Free (UAF)
516
517- Requested memory less than or equal to 0x1c000 bytes:
518
519  Read operation: If the magic number (0xFEFEFEFE) is read from the memory block released, UAF occurs.
520
521  > **NOTE**
522  >
523  > After **free** is called, the heap memory will not be released to the heap memory pool immediately. Instead, the heap memory is placed in a queue with a fixed length and filled with the magic number 0xFE. When the queue is full, the memory block first placed in the queue is released to the heap memory pool first.
524
525  Write operation: The memory debugging module cannot detect UAF errors from write operations.
526
527
528- Requested memory block greater than 0x1c000 bytes:
529
530  The heap memory greater than 0x1c000 bytes must be requested by calling the **mmap** API via **malloc**. If the heap memory is accessed after being released, the user program will become abnormal (because the memory region has been unmapped).
531
532
533### Double Free
534
535Double free errors occur when **free()** is called more than once with the same memory address as an argument. When a double free error occurs, the user program exits unexpectedly.
536
537
538### Heap Memory Node Corrupted
539
540- Requested memory block less than or equal to 0x1c000 bytes:
541
542  When a heap memory node is corrupted, the user program exits unexpectedly, and the call stack that requests the heap memory of the node corrupted is output. The memory debugging module, however, cannot debug the memory corrupted by a wild pointer. For example, if the user program mem_check has heap memory overwriting, you can use the command line to obtain the possible location of the memory corruption.
543
544
545  ```
546  OHOS # ./mem_check --mwatch
547  OHOS #
548  ==PID:6== Memory integrity information:
549      [TID:28 allocated addr: 0x272e1ea0, size: 0x120] The possible attacker was allocated from:
550          #00: <malloc+0x808>[0x640e8] -> /lib/libc.so
551          #01: <threadFunc1+0x7c>[0x21d0] -> mem_check
552  ```
553
554  You can use the call stack parsing script to parse the call stack information.
555
556- Requested memory block greater than 0x1c000 bytes:
557
558  When a large memory block (greater than 0x1c000 bytes) is requested by calling the **mmap** API via **malloc**, one more page of **PAGE_SIZE** is allocated at the start and end of the memory region. The two pages are neither readable nor writeable. Any read or write operation to the pages may cause an exception of the user program.
559