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