extern "C" bool malloc_debug_initialize(HashTable* hash_table, const MallocDebug* malloc_dispatch) {
  g_hash_table = hash_table;
  g_malloc_dispatch = malloc_dispatch;

  pthread_key_create(&g_debug_calls_disabled, NULL);

  char debug_backlog[PROP_VALUE_MAX];
  if (__system_property_get("libc.debug.malloc.backlog", debug_backlog)) {
    g_malloc_debug_backlog = atoi(debug_backlog);
    info_log("%s: setting backlog length to %d\n", getprogname(), g_malloc_debug_backlog);
  }

  // Check if backtracing should be disabled.
  char env[PROP_VALUE_MAX];
  if (__system_property_get("libc.debug.malloc.nobacktrace", env) && atoi(env) != 0) {
    g_backtrace_enabled = false;
    __libc_format_log(ANDROID_LOG_INFO, "libc", "not gathering backtrace information\n");
  }

  if (g_backtrace_enabled) {
    backtrace_startup();
  }

  return true;
}
bool debug_initialize(const MallocDispatch* malloc_dispatch, int* malloc_zygote_child) {
  if (malloc_zygote_child == nullptr) {
    return false;
  }

  InitAtfork();

  g_malloc_zygote_child = malloc_zygote_child;

  g_dispatch = malloc_dispatch;

  if (!DebugDisableInitialize()) {
    return false;
  }

  DebugData* debug = new DebugData();
  if (!debug->Initialize()) {
    delete debug;
    DebugDisableFinalize();
    return false;
  }
  g_debug = debug;

  // Always enable the backtrace code since we will use it in a number
  // of different error cases.
  backtrace_startup();

  return true;
}
extern "C" int malloc_debug_initialize() {
  backtrace_startup();
  return 0;
}
Example #4
0
static int traverseTree(MutexInfo* obj, MutexInfo const* objParent)
{
    /*
     * Have we been here before?
     */
    if (obj->historyMark) {
        int stackDepth;
        uintptr_t addrs[STACK_TRACE_DEPTH];

        /* Turn off prediction temporarily in this thread while logging */
        sPthreadDebugDisabledThread = gettid();

        backtrace_startup();

        LOGW("%s\n", kStartBanner);
        LOGW("pid: %d, tid: %d >>> %s <<<", getpid(), gettid(), __progname);
        LOGW("Illegal lock attempt:\n");
        LOGW("--- pthread_mutex_t at %p\n", obj->mutex);
        stackDepth = get_backtrace(addrs, STACK_TRACE_DEPTH);
        log_backtrace(addrs, stackDepth);

        LOGW("+++ Currently held locks in this thread (in reverse order):");
        MutexInfo* cur = obj;
        pid_t ourtid = gettid();
        int i;
        for (i=0 ; i<cur->parents.count ; i++) {
            MutexInfo* parent = cur->parents.list[i];
            if (parent->owner == ourtid) {
                LOGW("--- pthread_mutex_t at %p\n", parent->mutex);
                if (sPthreadDebugLevel >= CAPTURE_CALLSTACK) {
                    log_backtrace(parent->stackTrace, parent->stackDepth);
                }
                cur = parent;
                break;
            }
        }

        LOGW("+++ Earlier, the following lock order (from last to first) was established\n");
        return 0;
    }

    obj->historyMark = 1;

    MutexInfoList* pList = &obj->children;
    int result = 1;
    int i;
    for (i = pList->count-1; i >= 0; i--) {
        MutexInfo* child = pList->list[i];
        if (!traverseTree(child,  obj)) {
            LOGW("--- pthread_mutex_t at %p\n", obj->mutex);
            if (sPthreadDebugLevel >= CAPTURE_CALLSTACK) {
                int index = historyListHas(&obj->parents, objParent);
                if ((size_t)index < (size_t)obj->stacks.count) {
                    log_backtrace(obj->stacks.stack[index].addrs, obj->stacks.stack[index].depth);
                } else {
                    log_backtrace(obj->stackTrace, obj->stackDepth);
                }
            }
            result = 0;
            break;
        }
    }

    obj->historyMark = 0;
    return result;
}