Loading libbacktrace/Backtrace.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -170,5 +170,7 @@ std::string Backtrace::GetErrorString(BacktraceUnwindError error) { return "Failed to unwind due to invalid unwind information"; case BACKTRACE_UNWIND_ERROR_REPEATED_FRAME: return "Failed to unwind due to same sp/pc repeating"; case BACKTRACE_UNWIND_ERROR_INVALID_ELF: return "Failed to unwind due to invalid elf"; } } libbacktrace/UnwindStack.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,10 @@ bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, case unwindstack::ERROR_REPEATED_FRAME: error->error_code = BACKTRACE_UNWIND_ERROR_REPEATED_FRAME; break; case unwindstack::ERROR_INVALID_ELF: error->error_code = BACKTRACE_UNWIND_ERROR_INVALID_ELF; break; } } Loading libbacktrace/include/backtrace/Backtrace.h +2 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,8 @@ enum BacktraceUnwindErrorCode : uint32_t { BACKTRACE_UNWIND_ERROR_UNWIND_INFO, // Unwind information stopped due to sp/pc repeating. BACKTRACE_UNWIND_ERROR_REPEATED_FRAME, // Unwind information stopped due to invalid elf. BACKTRACE_UNWIND_ERROR_INVALID_ELF, }; struct BacktraceUnwindError { Loading libunwindstack/Elf.cpp +10 −9 Original line number Diff line number Diff line Loading @@ -160,7 +160,7 @@ ErrorCode Elf::GetLastErrorCode() { if (valid_) { return interface_->LastErrorCode(); } return ERROR_NONE; return ERROR_INVALID_ELF; } uint64_t Elf::GetLastErrorAddress() { Loading @@ -170,22 +170,23 @@ uint64_t Elf::GetLastErrorAddress() { return 0; } // The relative pc is always relative to the start of the map from which it comes. bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, Regs* regs, Memory* process_memory, bool* finished) { // The relative pc expectd by this function is relative to the start of the elf. bool Elf::StepIfSignalHandler(uint64_t rel_pc, Regs* regs, Memory* process_memory) { if (!valid_) { return false; } return regs->StepIfSignalHandler(rel_pc, this, process_memory); } // The relative pc expectd by StepIfSignalHandler is relative to the start of the elf. if (regs->StepIfSignalHandler(rel_pc, this, process_memory)) { *finished = false; return true; // The relative pc is always relative to the start of the map from which it comes. bool Elf::Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished) { if (!valid_) { return false; } // Lock during the step which can update information in the object. std::lock_guard<std::mutex> guard(lock_); return interface_->Step(adjusted_rel_pc, regs, process_memory, finished); return interface_->Step(rel_pc, regs, process_memory, finished); } bool Elf::IsValidElf(Memory* memory) { Loading libunwindstack/LocalUnwinder.cpp +11 −13 Original line number Diff line number Diff line Loading @@ -111,6 +111,14 @@ bool LocalUnwinder::Unwind(std::vector<LocalFrameData>* frame_info, size_t max_f pc_adjustment = 0; } step_pc -= pc_adjustment; bool finished = false; if (elf->StepIfSignalHandler(rel_pc, regs.get(), process_memory_.get())) { step_pc = rel_pc; } else if (!elf->Step(step_pc, regs.get(), process_memory_.get(), &finished)) { finished = true; } // Skip any locations that are within this library. if (num_frames != 0 || !ShouldSkipLibrary(map_info->name)) { // Add frame information. Loading @@ -124,22 +132,12 @@ bool LocalUnwinder::Unwind(std::vector<LocalFrameData>* frame_info, size_t max_f } num_frames++; } if (!elf->valid()) { break; } if (frame_info->size() == max_frames) { break; } adjust_pc = true; bool finished; if (!elf->Step(rel_pc, step_pc, regs.get(), process_memory_.get(), &finished) || finished) { break; } // pc and sp are the same, terminate the unwind. if (cur_pc == regs->pc() && cur_sp == regs->sp()) { if (finished || frame_info->size() == max_frames || (cur_pc == regs->pc() && cur_sp == regs->sp())) { break; } adjust_pc = true; } return num_frames != 0; } Loading Loading
libbacktrace/Backtrace.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -170,5 +170,7 @@ std::string Backtrace::GetErrorString(BacktraceUnwindError error) { return "Failed to unwind due to invalid unwind information"; case BACKTRACE_UNWIND_ERROR_REPEATED_FRAME: return "Failed to unwind due to same sp/pc repeating"; case BACKTRACE_UNWIND_ERROR_INVALID_ELF: return "Failed to unwind due to invalid elf"; } }
libbacktrace/UnwindStack.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,10 @@ bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, case unwindstack::ERROR_REPEATED_FRAME: error->error_code = BACKTRACE_UNWIND_ERROR_REPEATED_FRAME; break; case unwindstack::ERROR_INVALID_ELF: error->error_code = BACKTRACE_UNWIND_ERROR_INVALID_ELF; break; } } Loading
libbacktrace/include/backtrace/Backtrace.h +2 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,8 @@ enum BacktraceUnwindErrorCode : uint32_t { BACKTRACE_UNWIND_ERROR_UNWIND_INFO, // Unwind information stopped due to sp/pc repeating. BACKTRACE_UNWIND_ERROR_REPEATED_FRAME, // Unwind information stopped due to invalid elf. BACKTRACE_UNWIND_ERROR_INVALID_ELF, }; struct BacktraceUnwindError { Loading
libunwindstack/Elf.cpp +10 −9 Original line number Diff line number Diff line Loading @@ -160,7 +160,7 @@ ErrorCode Elf::GetLastErrorCode() { if (valid_) { return interface_->LastErrorCode(); } return ERROR_NONE; return ERROR_INVALID_ELF; } uint64_t Elf::GetLastErrorAddress() { Loading @@ -170,22 +170,23 @@ uint64_t Elf::GetLastErrorAddress() { return 0; } // The relative pc is always relative to the start of the map from which it comes. bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, Regs* regs, Memory* process_memory, bool* finished) { // The relative pc expectd by this function is relative to the start of the elf. bool Elf::StepIfSignalHandler(uint64_t rel_pc, Regs* regs, Memory* process_memory) { if (!valid_) { return false; } return regs->StepIfSignalHandler(rel_pc, this, process_memory); } // The relative pc expectd by StepIfSignalHandler is relative to the start of the elf. if (regs->StepIfSignalHandler(rel_pc, this, process_memory)) { *finished = false; return true; // The relative pc is always relative to the start of the map from which it comes. bool Elf::Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished) { if (!valid_) { return false; } // Lock during the step which can update information in the object. std::lock_guard<std::mutex> guard(lock_); return interface_->Step(adjusted_rel_pc, regs, process_memory, finished); return interface_->Step(rel_pc, regs, process_memory, finished); } bool Elf::IsValidElf(Memory* memory) { Loading
libunwindstack/LocalUnwinder.cpp +11 −13 Original line number Diff line number Diff line Loading @@ -111,6 +111,14 @@ bool LocalUnwinder::Unwind(std::vector<LocalFrameData>* frame_info, size_t max_f pc_adjustment = 0; } step_pc -= pc_adjustment; bool finished = false; if (elf->StepIfSignalHandler(rel_pc, regs.get(), process_memory_.get())) { step_pc = rel_pc; } else if (!elf->Step(step_pc, regs.get(), process_memory_.get(), &finished)) { finished = true; } // Skip any locations that are within this library. if (num_frames != 0 || !ShouldSkipLibrary(map_info->name)) { // Add frame information. Loading @@ -124,22 +132,12 @@ bool LocalUnwinder::Unwind(std::vector<LocalFrameData>* frame_info, size_t max_f } num_frames++; } if (!elf->valid()) { break; } if (frame_info->size() == max_frames) { break; } adjust_pc = true; bool finished; if (!elf->Step(rel_pc, step_pc, regs.get(), process_memory_.get(), &finished) || finished) { break; } // pc and sp are the same, terminate the unwind. if (cur_pc == regs->pc() && cur_sp == regs->sp()) { if (finished || frame_info->size() == max_frames || (cur_pc == regs->pc() && cur_sp == regs->sp())) { break; } adjust_pc = true; } return num_frames != 0; } Loading