static void dump_thread(log_t* log, pid_t tid, bool attached, bool* detach_failed, int* total_sleep_time_usec) { char path[PATH_MAX]; char threadnamebuf[1024]; char* threadname = NULL; FILE* fp; snprintf(path, sizeof(path), "/proc/%d/comm", tid); if ((fp = fopen(path, "r"))) { threadname = fgets(threadnamebuf, sizeof(threadnamebuf), fp); fclose(fp); if (threadname) { size_t len = strlen(threadname); if (len && threadname[len - 1] == '\n') { threadname[len - 1] = '\0'; } } } _LOG(log, SCOPE_AT_FAULT, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid); if (!attached && ptrace(PTRACE_ATTACH, tid, 0, 0) < 0) { _LOG(log, SCOPE_AT_FAULT, "Could not attach to thread: %s\n", strerror(errno)); return; } wait_for_stop(tid, total_sleep_time_usec); backtrace_context_t context; if (!backtrace_create_context(&context, tid, -1, 0)) { _LOG(log, SCOPE_AT_FAULT, "Could not create backtrace context.\n"); } else { dump_backtrace_to_log(&context, log, SCOPE_AT_FAULT, " "); backtrace_destroy_context(&context); } if (!attached && ptrace(PTRACE_DETACH, tid, 0, 0) != 0) { LOG("ptrace detach from %d failed: %s\n", tid, strerror(errno)); *detach_failed = true; } }
static void dump_thread( log_t* log, pid_t tid, bool attached, bool* detach_failed, int* total_sleep_time_usec) { char path[PATH_MAX]; char threadnamebuf[1024]; char* threadname = NULL; FILE* fp; snprintf(path, sizeof(path), "/proc/%d/comm", tid); if ((fp = fopen(path, "r"))) { threadname = fgets(threadnamebuf, sizeof(threadnamebuf), fp); fclose(fp); if (threadname) { size_t len = strlen(threadname); if (len && threadname[len - 1] == '\n') { threadname[len - 1] = '\0'; } } } _LOG(log, logtype::BACKTRACE, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid); if (!attached && ptrace(PTRACE_ATTACH, tid, 0, 0) < 0) { _LOG(log, logtype::BACKTRACE, "Could not attach to thread: %s\n", strerror(errno)); return; } if (!attached && wait_for_sigstop(tid, total_sleep_time_usec, detach_failed) == -1) { return; } std::unique_ptr<Backtrace> backtrace(Backtrace::Create(tid, BACKTRACE_CURRENT_THREAD)); if (backtrace->Unwind(0)) { dump_backtrace_to_log(backtrace.get(), log, " "); } else { ALOGE("Unwind failed: tid = %d", tid); } if (!attached && ptrace(PTRACE_DETACH, tid, 0, 0) != 0) { ALOGE("ptrace detach from %d failed: %s\n", tid, strerror(errno)); *detach_failed = true; } }