1Malloc Debug 2============ 3 4Malloc debug is a method of debugging native memory problems. It can help 5detect memory corruption, memory leaks, and use after free issues. 6 7This documentation describes how to enable this feature on Android N or later 8versions of the Android OS. (See the "Examples" section.) 9 10The documentation for malloc debug on older versions of Android is 11[here](README_marshmallow_and_earlier.md). 12 13When malloc debug is enabled, it works by adding a shim layer that replaces 14the normal allocation calls. The replaced calls are: 15 16* `malloc` 17* `free` 18* `calloc` 19* `realloc` 20* `posix_memalign` 21* `memalign` 22* `aligned_alloc` 23* `malloc_usable_size` 24 25On 32 bit systems, these two deprecated functions are also replaced: 26 27* `pvalloc` 28* `valloc` 29 30Any errors detected by the library are reported in the log. 31 32NOTE: There is a small behavioral change beginning in P for realloc. 33Before, a realloc from one size to a smaller size would not update the 34backtrace related to the allocation. Starting in P, every single realloc 35call changes the backtrace for the pointer no matter whether the pointer 36returned has changed or not. 37 38 39Controlling Malloc Debug Behavior 40--------------------------------- 41Malloc debug is controlled by individual options. Each option can be enabled 42individually, or in a group of other options. Every single option can be 43combined with every other option. 44 45Option Descriptions 46------------------- 47### front\_guard[=SIZE\_BYTES] 48Enables a small buffer placed before the allocated data. This is an attempt 49to find memory corruption occuring to a region before the original allocation. 50On first allocation, this front guard is written with a specific pattern (0xaa). 51When the allocation is freed, the guard is checked to verify it has not been 52modified. If any part of the front guard is modified, an error will be reported 53in the log indicating what bytes changed. 54 55If the backtrace option is also enabled, then any error message will include 56the backtrace of the allocation site. 57 58If SIZE\_BYTES is present, it indicates the number of bytes in the guard. 59The default is 32 bytes, the max bytes is 16384. SIZE\_BYTES will be 60padded so that it is a multiple of 8 bytes on 32 bit systems and 16 bytes 61on 64 bit systems to make sure that the allocation returned is aligned 62properly. 63 64This option adds a special header to all allocations that contains the guard 65and information about the original allocation. 66 67Example error: 68 69 04-10 12:00:45.621 7412 7412 E malloc_debug: +++ ALLOCATION 0x12345678 SIZE 100 HAS A CORRUPTED FRONT GUARD 70 04-10 12:00:45.622 7412 7412 E malloc_debug: allocation[-32] = 0x00 (expected 0xaa) 71 04-10 12:00:45.622 7412 7412 E malloc_debug: allocation[-15] = 0x02 (expected 0xaa) 72 73### rear\_guard[=SIZE\_BYTES] 74Enables a small buffer placed after the allocated data. This is an attempt 75to find memory corruption occuring to a region after the original allocation. 76On first allocation, this rear guard is written with a specific pattern (0xbb). 77When the allocation is freed, the guard is checked to verify it has not been 78modified. If any part of the rear guard is modified, an error will be reported 79in the log indicating what bytes changed. 80 81If SIZE\_BYTES is present, it indicates the number of bytes in the guard. 82The default is 32 bytes, the max bytes is 16384. 83 84This option adds a special header to all allocations that contains 85information about the original allocation. 86 87Example error: 88 89 04-10 12:00:45.621 7412 7412 E malloc_debug: +++ ALLOCATION 0x12345678 SIZE 100 HAS A CORRUPTED REAR GUARD 90 04-10 12:00:45.622 7412 7412 E malloc_debug: allocation[130] = 0xbf (expected 0xbb) 91 04-10 12:00:45.622 7412 7412 E malloc_debug: allocation[131] = 0x00 (expected 0xbb) 92 93### guard[=SIZE\_BYTES] 94Enables both a front guard and a rear guard on all allocations. 95 96If SIZE\_BYTES is present, it indicates the number of bytes in both guards. 97The default is 32 bytes, the max bytes is 16384. 98 99### backtrace[=MAX\_FRAMES] 100Enable capturing the backtrace of each allocation site. 101This option will slow down allocations by an order of magnitude. If the 102system runs too slowly with this option enabled, decreasing the maximum number 103of frames captured will speed the allocations up. 104 105Note that any backtrace frames that occur within the malloc backtrace library 106itself are not recorded. 107 108If MAX\_FRAMES is present, it indicates the maximum number of frames to 109capture in a backtrace. The default is 16 frames, the maximumum value 110this can be set to is 256. 111 112Before P, this option adds a special header to all allocations that contains 113the backtrace and information about the original allocation. After that, this 114option will not add a special header. 115 116As of P, this option will also enable dumping backtrace heap data to a 117file when the process receives the signal SIGRTMAX - 17 ( which is 47 on most 118Android devices). The format of this dumped data is the same format as 119that dumped when running am dumpheap -n. The default is to dump this data 120to the file /data/local/tmp/backtrace\_heap.**PID**.txt. This is useful when 121used with native only executables that run for a while since these processes 122are not spawned from a zygote process. 123 124Note that when the signal is received, the heap is not dumped until the next 125malloc/free occurs. 126 127### backtrace\_enable\_on\_signal[=MAX\_FRAMES] 128Enable capturing the backtrace of each allocation site. If the 129backtrace capture is toggled when the process receives the signal 130SIGRTMAX - 19 (which is 45 on most Android devices). When this 131option is used alone, backtrace capture starts out disabled until the signal 132is received. If both this option and the backtrace option are set, then 133backtrace capture is enabled until the signal is received. 134 135If MAX\_FRAMES is present, it indicates the maximum number of frames to 136capture in a backtrace. The default is 16 frames, the maximumum value 137this can be set to is 256. 138 139Before P, this option adds a special header to all allocations that contains 140the backtrace and information about the original allocation. After that, this 141option will not add a special header. 142 143### backtrace\_dump\_on\_exit 144As of P, when the backtrace option has been enabled, this causes the backtrace 145dump heap data to be dumped to a file when the program exits. If the backtrace 146option has not been enabled, this does nothing. The default is to dump this 147to the file named /data/local/tmp/backtrace\_heap.**PID**.exit.txt. 148 149The file location can be changed by setting the backtrace\_dump\_prefix 150option. 151 152### backtrace\_dump\_prefix 153As of P, when one of the backtrace options has been enabled, this sets the 154prefix used for dumping files when the signal SIGRTMAX - 17 is received or when 155the program exits and backtrace\_dump\_on\_exit is set. 156 157The default is /data/local/tmp/backtrace\_heap. 158 159When this value is changed from the default, then the filename chosen 160on the signal will be backtrace\_dump\_prefix.**PID**.txt. The filename chosen 161when the program exits will be backtrace\_dump\_prefix.**PID**.exit.txt. 162 163### backtrace\_full 164As of Q, any time that a backtrace is gathered, a different algorithm is used 165that is extra thorough and can unwind through Java frames. This will run 166slower than the normal backtracing function. 167 168### fill\_on\_alloc[=MAX\_FILLED\_BYTES] 169Any allocation routine, other than calloc, will result in the allocation being 170filled with the value 0xeb. When doing a realloc to a larger size, the bytes 171above the original usable size will be set to 0xeb. 172 173If MAX\_FILLED\_BYTES is present, it will only fill up to the specified number 174of bytes in the allocation. The default is to fill the entire allocation. 175 176### fill\_on\_free[=MAX\_FILLED\_BYTES] 177When an allocation is freed, fill it with 0xef. 178 179If MAX\_FILLED\_BYTES is present, it will only fill up to the specified number 180of bytes in the allocation. The default is to fill the entire allocation. 181 182### fill[=MAX\_FILLED\_BYTES] 183This enables both the fill\_on\_alloc option and the fill\_on\_free option. 184 185If MAX\_FILLED\_BYTES is present, it will only fill up to the specified number 186of bytes in the allocation. The default is to fill the entire allocation. 187 188### expand\_alloc[=EXPAND\_BYTES] 189Add an extra amount to allocate for every allocation. 190 191If XX is present, it is the number of bytes to expand the allocation by. 192The default is 16 bytes, the max bytes is 16384. 193 194### free\_track[=ALLOCATION\_COUNT] 195When a pointer is freed, do not free the memory right away, but add it to 196a list of freed allocations. In addition to being added to the list, the 197entire allocation is filled with the value 0xef, and the backtrace at 198the time of the free is recorded. The backtrace recording is completely 199separate from the backtrace option, and happens automatically if this 200option is enabled. By default, a maximum of 16 frames will be recorded, 201but this value can be changed using the free\_track\_backtrace\_num\_frames 202option. It can also be completely disabled by setting the option to zero. 203See the full description of this option below. 204 205When the list is full, an allocation is removed from the list and is 206checked to make sure that none of the contents have been modified since 207being placed on the list. When the program terminates, all of the allocations 208left on the list are verified. 209 210If ALLOCATION\_COUNT is present, it indicates the total number of allocations 211in the list. The default is to record 100 freed allocations, the max 212allocations to record is 16384. 213 214Before P, this option adds a special header to all allocations that contains 215the backtrace and information about the original allocation. After that, this 216option will not add a special header. 217 218Example error: 219 220 04-15 12:00:31.304 7412 7412 E malloc_debug: +++ ALLOCATION 0x12345678 USED AFTER FREE 221 04-15 12:00:31.305 7412 7412 E malloc_debug: allocation[20] = 0xaf (expected 0xef) 222 04-15 12:00:31.305 7412 7412 E malloc_debug: allocation[99] = 0x12 (expected 0xef) 223 04-15 12:00:31.305 7412 7412 E malloc_debug: Backtrace at time of free: 224 04-15 12:00:31.305 7412 7412 E malloc_debug: #00 pc 00029310 /system/lib/libc.so 225 04-15 12:00:31.305 7412 7412 E malloc_debug: #01 pc 00021438 /system/lib/libc.so (newlocale+160) 226 04-15 12:00:31.305 7412 7412 E malloc_debug: #02 pc 000a9e38 /system/lib/libc++.so 227 04-15 12:00:31.305 7412 7412 E malloc_debug: #03 pc 000a28a8 /system/lib/libc++.so 228 229In addition, there is another type of error message that can occur if 230an allocation has a special header applied, and the header is corrupted 231before the verification occurs. This is the error message that will be found 232in the log: 233 234 04-15 12:00:31.604 7412 7412 E malloc_debug: +++ ALLOCATION 0x12345678 HAS CORRUPTED HEADER TAG 0x1cc7dc00 AFTER FREE 235 236### free\_track\_backtrace\_num\_frames[=MAX\_FRAMES] 237This option only has meaning if free\_track is set. It indicates how many 238backtrace frames to capture when an allocation is freed. 239 240If MAX\_FRAMES is present, it indicates the number of frames to capture. 241If the value is set to zero, then no backtrace will be captured when the 242allocation is freed. The default is to record 16 frames, the max number of 243frames to to record is 256. 244 245### leak\_track 246Track all live allocations. When the program terminates, all of the live 247allocations will be dumped to the log. If the backtrace option was enabled, 248then the log will include the backtrace of the leaked allocations. This 249option is not useful when enabled globally because a lot of programs do not 250free everything before the program terminates. 251 252Before P, this option adds a special header to all allocations that contains 253the backtrace and information about the original allocation. After that, this 254option will not add a special header. 255 256Example leak error found in the log: 257 258 04-15 12:35:33.304 7412 7412 E malloc_debug: +++ APP leaked block of size 100 at 0x2be3b0b0 (leak 1 of 2) 259 04-15 12:35:33.304 7412 7412 E malloc_debug: Backtrace at time of allocation: 260 04-15 12:35:33.305 7412 7412 E malloc_debug: #00 pc 00029310 /system/lib/libc.so 261 04-15 12:35:33.305 7412 7412 E malloc_debug: #01 pc 00021438 /system/lib/libc.so (newlocale+160) 262 04-15 12:35:33.305 7412 7412 E malloc_debug: #02 pc 000a9e38 /system/lib/libc++.so 263 04-15 12:35:33.305 7412 7412 E malloc_debug: #03 pc 000a28a8 /system/lib/libc++.so 264 04-15 12:35:33.305 7412 7412 E malloc_debug: +++ APP leaked block of size 24 at 0x7be32380 (leak 2 of 2) 265 04-15 12:35:33.305 7412 7412 E malloc_debug: Backtrace at time of allocation: 266 04-15 12:35:33.305 7412 7412 E malloc_debug: #00 pc 00029310 /system/lib/libc.so 267 04-15 12:35:33.305 7412 7412 E malloc_debug: #01 pc 00021438 /system/lib/libc.so (newlocale+160) 268 04-15 12:35:33.305 7412 7412 E malloc_debug: #02 pc 000a9e38 /system/lib/libc++.so 269 04-15 12:35:33.305 7412 7412 E malloc_debug: #03 pc 000a28a8 /system/lib/libc++.so 270 271### record\_allocs[=TOTAL\_ENTRIES] 272Keep track of every allocation/free made on every thread and dump them 273to a file when the signal SIGRTMAX - 18 (which is 46 on most Android devices) 274is received. 275 276If TOTAL\_ENTRIES is set, then it indicates the total number of 277allocation/free records that can be retained. If the number of records 278reaches the TOTAL\_ENTRIES value, then any further allocations/frees are 279not recorded. The default value is 8,000,000 and the maximum value this 280can be set to is 50,000,000. 281 282Once the signal is received, and the current records are written to the 283file, all current records are deleted. Any allocations/frees occuring while 284the data is being dumped to the file are ignored. 285 286**NOTE**: This option is not available until the O release of Android. 287 288The allocation data is written in a human readable format. Every line begins 289with the THREAD\_ID returned by gettid(), which is the thread that is making 290the allocation/free. If a new thread is created, no special line is added 291to the file. However, when a thread completes, a special entry is added to 292the file indicating this. 293 294The thread complete line is: 295 296**THREAD\_ID**: thread\_done 0x0 297 298Example: 299 300 187: thread_done 0x0 301 302Below is how each type of allocation/free call ends up in the file dump. 303 304pointer = malloc(size) 305 306**THREAD\_ID**: malloc pointer size 307 308Example: 309 310 186: malloc 0xb6038060 20 311 312free(pointer) 313 314**THREAD\_ID**: free pointer 315 316Example: 317 318 186: free 0xb6038060 319 320pointer = calloc(nmemb, size) 321 322**THREAD\_ID**: calloc pointer nmemb size 323 324Example: 325 326 186: calloc 0xb609f080 32 4 327 328new\_pointer = realloc(old\_pointer, size) 329 330**THREAD\_ID**: realloc new\_pointer old\_pointer size 331 332Example: 333 334 186: realloc 0xb609f080 0xb603e9a0 12 335 336pointer = memalign(alignment, size) 337 338**THREAD\_ID**: memalign pointer alignment size 339 340pointer = aligned\_alloc(alignment, size) 341 342**THREAD\_ID**: memalign pointer alignment size 343 344posix\_memalign(&pointer, alignment, size) 345 346**THREAD\_ID**: memalign pointer alignment size 347 348Example: 349 350 186: memalign 0x85423660 16 104 351 352pointer = valloc(size) 353 354**THREAD\_ID**: memalign pointer 4096 size 355 356Example: 357 358 186: memalign 0x85423660 4096 112 359 360pointer = pvalloc(size) 361 362**THREAD\_ID**: memalign pointer 4096 <b>SIZE\_ROUNDED\_UP\_TO\_4096</b> 363 364Example: 365 366 186: memalign 0x85423660 4096 8192 367 368### record\_allocs\_file[=FILE\_NAME] 369This option only has meaning if record\_allocs is set. It indicates the 370file where the recorded allocations will be found. 371 372If FILE\_NAME is set, then it indicates where the record allocation data 373will be placed. 374 375**NOTE**: This option is not available until the O release of Android. 376 377### verify\_pointers 378Track all live allocations to determine if a pointer is used that does not 379exist. This option is a lightweight way to verify that all 380free/malloc\_usable\_size/realloc calls are passed valid pointers. 381 382Example error: 383 384 04-15 12:00:31.304 7412 7412 E malloc_debug: +++ ALLOCATION 0x12345678 UNKNOWN POINTER (free) 385 04-15 12:00:31.305 7412 7412 E malloc_debug: Backtrace at time of failure: 386 04-15 12:00:31.305 7412 7412 E malloc_debug: #00 pc 00029310 /system/lib/libc.so 387 04-15 12:00:31.305 7412 7412 E malloc_debug: #01 pc 00021438 /system/lib/libc.so (newlocale+160) 388 04-15 12:00:31.305 7412 7412 E malloc_debug: #02 pc 000a9e38 /system/lib/libc++.so 389 04-15 12:00:31.305 7412 7412 E malloc_debug: #03 pc 000a28a8 /system/lib/libc++.so 390 391Where the name of the function varies depending on the function that called 392with a bad pointer. Only three functions do this checking: free, 393malloc\_usable\_size, realloc. 394 395**NOTE**: This option is not available until the P release of Android. 396 397### abort\_on\_error 398When malloc debug detects an error, abort after sending the error 399log message. 400 401**NOTE**: If leak\_track is enabled, no abort occurs if leaks have been 402detected when the process is exiting. 403 404### verbose 405As of Android Q, all info messages will be turned off by default. For example, 406in Android P and older, enabling malloc debug would result in this message 407in the log: 408 409 08-16 15:54:16.060 26947 26947 I libc : /system/bin/app_process64: malloc debug enabled 410 411In android Q, this message will not be displayed because these info messages 412slow down process start up. However, if you want to re-enable these messages, 413add the verbose option. All of the "Run XXX" messages are also silenced unless 414the verbose option is specified. This is an example of the type 415of messages that are no longer displayed: 416 417 09-10 01:03:50.070 557 557 I malloc_debug: /system/bin/audioserver: Run: 'kill -47 557' to dump the backtrace. 418 419Additional Errors 420----------------- 421There are a few other error messages that might appear in the log. 422 423### Use After Free 424 04-15 12:00:31.304 7412 7412 E malloc_debug: +++ ALLOCATION 0x12345678 USED AFTER FREE (free) 425 04-15 12:00:31.305 7412 7412 E malloc_debug: Backtrace of original free: 426 04-15 12:00:31.305 7412 7412 E malloc_debug: #00 pc 00029310 /system/lib/libc.so 427 04-15 12:00:31.305 7412 7412 E malloc_debug: #01 pc 00021438 /system/lib/libc.so (newlocale+160) 428 04-15 12:00:31.305 7412 7412 E malloc_debug: #02 pc 000a9e38 /system/lib/libc++.so 429 04-15 12:00:31.305 7412 7412 E malloc_debug: #03 pc 000a28a8 /system/lib/libc++.so 430 04-15 12:00:31.305 7412 7412 E malloc_debug: Backtrace at time of failure: 431 04-15 12:00:31.305 7412 7412 E malloc_debug: #00 pc 00029310 /system/lib/libc.so 432 04-15 12:00:31.305 7412 7412 E malloc_debug: #01 pc 00021438 /system/lib/libc.so (newlocale+160) 433 04-15 12:00:31.305 7412 7412 E malloc_debug: #02 pc 000a9e38 /system/lib/libc++.so 434 04-15 12:00:31.305 7412 7412 E malloc_debug: #03 pc 000a28a8 /system/lib/libc++.so 435 436This indicates that code is attempting to free an already freed pointer. The 437name in parenthesis indicates that the application called the function 438*free* with the bad pointer. 439 440For example, this message: 441 442 04-15 12:00:31.304 7412 7412 E malloc_debug: +++ ALLOCATION 0x12345678 USED AFTER FREE (realloc) 443 444Would indicate that the application called the *realloc* function 445with an already freed pointer. 446 447### Invalid Tag 448 04-15 12:00:31.304 7412 7412 E malloc_debug: +++ ALLOCATION 0x12345678 HAS INVALID TAG 1ee7d000 (malloc_usable_size) 449 04-15 12:00:31.305 7412 7412 E malloc_debug: Backtrace at time of failure: 450 04-15 12:00:31.305 7412 7412 E malloc_debug: #00 pc 00029310 /system/lib/libc.so 451 04-15 12:00:31.305 7412 7412 E malloc_debug: #01 pc 00021438 /system/lib/libc.so (newlocale+160) 452 04-15 12:00:31.305 7412 7412 E malloc_debug: #02 pc 000a9e38 /system/lib/libc++.so 453 04-15 12:00:31.305 7412 7412 E malloc_debug: #03 pc 000a28a8 /system/lib/libc++.so 454 455This indicates that a function (malloc\_usable\_size) was called with 456a pointer that is either not allocated memory, or that the memory of 457the pointer has been corrupted. 458 459As with the other error message, the function in parenthesis is the 460function that was called with the bad pointer. 461 462Backtrace Heap Dump Format 463========================== 464 465This section describes the format of the backtrace heap dump. This data is 466generated by am dumpheap -n or, as of P, by the signal or on exit. 467 468The data has this header: 469 470 Android Native Heap Dump v1.0 471 472 Total memory: XXXX 473 Allocation records: YYYY 474 Backtrace size: ZZZZ 475 476Total memory is the total of all of the currently live allocations. 477Allocation records is the total number of allocation records. 478Backtrace size is the maximum number of backtrace frames that can be present. 479 480Following this header are two different sections, the first section is the 481allocation records, the second section is the map data. 482 483The allocation record data has this format: 484 485 z ZYGOTE_CHILD_ALLOC sz ALLOCATION_SIZE num NUM_ALLOCATIONS bt FRAMES 486 487ZYGOTE\_CHILD\_ALLOC is either 0 or 1. 0 means this was allocated by the 488zygote process or in a process not spawned from the zygote. 1 means this 489was allocated by an application after it forked off from the zygote process. 490 491ALLOCATION\_SIZE is the size of the allocation. 492NUM\_ALLOCATIONS is the number of allocations that have this size and have the 493same backtrace. 494FRAMES is a list of instruction pointers that represent the backtrace of the 495allocation. 496 497Example: 498 499 z 0 sz 400 num 1 bt 0000a230 0000b500 500 z 1 sz 500 num 3 bt 0000b000 0000c000 501 502The first allocation record was created by the zygote of size 400 only one 503with this backtrace/size and a backtrace of 0xa230, 0xb500. 504The second allocation record was create by an application spawned from the 505zygote of size 500, where there are three of these allocation with the same 506backtrace/size and a backtrace of 0xb000, 0xc000. 507 508The final section is the map data for the process: 509 510 MAPS 511 7fe9181000-7fe91a2000 rw-p 00000000 00:00 0 /system/lib/libc.so 512 . 513 . 514 . 515 END 516 517The map data is simply the output of /proc/PID/maps. This data can be used to 518decode the frames in the backtraces. 519 520There are now multiple versions of the file: 521 522Android P produces version v1.1 of the heap dump. 523 524 Android Native Heap Dump v1.1 525 526The only difference between v1.0 and v1.1 is that the NUM\_ALLOCATIONS 527value is always accurate in v1.1. A previous version of malloc debug set 528NUM\_ALLOCATIONS to an incorrect value. For heap dump v1.0, the 529NUM\_ALLOCATIONS value should be treated as always 1 no matter what is 530actually present. 531 532Android Q introduces v1.2 of the heap dump. The new header looks like this: 533 534 Android Native Heap Dump v1.2 535 536 Build fingerprint: 'google/taimen/taimen:8.1.0/OPM2.171026.006.C1/4769658:user/release-keys' 537 538The new line fingerprint line is the contents of the ro.build.fingerprint 539property. 540 541The new version no longer 0 pads the backtrace addresses. In v1.0/v1.1: 542 543 z 0 sz 400 num 1 bt 0000a230 0000b500 544 545While v1.2: 546 547 z 0 sz 400 num 1 bt a230 b500 548 549In addition, when the new option backtrace\_full is used, another line will 550be added to every backtrace line. The line will be: 551 552 bt_info {"MAP_NAME" RELATIVE_TO_MAP_PC "FUNCTION_NAME" FUNCTION_OFFSET} ... 553 554For each backtrace pc, there will be one element in braces. 555 556MAP\_NAME is the name of the map in which the backtrace pc exists. If there is 557no valid map name, this will be empty. 558RELATIVE\_TO\_MAP\_PC is the hexadecimal value of the relative pc to the map. 559FUNCTION\_NAME the name of the function for this pc. If there is no valid 560function name, then it will be empty. 561FUNCTION\_OFFSET the hexadecimal offset from the beginning of the function. If 562the FUNCTION\_NAME is empty, then this value will always be zero. 563 564An example of this new format: 565 566 z 0 sz 400 num 1 bt a2a0 b510 567 bt_info {"/system/libc.so" 2a0 "abort" 24} {"/system/libutils.so" 510 "" 0} 568 569In this example, the first backtrace frame has a pc of 0xa2a0 and is in the 570map named /system/libc.so which starts at 0xa000. The relative pc is 0x2a0, 571and it is in the function abort + 0x24. 572The second backtrace frame has a pc of 0xb510 and is in the map named 573/system/libutils.so which starts at 0xb000. The relative pc is 0x510 and 574it is in an unknown function. 575 576There is a tool to visualize this data, 577[native\_heapdump\_viewer.py](https://android.googlesource.com/platform/development/+/master/scripts/native_heapdump_viewer.py). 578 579Examples 580======== 581 582### For platform developers 583 584Enable backtrace tracking of all allocation for all processes: 585 586 adb shell stop 587 adb shell setprop libc.debug.malloc.options backtrace 588 adb shell start 589 590Enable backtrace tracking for a specific process (ls): 591 592 adb shell setprop libc.debug.malloc.options backtrace 593 adb shell setprop libc.debug.malloc.program ls 594 adb shell ls 595 596Enable backtrace tracking for the zygote and zygote based processes: 597 598 adb shell stop 599 adb shell setprop libc.debug.malloc.program app_process 600 adb shell setprop libc.debug.malloc.options backtrace 601 adb shell start 602 603Enable multiple options (backtrace and guard): 604 605 adb shell stop 606 adb shell setprop libc.debug.malloc.options "\"backtrace guard\"" 607 adb shell start 608 609Note: The two levels of quoting in the adb shell command is necessary. 610The outer layer of quoting is for the shell on the host, to ensure that the 611inner layer of quoting is sent to the device, to make 'backtrace guard' 612a single argument. 613 614Enable malloc debug using an environment variable (pre-O Android release): 615 616 adb shell 617 # setprop libc.debug.malloc.env_enabled 1 618 # setprop libc.debug.malloc.options backtrace 619 # export LIBC_DEBUG_MALLOC_ENABLE=1 620 # ls 621 622Enable malloc debug using an environment variable (Android O or later): 623 624 adb shell 625 # export LIBC_DEBUG_MALLOC_OPTIONS=backtrace 626 # ls 627 628Any process spawned from this shell will run with malloc debug enabled 629using the backtrace option. 630 631 adb shell stop 632 adb shell setprop libc.debug.malloc.options backtrace 633 adb shell start 634 adb shell am dumpheap -n <PID_TO_DUMP> /data/local/tmp/heap.txt 635 636It is possible to use the backtrace\_enable\_on\_signal option as well, 637but, obviously, it must be enabled through the signal before the file will 638contain any data. 639 640### For app developers 641 642App developers should check the NDK documentation about 643[wrap.sh](https://developer.android.com/ndk/guides/wrap-script.html) 644for the best way to use malloc debug in Android O or later on non-rooted 645devices. 646 647If you do have a rooted device, you can enable malloc debug for a specific 648program/application (Android O or later): 649 650 adb shell setprop wrap.<APP> '"LIBC_DEBUG_MALLOC_OPTIONS=backtrace logwrapper"' 651 652If you need to enable multiple options using this method, then you can set 653them like so: 654 655 adb shell setprop wrap.<APP> '"LIBC_DEBUG_MALLOC_OPTIONS=backtrace\ leak_track\ fill logwrapper"' 656 657For example, to enable malloc debug for the google search box (Android O or later): 658 659 adb shell setprop wrap.com.google.android.googlequicksearchbox '"LIBC_DEBUG_MALLOC_OPTIONS=backtrace logwrapper"' 660 adb shell am force-stop com.google.android.googlequicksearchbox 661 662If you are setting multiple options and the app does not appear to start 663properly, check the logcat looking for this message 664(`adb logcat -d | grep "malloc debug"`): 665 666 08-16 15:54:16.060 26947 26947 I libc : /system/bin/app_process64: malloc debug enabled 667 668If you do not see this message, then the wrap property was not set correctly. 669Run: 670 671 adb shell getprop | grep wrap 672 673And verify that any spaces are properly escaped. 674 675NOTE: On pre-O versions of the Android OS, property names had a length limit 676of 32. This meant that to create a wrap property with the name of the app, it 677was necessary to truncate the name to fit. On O, property names can be 678an order of magnitude larger, so there should be no need to truncate the name 679at all. 680 681To detect leaks while an app is running: 682 683 adb shell dumpsys meminfo --unreachable <PID_OF_APP> 684 685Without also enabling malloc debug, this command will only tell 686you whether it can detect leaked memory, not where those leaks are 687occurring. If you enable malloc debug with the backtrace option for your 688app before running the dumpsys command, you'll get backtraces showing 689where the memory was allocated. 690 691For backtraces from your app to be useful, you'll want to keep the 692symbols in your app's shared libraries rather than stripping them. That 693way you'll see the location of the leak directly without having to use 694something like the <code>ndk-stack</code> tool. 695 696### Analyzing heap dumps 697 698To analyze the data produced by the dumpheap command, run 699[development/scripts/native\_heapdump\_viewer.py](https://android.googlesource.com/platform/development/+/master/scripts/native_heapdump_viewer.py) 700 701In order for the script to properly symbolize the stacks in the file, 702make sure the script is executed from the tree that built the image. 703 704To collect, transfer, and analyze a dump: 705 706 adb shell am dumpheap -n <PID_TO_DUMP> /data/local/tmp/heap.txt 707 adb shell pull /data/local/tmp/heap.txt . 708 python development/scripts/native_heapdump_viewer.py --symbols /some/path/to/symbols/ heap.txt > heap_info.txt 709 710At the moment, the script will look for symbols in the given directory, 711using the path the .so file would have on the device. So if your .so file 712is at `/data/app/.../lib/arm/libx.so` on the device, it will need to be at 713`/some/path/to/symbols/data/app/.../lib/arm/libx.so` locally given the 714command line above. That is: you need to mirror the directory structure 715for the app in the symbols directory. 716