summaryrefslogtreecommitdiff
path: root/libunwindstack/LocalUnwinder.cpp
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2019-04-11 19:45:35 -0700
committerChristopher Ferris <cferris@google.com>2019-04-12 17:23:18 -0700
commit6020e865dac13a3c4462fddef4a540d0e0d78ed0 (patch)
tree2d9d5c10858057c41f62c7f5c062fb9d532c1c0f /libunwindstack/LocalUnwinder.cpp
parentcb88d8cbfe592d966cf1160639fa9b84402f4c29 (diff)
downloadunwinding-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.cpp24
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;
}