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