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; }
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; }