Create StackFrame::FRAME_TRUST_PREWALKED trust type.

This creates a new frame trust type for prewalked stack frames, as suggested in
the review of https://breakpad.appspot.com/620002/.

R=ted.mielczarek@gmail.com, mark@chromium.org

Review URL: https://breakpad.appspot.com/621002/



git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1208 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
chrisha@chromium.org 2013-08-23 19:41:36 +00:00
parent 1e57990cee
commit 16a880e135
3 changed files with 17 additions and 8 deletions

View File

@ -45,12 +45,13 @@ struct StackFrame {
// stack scanning, it can wind up with dubious frames. // stack scanning, it can wind up with dubious frames.
// In rough order of "trust metric". // In rough order of "trust metric".
enum FrameTrust { enum FrameTrust {
FRAME_TRUST_NONE, // Unknown FRAME_TRUST_NONE, // Unknown
FRAME_TRUST_SCAN, // Scanned the stack, found this FRAME_TRUST_SCAN, // Scanned the stack, found this
FRAME_TRUST_CFI_SCAN, // Scanned the stack using call frame info, found this FRAME_TRUST_CFI_SCAN, // Found while scanning stack using call frame info
FRAME_TRUST_FP, // Derived from frame pointer FRAME_TRUST_FP, // Derived from frame pointer
FRAME_TRUST_CFI, // Derived from call frame info FRAME_TRUST_CFI, // Derived from call frame info
FRAME_TRUST_CONTEXT // Given as instruction pointer in a context FRAME_TRUST_PREWALKED, // Explicitly provided by some external stack walker.
FRAME_TRUST_CONTEXT // Given as instruction pointer in a context
}; };
StackFrame() StackFrame()
@ -70,6 +71,8 @@ struct StackFrame {
switch (trust) { switch (trust) {
case StackFrame::FRAME_TRUST_CONTEXT: case StackFrame::FRAME_TRUST_CONTEXT:
return "given as instruction pointer in context"; return "given as instruction pointer in context";
case StackFrame::FRAME_TRUST_PREWALKED:
return "recovered by external stack walker";
case StackFrame::FRAME_TRUST_CFI: case StackFrame::FRAME_TRUST_CFI:
return "call frame info"; return "call frame info";
case StackFrame::FRAME_TRUST_CFI_SCAN: case StackFrame::FRAME_TRUST_CFI_SCAN:

View File

@ -85,7 +85,7 @@ StackFrame* StackwalkerAddressList::GetCallerFrame(const CallStack* stack,
// explicitly provided. // explicitly provided.
StackFrame* frame = new StackFrame(); StackFrame* frame = new StackFrame();
frame->instruction = frames_[frame_index]; frame->instruction = frames_[frame_index];
frame->trust = StackFrame::FRAME_TRUST_CONTEXT; frame->trust = StackFrame::FRAME_TRUST_PREWALKED;
return frame; return frame;
} }

View File

@ -106,8 +106,14 @@ class StackwalkerAddressListTest : public testing::Test {
void CheckCallStack(const CallStack& call_stack) { void CheckCallStack(const CallStack& call_stack) {
const std::vector<StackFrame*>* frames = call_stack.frames(); const std::vector<StackFrame*>* frames = call_stack.frames();
ASSERT_EQ(arraysize(kDummyFrames), frames->size()); ASSERT_EQ(arraysize(kDummyFrames), frames->size());
for (size_t i = 0; i < arraysize(kDummyFrames); ++i) for (size_t i = 0; i < arraysize(kDummyFrames); ++i) {
ASSERT_EQ(kDummyFrames[i], frames->at(i)->instruction); ASSERT_EQ(kDummyFrames[i], frames->at(i)->instruction);
if (i == 0) {
ASSERT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frames->at(i)->trust);
} else {
ASSERT_EQ(StackFrame::FRAME_TRUST_PREWALKED, frames->at(i)->trust);
}
}
ASSERT_EQ(static_cast<const CodeModule*>(&module2), frames->at(0)->module); ASSERT_EQ(static_cast<const CodeModule*>(&module2), frames->at(0)->module);
ASSERT_EQ(static_cast<const CodeModule*>(&module2), frames->at(1)->module); ASSERT_EQ(static_cast<const CodeModule*>(&module2), frames->at(1)->module);
ASSERT_EQ(static_cast<const CodeModule*>(&module2), frames->at(2)->module); ASSERT_EQ(static_cast<const CodeModule*>(&module2), frames->at(2)->module);