Revert "arm: Allow the first function to use linked register as return pc"
This reverts commit f2b3ab5e0a
.
Reason for revert: Causes symbolization errors on ARM ChromeOS
devices crbug.com/1182948.
Original change's description:
> arm: Allow the first function to use linked register as return pc
>
> For a crash at the function entry with corrupted PC, the caller's PC
> could be lying in the link register. Using the PC from link register
> would be more effective than blindly scanning the stack immediately.
>
> Change-Id: I51673b7298e70faeeab2bfa97075e3c4793f94bc
> Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2678992
> Reviewed-by: Mike Frysinger <vapier@chromium.org>
> Reviewed-by: Joshua Peraza <jperaza@chromium.org>
Bug: 1182948
Change-Id: I2818b35ab1fb99012919cccc0fb80368e456ca15
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2765164
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
parent
8b22babdf8
commit
dff7d5afd5
3 changed files with 1 additions and 33 deletions
|
@ -232,7 +232,7 @@ TEST_F(MicrodumpProcessorTest, TestProcessMultiple) {
|
||||||
ASSERT_EQ("arm", state.system_info()->cpu);
|
ASSERT_EQ("arm", state.system_info()->cpu);
|
||||||
ASSERT_EQ("lge/p1_tmo_us/p1:6.0/MRA58K/1603210524c8d:user/release-keys",
|
ASSERT_EQ("lge/p1_tmo_us/p1:6.0/MRA58K/1603210524c8d:user/release-keys",
|
||||||
state.system_info()->os_version);
|
state.system_info()->os_version);
|
||||||
ASSERT_EQ(6U, state.threads()->at(0)->frames()->size());
|
ASSERT_EQ(5U, state.threads()->at(0)->frames()->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MicrodumpProcessorTest, TestProcessMips) {
|
TEST_F(MicrodumpProcessorTest, TestProcessMips) {
|
||||||
|
|
|
@ -238,27 +238,6 @@ StackFrameARM* StackwalkerARM::GetCallerByFramePointer(
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
StackFrameARM* StackwalkerARM::GetCallerByLinkRegister(
|
|
||||||
const vector<StackFrame*>& frames) {
|
|
||||||
StackFrameARM* last_frame = static_cast<StackFrameARM*>(frames.back());
|
|
||||||
uint32_t last_lr = last_frame->context.iregs[MD_CONTEXT_ARM_REG_LR];
|
|
||||||
|
|
||||||
if (!(last_frame->context_validity & StackFrameARM::CONTEXT_VALID_LR) ||
|
|
||||||
!InstructionAddressSeemsValid(last_lr)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
StackFrameARM* frame = new StackFrameARM();
|
|
||||||
|
|
||||||
frame->trust = StackFrame::FRAME_TRUST_SCAN;
|
|
||||||
frame->context = last_frame->context;
|
|
||||||
frame->context.iregs[MD_CONTEXT_ARM_REG_PC] = last_lr;
|
|
||||||
frame->context_validity =
|
|
||||||
context_frame_validity_ & (~StackFrameARM::CONTEXT_VALID_LR);
|
|
||||||
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
StackFrame* StackwalkerARM::GetCallerFrame(const CallStack* stack,
|
StackFrame* StackwalkerARM::GetCallerFrame(const CallStack* stack,
|
||||||
bool stack_scan_allowed) {
|
bool stack_scan_allowed) {
|
||||||
if (!memory_ || !stack) {
|
if (!memory_ || !stack) {
|
||||||
|
@ -285,12 +264,6 @@ StackFrame* StackwalkerARM::GetCallerFrame(const CallStack* stack,
|
||||||
if (fp_register_ >= 0 && !frame.get())
|
if (fp_register_ >= 0 && !frame.get())
|
||||||
frame.reset(GetCallerByFramePointer(frames));
|
frame.reset(GetCallerByFramePointer(frames));
|
||||||
|
|
||||||
// For the first frame, return address may still be in the LR register at
|
|
||||||
// entry. Prefer to use LR register than scanning stack if LR register value
|
|
||||||
// points to a function range.
|
|
||||||
if (frames.size() == 1 && !frame.get())
|
|
||||||
frame.reset(GetCallerByLinkRegister(frames));
|
|
||||||
|
|
||||||
// If everuthing failed, fall back to stack scanning.
|
// If everuthing failed, fall back to stack scanning.
|
||||||
if (stack_scan_allowed && !frame.get())
|
if (stack_scan_allowed && !frame.get())
|
||||||
frame.reset(GetCallerByStackScan(frames));
|
frame.reset(GetCallerByStackScan(frames));
|
||||||
|
|
|
@ -82,11 +82,6 @@ class StackwalkerARM : public Stackwalker {
|
||||||
// Return NULL on failure.
|
// Return NULL on failure.
|
||||||
StackFrameARM* GetCallerByFramePointer(const vector<StackFrame*>& frames);
|
StackFrameARM* GetCallerByFramePointer(const vector<StackFrame*>& frames);
|
||||||
|
|
||||||
// Use the link register if it seems to be a valid function adderss.
|
|
||||||
// The caller takes ownership of the returned frame. Return NULL on failure.
|
|
||||||
// This is useful when PC register is corrupted.
|
|
||||||
StackFrameARM* GetCallerByLinkRegister(const vector<StackFrame*>& frames);
|
|
||||||
|
|
||||||
// Scan the stack for plausible return addresses. The caller takes ownership
|
// Scan the stack for plausible return addresses. The caller takes ownership
|
||||||
// of the returned frame. Return NULL on failure.
|
// of the returned frame. Return NULL on failure.
|
||||||
StackFrameARM* GetCallerByStackScan(const vector<StackFrame*>& frames);
|
StackFrameARM* GetCallerByStackScan(const vector<StackFrame*>& frames);
|
||||||
|
|
Loading…
Reference in a new issue