Android malloc_debug介绍

2020-08-24  本文已影响0人  Little熊猫

一 简述

android 的libc中有malloc_debug的hook调用,我们可以使用malloc_debug中的hook函数对内存分配进行跟踪加测。
malloc_debug主要包含的功能如下:

  1. 内存分配和释放跟踪,支持的函数如下:
    malloc
    free
    calloc
    realloc
    posix_memalign
    memalign
    aligned_alloc
    malloc_usable_size

2) 支持内存边界,可以在申请的内存头部和尾部添加guard,内存越界检查,use after free,内存崩溃检查等。
3) 调用栈跟踪和打印,跟踪内存分配的同时保存内存分配的调用栈,方便内存泄漏检查。

二 malloc_debug使用

1) 开启malloc_debug
adb shell setprop libc.debug.malloc.program

  1. 设置相关检测项
    adb shell setprop libc.debug.malloc.options backtrace
    3)重启应用程序

三) malloc_debug原理

libc在初始化时会调用MallocInitImpl判断属性来加载debug so,调用InitMallocFunctions替换掉Libc原生的内存分配和释放函数。

// Initializes memory allocation framework once per process.
static void MallocInitImpl(libc_globals* globals) {
  char prop[PROP_VALUE_MAX];
  char* options = prop;

  MaybeInitGwpAsanFromLibc(globals);

  // Prefer malloc debug since it existed first and is a more complete
  // malloc interceptor than the hooks.
  bool hook_installed = false;
  if (CheckLoadMallocDebug(&options)) {
    hook_installed = InstallHooks(globals, options, kDebugPrefix, kDebugSharedLib);
  } else if (CheckLoadMallocHooks(&options)) {
    hook_installed = InstallHooks(globals, options, kHooksPrefix, kHooksSharedLib);
  }

  if (!hook_installed) {
    if (HeapprofdShouldLoad()) {
      HeapprofdInstallHooksAtInit(globals);
    }
  } else {
    // Record the fact that incompatible hooks are active, to skip any later
    // heapprofd signal handler invocations.
    HeapprofdRememberHookConflict();
  }
}

除了内存分配和释放,常见如下:

      "initialize",
      "finalize",
      "get_malloc_leak_info",
      "free_malloc_leak_info",
      "malloc_backtrace",
      "write_malloc_leak_info",

比如在完成注册后,调用FinishInstallHooks,initialize,将finalize注册到process退出时。

四 malloc_debug option选项

1) 内存边界检查
front_guard[=SIZE_BYTES]Enables a small buffer placed before the allocated data.
rear_guard[=SIZE_BYTES] Enables a small buffer placed after the allocated data.
guard[=SIZE_BYTES] Enables both a front guard and a rear guard on all allocations.
主要原理是在分配内存的头部和尾部添加一段数据,作为边界,头部初始化为0xaa,尾部初始化为0xbb。
2)调用栈功能
backtrace[=MAX_FRAMES]
backtrace_enable_on_signal[=MAX_FRAMES]
backtrace_dump_on_exit
backtrace_dump_prefix
backtrace_full
设置保存的调用栈个数,在信号量或者退出时打印调用栈
3) malloc内存默认值
fill_on_alloc[=MAX_FILLED_BYTES] size will be set to 0xeb.
fill_on_free[=MAX_FILLED_BYTES] When an allocation is freed, fill it with 0xef.
fill[=MAX_FILLED_BYTES] This enables both the fill_on_alloc option and the fill_on_free option.
expand_alloc[=EXPAND_BYTES] Add an extra amount to allocate for every allocation.

  1. 释放内存存档
    free_track[=ALLOCATION_COUNT] 默认值是100,最大值是16384
    free_track_backtrace_num_frames[=MAX_FRAMES]
    5)分配释放检测
    leak_track 在进程退出时,执行finalize函数,打印当前分配的内存
    record_allocs[=TOTAL_ENTRIES] 记录alloc操作,The default value is 8,000,000 and the maximum value this can be set to is 50,000,000.
    record_allocs_file[=FILE_NAME] 设置record_allocs保存地址
    verify_pointers free/malloc_usable_size/realloc 有效检查
    abort_on_error When malloc debug detects an error, abort after sending the error log message.内存泄漏检测不在此处,只在进程退出时检测
    6) verbose 开启debug info log,如果要看更多的信息,建议开启此选项

五 常见用法

1) 内存泄漏检测
在shell命令下执行 #setprop libc.debug.malloc.options "backtrace leak_track verbose"
这样开启后在进程退出时会打印leak信息,在发送kill -47时会打印当前内存申请
2) 内存崩溃检查
在shell命令中添加guard #setprop libc.debug.malloc.options "backtrace leak_track verbose guard"
这样会检测内存覆盖等检测
3) verify_pointers 开启可以检测use after free和double free等操作

上一篇下一篇

猜你喜欢

热点阅读