Loading libbacktrace/Backtrace.cpp +28 −17 Original line number Diff line number Diff line Loading @@ -142,7 +142,7 @@ Backtrace* Backtrace::Create(pid_t pid, pid_t tid, BacktraceMap* map) { } std::string Backtrace::GetErrorString(BacktraceUnwindError error) { switch (error) { switch (error.error_code) { case BACKTRACE_UNWIND_NO_ERROR: return "No error"; case BACKTRACE_UNWIND_ERROR_SETUP_FAILED: Loading @@ -159,5 +159,16 @@ std::string Backtrace::GetErrorString(BacktraceUnwindError error) { return "Attempt to use an unsupported feature"; case BACKTRACE_UNWIND_ERROR_NO_CONTEXT: return "Attempt to do an offline unwind without a context"; case BACKTRACE_UNWIND_ERROR_EXCEED_MAX_FRAMES_LIMIT: return "Exceed MAX_BACKTRACE_FRAMES limit"; case BACKTRACE_UNWIND_ERROR_ACCESS_MEM_FAILED: return android::base::StringPrintf("Failed to read memory at addr 0x%" PRIx64, error.error_info.addr); case BACKTRACE_UNWIND_ERROR_ACCESS_REG_FAILED: return android::base::StringPrintf("Failed to read register %" PRIu64, error.error_info.regno); case BACKTRACE_UNWIND_ERROR_FIND_PROC_INFO_FAILED: return "Failed to find a function in debug sections"; case BACKTRACE_UNWIND_ERROR_EXECUTE_DWARF_INSTRUCTION_FAILED: return "Failed to execute dwarf instructions in debug sections"; } } libbacktrace/BacktraceCurrent.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -67,11 +67,11 @@ size_t BacktraceCurrent::Read(uintptr_t addr, uint8_t* buffer, size_t bytes) { bool BacktraceCurrent::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) { if (GetMap() == nullptr) { // Without a map object, we can't do anything. error_ = BACKTRACE_UNWIND_ERROR_MAP_MISSING; error_.error_code = BACKTRACE_UNWIND_ERROR_MAP_MISSING; return false; } error_ = BACKTRACE_UNWIND_NO_ERROR; error_.error_code = BACKTRACE_UNWIND_NO_ERROR; if (ucontext) { return UnwindFromContext(num_ignore_frames, ucontext); } Loading Loading @@ -163,7 +163,7 @@ bool BacktraceCurrent::UnwindThread(size_t num_ignore_frames) { BACK_ASYNC_SAFE_LOGE("sigaction failed: %s", strerror(errno)); ThreadEntry::Remove(entry); pthread_mutex_unlock(&g_sigaction_mutex); error_ = BACKTRACE_UNWIND_ERROR_INTERNAL; error_.error_code = BACKTRACE_UNWIND_ERROR_INTERNAL; return false; } Loading @@ -171,9 +171,9 @@ bool BacktraceCurrent::UnwindThread(size_t num_ignore_frames) { // Do not emit an error message, this might be expected. Set the // error and let the caller decide. if (errno == ESRCH) { error_ = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST; error_.error_code = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST; } else { error_ = BACKTRACE_UNWIND_ERROR_INTERNAL; error_.error_code = BACKTRACE_UNWIND_ERROR_INTERNAL; } sigaction(THREAD_SIGNAL, &oldact, nullptr); Loading Loading @@ -218,9 +218,9 @@ bool BacktraceCurrent::UnwindThread(size_t num_ignore_frames) { } else { // Check to see if the thread has disappeared. if (tgkill(Pid(), Tid(), 0) == -1 && errno == ESRCH) { error_ = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST; error_.error_code = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST; } else { error_ = BACKTRACE_UNWIND_ERROR_THREAD_TIMEOUT; error_.error_code = BACKTRACE_UNWIND_ERROR_THREAD_TIMEOUT; BACK_ASYNC_SAFE_LOGE("Timed out waiting for signal handler to get ucontext data."); } } Loading libbacktrace/BacktraceOffline.cpp +30 −6 Original line number Diff line number Diff line Loading @@ -174,11 +174,11 @@ static unw_accessors_t accessors = { bool BacktraceOffline::Unwind(size_t num_ignore_frames, ucontext_t* context) { if (context == nullptr) { BACK_LOGW("The context is needed for offline backtracing."); error_ = BACKTRACE_UNWIND_ERROR_NO_CONTEXT; error_.error_code = BACKTRACE_UNWIND_ERROR_NO_CONTEXT; return false; } context_ = context; error_ = BACKTRACE_UNWIND_NO_ERROR; error_.error_code = BACKTRACE_UNWIND_NO_ERROR; unw_addr_space_t addr_space = unw_create_addr_space(&accessors, 0); unw_cursor_t cursor; Loading @@ -186,11 +186,11 @@ bool BacktraceOffline::Unwind(size_t num_ignore_frames, ucontext_t* context) { if (ret != 0) { BACK_LOGW("unw_init_remote failed %d", ret); unw_destroy_addr_space(addr_space); error_ = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; error_.error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; return false; } size_t num_frames = 0; do { while (true) { unw_word_t pc; ret = unw_get_reg(&cursor, UNW_REG_IP, &pc); if (ret < 0) { Loading Loading @@ -224,7 +224,17 @@ bool BacktraceOffline::Unwind(size_t num_ignore_frames, ucontext_t* context) { } is_debug_frame_used_ = false; ret = unw_step(&cursor); } while (ret > 0 && num_frames < MAX_BACKTRACE_FRAMES); if (ret <= 0) { if (error_.error_code == BACKTRACE_UNWIND_NO_ERROR) { error_.error_code = BACKTRACE_UNWIND_ERROR_EXECUTE_DWARF_INSTRUCTION_FAILED; } break; } if (num_frames == MAX_BACKTRACE_FRAMES) { error_.error_code = BACKTRACE_UNWIND_ERROR_EXCEED_MAX_FRAMES_LIMIT; break; } } unw_destroy_addr_space(addr_space); context_ = nullptr; Loading Loading @@ -259,21 +269,30 @@ size_t BacktraceOffline::Read(uintptr_t addr, uint8_t* buffer, size_t bytes) { return read_size; } read_size = stack_space_.Read(addr, buffer, bytes); if (read_size != 0) { return read_size; } error_.error_code = BACKTRACE_UNWIND_ERROR_ACCESS_MEM_FAILED; error_.error_info.addr = addr; return 0; } bool BacktraceOffline::FindProcInfo(unw_addr_space_t addr_space, uint64_t ip, unw_proc_info_t* proc_info, int need_unwind_info) { backtrace_map_t map; FillInMap(ip, &map); if (!BacktraceMap::IsValid(map)) { error_.error_code = BACKTRACE_UNWIND_ERROR_FIND_PROC_INFO_FAILED; return false; } const std::string& filename = map.name; DebugFrameInfo* debug_frame = GetDebugFrameInFile(filename); if (debug_frame == nullptr) { error_.error_code = BACKTRACE_UNWIND_ERROR_FIND_PROC_INFO_FAILED; return false; } // Each FindProcInfo() is a new attempt to unwind, so reset the reason. error_.error_code = BACKTRACE_UNWIND_NO_ERROR; eh_frame_hdr_space_.Clear(); eh_frame_space_.Clear(); Loading Loading @@ -367,6 +386,7 @@ bool BacktraceOffline::FindProcInfo(unw_addr_space_t addr_space, uint64_t ip, } } } error_.error_code = BACKTRACE_UNWIND_ERROR_FIND_PROC_INFO_FAILED; return false; } Loading Loading @@ -548,6 +568,10 @@ bool BacktraceOffline::ReadReg(size_t reg, uint64_t* value) { UNUSED(value); result = false; #endif if (!result) { error_.error_code = BACKTRACE_UNWIND_ERROR_ACCESS_REG_FAILED; error_.error_info.regno = reg; } return result; } Loading libbacktrace/BacktraceOffline.h +1 −3 Original line number Diff line number Diff line Loading @@ -32,9 +32,7 @@ struct Space { uint64_t end; const uint8_t* data; Space() { Clear(); } Space() { Clear(); } void Clear(); size_t Read(uint64_t addr, uint8_t* buffer, size_t size); Loading libbacktrace/UnwindCurrent.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -81,7 +81,7 @@ bool UnwindCurrent::UnwindFromContext(size_t num_ignore_frames, ucontext_t* ucon int ret = unw_getcontext(&context_); if (ret < 0) { BACK_LOGW("unw_getcontext failed %d", ret); error_ = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; error_.error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; return false; } } else { Loading @@ -93,7 +93,7 @@ bool UnwindCurrent::UnwindFromContext(size_t num_ignore_frames, ucontext_t* ucon int ret = unw_init_local(cursor.get(), &context_); if (ret < 0) { BACK_LOGW("unw_init_local failed %d", ret); error_ = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; error_.error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; return false; } initialized_ = true; Loading Loading
libbacktrace/Backtrace.cpp +28 −17 Original line number Diff line number Diff line Loading @@ -142,7 +142,7 @@ Backtrace* Backtrace::Create(pid_t pid, pid_t tid, BacktraceMap* map) { } std::string Backtrace::GetErrorString(BacktraceUnwindError error) { switch (error) { switch (error.error_code) { case BACKTRACE_UNWIND_NO_ERROR: return "No error"; case BACKTRACE_UNWIND_ERROR_SETUP_FAILED: Loading @@ -159,5 +159,16 @@ std::string Backtrace::GetErrorString(BacktraceUnwindError error) { return "Attempt to use an unsupported feature"; case BACKTRACE_UNWIND_ERROR_NO_CONTEXT: return "Attempt to do an offline unwind without a context"; case BACKTRACE_UNWIND_ERROR_EXCEED_MAX_FRAMES_LIMIT: return "Exceed MAX_BACKTRACE_FRAMES limit"; case BACKTRACE_UNWIND_ERROR_ACCESS_MEM_FAILED: return android::base::StringPrintf("Failed to read memory at addr 0x%" PRIx64, error.error_info.addr); case BACKTRACE_UNWIND_ERROR_ACCESS_REG_FAILED: return android::base::StringPrintf("Failed to read register %" PRIu64, error.error_info.regno); case BACKTRACE_UNWIND_ERROR_FIND_PROC_INFO_FAILED: return "Failed to find a function in debug sections"; case BACKTRACE_UNWIND_ERROR_EXECUTE_DWARF_INSTRUCTION_FAILED: return "Failed to execute dwarf instructions in debug sections"; } }
libbacktrace/BacktraceCurrent.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -67,11 +67,11 @@ size_t BacktraceCurrent::Read(uintptr_t addr, uint8_t* buffer, size_t bytes) { bool BacktraceCurrent::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) { if (GetMap() == nullptr) { // Without a map object, we can't do anything. error_ = BACKTRACE_UNWIND_ERROR_MAP_MISSING; error_.error_code = BACKTRACE_UNWIND_ERROR_MAP_MISSING; return false; } error_ = BACKTRACE_UNWIND_NO_ERROR; error_.error_code = BACKTRACE_UNWIND_NO_ERROR; if (ucontext) { return UnwindFromContext(num_ignore_frames, ucontext); } Loading Loading @@ -163,7 +163,7 @@ bool BacktraceCurrent::UnwindThread(size_t num_ignore_frames) { BACK_ASYNC_SAFE_LOGE("sigaction failed: %s", strerror(errno)); ThreadEntry::Remove(entry); pthread_mutex_unlock(&g_sigaction_mutex); error_ = BACKTRACE_UNWIND_ERROR_INTERNAL; error_.error_code = BACKTRACE_UNWIND_ERROR_INTERNAL; return false; } Loading @@ -171,9 +171,9 @@ bool BacktraceCurrent::UnwindThread(size_t num_ignore_frames) { // Do not emit an error message, this might be expected. Set the // error and let the caller decide. if (errno == ESRCH) { error_ = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST; error_.error_code = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST; } else { error_ = BACKTRACE_UNWIND_ERROR_INTERNAL; error_.error_code = BACKTRACE_UNWIND_ERROR_INTERNAL; } sigaction(THREAD_SIGNAL, &oldact, nullptr); Loading Loading @@ -218,9 +218,9 @@ bool BacktraceCurrent::UnwindThread(size_t num_ignore_frames) { } else { // Check to see if the thread has disappeared. if (tgkill(Pid(), Tid(), 0) == -1 && errno == ESRCH) { error_ = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST; error_.error_code = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST; } else { error_ = BACKTRACE_UNWIND_ERROR_THREAD_TIMEOUT; error_.error_code = BACKTRACE_UNWIND_ERROR_THREAD_TIMEOUT; BACK_ASYNC_SAFE_LOGE("Timed out waiting for signal handler to get ucontext data."); } } Loading
libbacktrace/BacktraceOffline.cpp +30 −6 Original line number Diff line number Diff line Loading @@ -174,11 +174,11 @@ static unw_accessors_t accessors = { bool BacktraceOffline::Unwind(size_t num_ignore_frames, ucontext_t* context) { if (context == nullptr) { BACK_LOGW("The context is needed for offline backtracing."); error_ = BACKTRACE_UNWIND_ERROR_NO_CONTEXT; error_.error_code = BACKTRACE_UNWIND_ERROR_NO_CONTEXT; return false; } context_ = context; error_ = BACKTRACE_UNWIND_NO_ERROR; error_.error_code = BACKTRACE_UNWIND_NO_ERROR; unw_addr_space_t addr_space = unw_create_addr_space(&accessors, 0); unw_cursor_t cursor; Loading @@ -186,11 +186,11 @@ bool BacktraceOffline::Unwind(size_t num_ignore_frames, ucontext_t* context) { if (ret != 0) { BACK_LOGW("unw_init_remote failed %d", ret); unw_destroy_addr_space(addr_space); error_ = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; error_.error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; return false; } size_t num_frames = 0; do { while (true) { unw_word_t pc; ret = unw_get_reg(&cursor, UNW_REG_IP, &pc); if (ret < 0) { Loading Loading @@ -224,7 +224,17 @@ bool BacktraceOffline::Unwind(size_t num_ignore_frames, ucontext_t* context) { } is_debug_frame_used_ = false; ret = unw_step(&cursor); } while (ret > 0 && num_frames < MAX_BACKTRACE_FRAMES); if (ret <= 0) { if (error_.error_code == BACKTRACE_UNWIND_NO_ERROR) { error_.error_code = BACKTRACE_UNWIND_ERROR_EXECUTE_DWARF_INSTRUCTION_FAILED; } break; } if (num_frames == MAX_BACKTRACE_FRAMES) { error_.error_code = BACKTRACE_UNWIND_ERROR_EXCEED_MAX_FRAMES_LIMIT; break; } } unw_destroy_addr_space(addr_space); context_ = nullptr; Loading Loading @@ -259,21 +269,30 @@ size_t BacktraceOffline::Read(uintptr_t addr, uint8_t* buffer, size_t bytes) { return read_size; } read_size = stack_space_.Read(addr, buffer, bytes); if (read_size != 0) { return read_size; } error_.error_code = BACKTRACE_UNWIND_ERROR_ACCESS_MEM_FAILED; error_.error_info.addr = addr; return 0; } bool BacktraceOffline::FindProcInfo(unw_addr_space_t addr_space, uint64_t ip, unw_proc_info_t* proc_info, int need_unwind_info) { backtrace_map_t map; FillInMap(ip, &map); if (!BacktraceMap::IsValid(map)) { error_.error_code = BACKTRACE_UNWIND_ERROR_FIND_PROC_INFO_FAILED; return false; } const std::string& filename = map.name; DebugFrameInfo* debug_frame = GetDebugFrameInFile(filename); if (debug_frame == nullptr) { error_.error_code = BACKTRACE_UNWIND_ERROR_FIND_PROC_INFO_FAILED; return false; } // Each FindProcInfo() is a new attempt to unwind, so reset the reason. error_.error_code = BACKTRACE_UNWIND_NO_ERROR; eh_frame_hdr_space_.Clear(); eh_frame_space_.Clear(); Loading Loading @@ -367,6 +386,7 @@ bool BacktraceOffline::FindProcInfo(unw_addr_space_t addr_space, uint64_t ip, } } } error_.error_code = BACKTRACE_UNWIND_ERROR_FIND_PROC_INFO_FAILED; return false; } Loading Loading @@ -548,6 +568,10 @@ bool BacktraceOffline::ReadReg(size_t reg, uint64_t* value) { UNUSED(value); result = false; #endif if (!result) { error_.error_code = BACKTRACE_UNWIND_ERROR_ACCESS_REG_FAILED; error_.error_info.regno = reg; } return result; } Loading
libbacktrace/BacktraceOffline.h +1 −3 Original line number Diff line number Diff line Loading @@ -32,9 +32,7 @@ struct Space { uint64_t end; const uint8_t* data; Space() { Clear(); } Space() { Clear(); } void Clear(); size_t Read(uint64_t addr, uint8_t* buffer, size_t size); Loading
libbacktrace/UnwindCurrent.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -81,7 +81,7 @@ bool UnwindCurrent::UnwindFromContext(size_t num_ignore_frames, ucontext_t* ucon int ret = unw_getcontext(&context_); if (ret < 0) { BACK_LOGW("unw_getcontext failed %d", ret); error_ = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; error_.error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; return false; } } else { Loading @@ -93,7 +93,7 @@ bool UnwindCurrent::UnwindFromContext(size_t num_ignore_frames, ucontext_t* ucon int ret = unw_init_local(cursor.get(), &context_); if (ret < 0) { BACK_LOGW("unw_init_local failed %d", ret); error_ = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; error_.error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; return false; } initialized_ = true; Loading