diff options
author | Christopher Ferris <cferris@google.com> | 2019-04-11 19:45:35 -0700 |
---|---|---|
committer | Christopher Ferris <cferris@google.com> | 2019-04-12 17:23:18 -0700 |
commit | 6020e865dac13a3c4462fddef4a540d0e0d78ed0 (patch) | |
tree | 2d9d5c10858057c41f62c7f5c062fb9d532c1c0f /libunwindstack/LocalUnwinder.cpp | |
parent | cb88d8cbfe592d966cf1160639fa9b84402f4c29 (diff) | |
download | unwinding-6020e865dac13a3c4462fddef4a540d0e0d78ed0.tar.gz |
Fix pc/function name for signal handler frame.
This refactors the step function slightly to split it up into
distinct pieces since the code needs to handle a signal handler
versus normal step slightly differently.
Add a new error for an invalid elf.
Modify libbacktrace code to handle new error code.
Bug: 130302288
Test: libbacktrace/libunwindstack unit tests.
Change-Id: I3fb9b00c02d2cf2cc5911541bba0346c6f39b8e6
Diffstat (limited to 'libunwindstack/LocalUnwinder.cpp')
-rw-r--r-- | libunwindstack/LocalUnwinder.cpp | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/libunwindstack/LocalUnwinder.cpp b/libunwindstack/LocalUnwinder.cpp index 5b2fadf..5d81200 100644 --- a/libunwindstack/LocalUnwinder.cpp +++ b/libunwindstack/LocalUnwinder.cpp @@ -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. @@ -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; } |