Index: syzygy/agent/common/stack_walker_x86_unittest.cc |
diff --git a/syzygy/agent/common/stack_walker_x86_unittest.cc b/syzygy/agent/common/stack_walker_x86_unittest.cc |
deleted file mode 100644 |
index ed099a71ab24b77a63be77e1f97808ff67b86fa3..0000000000000000000000000000000000000000 |
--- a/syzygy/agent/common/stack_walker_x86_unittest.cc |
+++ /dev/null |
@@ -1,271 +0,0 @@ |
-// Copyright 2015 Google Inc. All Rights Reserved. |
-// |
-// Licensed under the Apache License, Version 2.0 (the "License"); |
-// you may not use this file except in compliance with the License. |
-// You may obtain a copy of the License at |
-// |
-// http://www.apache.org/licenses/LICENSE-2.0 |
-// |
-// Unless required by applicable law or agreed to in writing, software |
-// distributed under the License is distributed on an "AS IS" BASIS, |
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-// See the License for the specific language governing permissions and |
-// limitations under the License. |
- |
-#include "syzygy/agent/common/stack_walker_x86.h" |
- |
-#include <windows.h> |
- |
-#include "gtest/gtest.h" |
-#include "syzygy/testing/metrics.h" |
- |
-namespace agent { |
-namespace common { |
- |
-namespace { |
- |
-class StackWalkerX86Test : public testing::Test { |
- public: |
- StackWalkerX86Test() |
- : dummy_ebp_(nullptr), dummy_esp_(nullptr), dummy_ret_(0u) { |
- ::memset(frames_, 0, sizeof(frames_)); |
- ::memset(frames2_, 0, sizeof(frames2_)); |
- ::memset(dummy_stack_, 0, sizeof(dummy_stack_)); |
- } |
- |
- static const uintptr_t kBaseRet = 0x1000000u; |
- |
- void Push(uintptr_t value) { |
- --dummy_esp_; |
- ASSERT_LE(dummy_stack_, dummy_esp_); |
- *dummy_esp_ = value; |
- } |
- |
- void PushEbp() { |
- Push(reinterpret_cast<uintptr_t>(dummy_ebp_)); |
- dummy_ebp_ = dummy_esp_; |
- } |
- |
- void PopEbp() { |
- dummy_ebp_ = reinterpret_cast<uintptr_t*>(*dummy_esp_); |
- ++dummy_esp_; |
- ASSERT_LE(dummy_esp_, dummy_stack_ + arraysize(dummy_stack_)); |
- } |
- |
- void PushRet() { |
- Push(dummy_ret_); |
- ++dummy_ret_; |
- } |
- |
- void ResetStack() { |
- ::memset(dummy_stack_, 0, sizeof(dummy_stack_)); |
- dummy_ebp_ = dummy_stack_ + arraysize(dummy_stack_); |
- dummy_esp_ = dummy_stack_ + arraysize(dummy_stack_); |
- dummy_ret_ = kBaseRet; |
- |
- // Push a return address, so that the very topmost thing on the |
- // stack is a return. |
- PushRet(); |
- } |
- |
- void SetUp() override { |
- ResetStack(); |
- } |
- |
- void BuildValidFrame(size_t locals) { |
- PushEbp(); |
- for (size_t i = 0; i < locals; ++i) |
- Push(::rand()); |
- PushRet(); |
- } |
- |
- void BuildInvalidFrameTooSmall() { |
- // Only push an EBP. This will be too close to the EBP of the next valid |
- // stack frame. |
- PushEbp(); |
- } |
- |
- void BuildInvalidFrameNonIncreasingBasePointer() { |
- Push(*dummy_ebp_ - 4 * sizeof(uintptr_t)); |
- dummy_ebp_ = dummy_esp_; |
- PushRet(); |
- } |
- |
- void BuildInvalidFrameUnalignedBasePointer() { |
- Push(*dummy_ebp_ - 1); |
- dummy_ebp_ = dummy_esp_; |
- PushRet(); |
- } |
- |
- void BuildInvalidFrameInvalidReturnAddress() { |
- PushEbp(); |
- Push(0); // Output a null return address. |
- ++dummy_ret_; |
- } |
- |
- void BuildInvalidFrameInvalidBasePointer() { |
- Push(reinterpret_cast<uintptr_t>(dummy_stack_ + arraysize(dummy_stack_))); |
- dummy_ebp_ = dummy_esp_; |
- PushRet(); |
- } |
- |
- void BuildInvalidFrameOverflowingBasePointer() { |
- // This base pointer will overflow to 0 when incremented. |
- Push(0xFFFFFFFC); |
- dummy_ebp_ = dummy_esp_; |
- PushRet(); |
- } |
- |
- void ExpectSuccessfulWalk(size_t num_frames, |
- size_t frames_to_skip) { |
- // Push a dummy EBP on the stack, which simulates the stack frame of the |
- // function actually calling WalkStack. |
- PushEbp(); |
- StackId stack_id; |
- EXPECT_EQ(num_frames, |
- WalkStackImpl(dummy_ebp_, dummy_esp_, |
- dummy_stack_ + arraysize(dummy_stack_), |
- frames_to_skip, kMaxFrames, frames_, &stack_id)); |
- for (size_t i = 0; i < num_frames; ++i) { |
- EXPECT_EQ(reinterpret_cast<void*>(dummy_ret_ - i - 1 - frames_to_skip), |
- frames_[i]); |
- } |
- |
- PopEbp(); |
- } |
- |
- static const size_t kMaxFrames = 100; |
- void* frames_[kMaxFrames]; |
- void* frames2_[kMaxFrames]; |
- |
- uintptr_t dummy_stack_[1024]; |
- uintptr_t* dummy_ebp_; |
- uintptr_t* dummy_esp_; |
- uintptr_t dummy_ret_; |
-}; |
- |
-} // namespace |
- |
-TEST_F(StackWalkerX86Test, ValidWalk) { |
- BuildValidFrame(0); |
- ExpectSuccessfulWalk(2, 0); |
- BuildValidFrame(2); |
- ExpectSuccessfulWalk(3, 0); |
- BuildValidFrame(1); |
- ExpectSuccessfulWalk(4, 0); |
- ExpectSuccessfulWalk(3, 1); |
- ExpectSuccessfulWalk(2, 2); |
-} |
- |
-TEST_F(StackWalkerX86Test, WalkStopsWhenFrameTooSmall) { |
- BuildValidFrame(0); |
- ExpectSuccessfulWalk(2, 0); |
- |
- BuildInvalidFrameTooSmall(); |
- BuildValidFrame(1); |
- ExpectSuccessfulWalk(1, 0); |
- |
- BuildValidFrame(2); |
- ExpectSuccessfulWalk(2, 0); |
- |
- BuildValidFrame(1); |
- ExpectSuccessfulWalk(3, 0); |
- ExpectSuccessfulWalk(2, 1); |
-} |
- |
-TEST_F(StackWalkerX86Test, WalkStopsAtNonIncreasingBasePointer) { |
- BuildValidFrame(0); |
- ExpectSuccessfulWalk(2, 0); |
- |
- BuildInvalidFrameNonIncreasingBasePointer(); |
- ExpectSuccessfulWalk(2, 0); |
- |
- BuildValidFrame(2); |
- ExpectSuccessfulWalk(3, 0); |
- |
- BuildValidFrame(1); |
- ExpectSuccessfulWalk(4, 0); |
- ExpectSuccessfulWalk(3, 1); |
-} |
- |
-TEST_F(StackWalkerX86Test, WalkStopsAtUnalignedBasePointer) { |
- BuildValidFrame(0); |
- ExpectSuccessfulWalk(2, 0); |
- |
- BuildInvalidFrameUnalignedBasePointer(); |
- ExpectSuccessfulWalk(2, 0); |
- |
- BuildValidFrame(2); |
- ExpectSuccessfulWalk(3, 0); |
- |
- BuildValidFrame(1); |
- ExpectSuccessfulWalk(4, 0); |
- ExpectSuccessfulWalk(3, 1); |
-} |
- |
-TEST_F(StackWalkerX86Test, WalkStopsAtInvalidReturnAddress) { |
- BuildValidFrame(0); |
- ExpectSuccessfulWalk(2, 0); |
- |
- BuildInvalidFrameInvalidReturnAddress(); |
- ExpectSuccessfulWalk(0, 0); |
- |
- BuildValidFrame(2); |
- ExpectSuccessfulWalk(1, 0); |
- |
- BuildValidFrame(1); |
- ExpectSuccessfulWalk(2, 0); |
-} |
- |
-TEST_F(StackWalkerX86Test, WalkStopsAtInvalidBasePointer) { |
- BuildValidFrame(0); |
- ExpectSuccessfulWalk(2, 0); |
- |
- BuildInvalidFrameInvalidBasePointer(); |
- ExpectSuccessfulWalk(2, 0); |
- |
- BuildValidFrame(2); |
- ExpectSuccessfulWalk(3, 0); |
- |
- BuildValidFrame(1); |
- ExpectSuccessfulWalk(4, 0); |
- ExpectSuccessfulWalk(3, 1); |
-} |
- |
-TEST_F(StackWalkerX86Test, WalkStopAtOverflowingBasePointer) { |
- BuildValidFrame(0); |
- ExpectSuccessfulWalk(2, 0); |
- |
- BuildInvalidFrameOverflowingBasePointer(); |
- ExpectSuccessfulWalk(2, 0); |
- |
- BuildValidFrame(2); |
- ExpectSuccessfulWalk(3, 0); |
- |
- BuildValidFrame(1); |
- ExpectSuccessfulWalk(4, 0); |
- ExpectSuccessfulWalk(3, 1); |
-} |
- |
-TEST_F(StackWalkerX86Test, CompareToCaptureStackBackTrace) { |
- // Use the OS stack walker to get the number of frames. Skip the top frame |
- // (in this function) as WalkStack and CaptureStackBackTrace won't have the |
- // same return address. |
- size_t num_frames = |
- ::CaptureStackBackTrace(1, kMaxFrames, frames_, nullptr); |
- |
- while (num_frames > 0) { |
- StackId stack_id; |
- size_t num_frames2 = WalkStack(1, num_frames, frames_, &stack_id); |
- size_t exp_frames2 = |
- ::CaptureStackBackTrace(1, num_frames, frames2_, nullptr); |
- EXPECT_EQ(num_frames, num_frames2); |
- EXPECT_EQ(exp_frames2, num_frames2); |
- EXPECT_EQ(0, ::memcmp(frames_, frames2_, num_frames * sizeof(*frames_))); |
- |
- --num_frames; |
- } |
-} |
- |
-} // namespace common |
-} // namespace agent |