1a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// Copyright (c) 2010, Google Inc. 2a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// All rights reserved. 3a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// 4a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// Redistribution and use in source and binary forms, with or without 5a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// modification, are permitted provided that the following conditions are 6a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// met: 7a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// 8a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// * Redistributions of source code must retain the above copyright 9a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// notice, this list of conditions and the following disclaimer. 10a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// * Redistributions in binary form must reproduce the above 11a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// copyright notice, this list of conditions and the following disclaimer 12a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// in the documentation and/or other materials provided with the 13a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// distribution. 14a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// * Neither the name of Google Inc. nor the names of its 15a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// contributors may be used to endorse or promote products derived from 16a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// this software without specific prior written permission. 17a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// 18a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 30a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> 31a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 32a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// stackwalker_x86_unittest.cc: Unit tests for StackwalkerX86 class. 33a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 34a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy#include <string> 35a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy#include <vector> 36a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 37a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy#include "breakpad_googletest_includes.h" 38865df5af57922a4dc1e2a24e3f5c371d84f0f574jimblandy#include "common/test_assembler.h" 394e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com#include "common/using_std_string.h" 40a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy#include "google_breakpad/common/minidump_format.h" 41a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy#include "google_breakpad/processor/basic_source_line_resolver.h" 42a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy#include "google_breakpad/processor/call_stack.h" 435a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com#include "google_breakpad/processor/code_module.h" 44a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy#include "google_breakpad/processor/source_line_resolver_interface.h" 45a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy#include "google_breakpad/processor/stack_frame_cpu.h" 46a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy#include "processor/stackwalker_unittest_utils.h" 47a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy#include "processor/stackwalker_x86.h" 48a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy#include "processor/windows_frame_info.h" 49a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 50a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyusing google_breakpad::BasicSourceLineResolver; 51a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyusing google_breakpad::CallStack; 525a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.comusing google_breakpad::CodeModule; 539753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.comusing google_breakpad::StackFrameSymbolizer; 54a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyusing google_breakpad::StackFrame; 55a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyusing google_breakpad::StackFrameX86; 5642b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.comusing google_breakpad::Stackwalker; 57a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyusing google_breakpad::StackwalkerX86; 58a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyusing google_breakpad::SystemInfo; 59a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyusing google_breakpad::WindowsFrameInfo; 606f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarekusing google_breakpad::test_assembler::kLittleEndian; 616f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarekusing google_breakpad::test_assembler::Label; 626f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarekusing google_breakpad::test_assembler::Section; 63a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyusing std::vector; 64a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyusing testing::_; 6584946cd973502ae101821c9d17d16ce1572dda00ted.mielczarek@gmail.comusing testing::AnyNumber; 66a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyusing testing::Return; 67a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyusing testing::SetArgumentPointee; 68a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyusing testing::Test; 69a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 70a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyclass StackwalkerX86Fixture { 71a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy public: 72a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy StackwalkerX86Fixture() 73a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy : stack_section(kLittleEndian), 74a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // Give the two modules reasonable standard locations and names 75a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // for tests to play with. 76a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy module1(0x40000000, 0x10000, "module1", "version1"), 772660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com module2(0x50000000, 0x10000, "module2", "version2"), 782660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com module3(0x771d0000, 0x180000, "module3", "version3"), 792660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com module4(0x75f90000, 0x46000, "module4", "version4"), 802660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com module5(0x75730000, 0x110000, "module5", "version5"), 812660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com module6(0x647f0000, 0x1ba8000, "module6", "version6") { 82a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // Identify the system as a Linux system. 83a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy system_info.os = "Linux"; 84a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy system_info.os_short = "linux"; 85a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy system_info.os_version = "Salacious Skink"; 86a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy system_info.cpu = "x86"; 87a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy system_info.cpu_info = ""; 88a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 89a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // Put distinctive values in the raw CPU context. 90a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy BrandContext(&raw_context); 91a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 92a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // Create some modules with some stock debugging information. 93a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy modules.Add(&module1); 94a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy modules.Add(&module2); 952660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com modules.Add(&module3); 962660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com modules.Add(&module4); 972660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com modules.Add(&module5); 982660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com modules.Add(&module6); 99a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 100a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // By default, none of the modules have symbol info; call 101a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // SetModuleSymbols to override this. 1022d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _)) 103a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND)); 10484946cd973502ae101821c9d17d16ce1572dda00ted.mielczarek@gmail.com 10584946cd973502ae101821c9d17d16ce1572dda00ted.mielczarek@gmail.com // Avoid GMOCK WARNING "Uninteresting mock function call - returning 10684946cd973502ae101821c9d17d16ce1572dda00ted.mielczarek@gmail.com // directly" for FreeSymbolData(). 10784946cd973502ae101821c9d17d16ce1572dda00ted.mielczarek@gmail.com EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); 10842b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com 10942b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com // Reset max_frames_scanned since it's static. 11042b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com Stackwalker::set_max_frames_scanned(1024); 111a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy } 112a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 113a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // Set the Breakpad symbol information that supplier should return for 114a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // MODULE to INFO. 115a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy void SetModuleSymbols(MockCodeModule *module, const string &info) { 1162d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com size_t buffer_size; 1172d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size); 1182d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _)) 1195b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer), 1202d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com SetArgumentPointee<4>(buffer_size), 121a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy Return(MockSymbolSupplier::FOUND))); 122a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy } 123a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 124a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // Populate stack_region with the contents of stack_section. Use 125a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // stack_section.start() as the region's starting address. 126a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy void RegionFromSection() { 127a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy string contents; 128a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy ASSERT_TRUE(stack_section.GetContents(&contents)); 129a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_region.Init(stack_section.start().Value(), contents); 130a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy } 131a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 132a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking. 133a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy void BrandContext(MDRawContextX86 *raw_context) { 1346162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t x = 173; 135a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy for (size_t i = 0; i < sizeof(*raw_context); i++) 1366162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com reinterpret_cast<uint8_t *>(raw_context)[i] = (x += 17); 137a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy } 1387a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com 139a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy SystemInfo system_info; 140a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy MDRawContextX86 raw_context; 141a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy Section stack_section; 142a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy MockMemoryRegion stack_region; 143a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy MockCodeModule module1; 144a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy MockCodeModule module2; 1452660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com MockCodeModule module3; 1462660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com MockCodeModule module4; 1472660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com MockCodeModule module5; 1482660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com MockCodeModule module6; 149a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy MockCodeModules modules; 150a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy MockSymbolSupplier supplier; 151a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy BasicSourceLineResolver resolver; 152a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy CallStack call_stack; 153a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy const vector<StackFrame *> *frames; 154a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy}; 155a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 156281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarekclass SanityCheck: public StackwalkerX86Fixture, public Test { }; 157281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek 158281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarekTEST_F(SanityCheck, NoResolver) { 159281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek stack_section.start() = 0x80000000; 1607a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com stack_section.D32(0).D32(0); // end-of-stack marker 161281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek RegionFromSection(); 162281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek raw_context.eip = 0x40000200; 163281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek raw_context.ebp = 0x80000000; 164281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek 1659753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com StackFrameSymbolizer frame_symbolizer(NULL, NULL); 166281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 1679753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com &frame_symbolizer); 168281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek // This should succeed, even without a resolver or supplier. 1695a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 1702d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 1712d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 1722d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 1735a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(1U, modules_without_symbols.size()); 1745a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 1752d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 176281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek frames = call_stack.frames(); 177281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0)); 178281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek // Check that the values from the original raw context made it 179281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek // through to the context in the stack frame. 180281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); 181281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek} 182281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek 183a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyclass GetContextFrame: public StackwalkerX86Fixture, public Test { }; 184a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 185a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyTEST_F(GetContextFrame, Simple) { 186a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section.start() = 0x80000000; 1877a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com stack_section.D32(0).D32(0); // end-of-stack marker 188a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy RegionFromSection(); 189a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.eip = 0x40000200; 190a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.ebp = 0x80000000; 191a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 1929753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 193a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 1949753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com &frame_symbolizer); 1955a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 1962d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 1972d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 1982d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 1995a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(1U, modules_without_symbols.size()); 2005a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 2012d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 202e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com frames = call_stack.frames(); 203e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0)); 204e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com // Check that the values from the original raw context made it 205e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com // through to the context in the stack frame. 206e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); 207e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com} 208e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com 209e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com// The stackwalker should be able to produce the context frame even 210e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com// without stack memory present. 211e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.comTEST_F(GetContextFrame, NoStackMemory) { 212e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com raw_context.eip = 0x40000200; 213e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com raw_context.ebp = 0x80000000; 214e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com 215e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 216e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com StackwalkerX86 walker(&system_info, &raw_context, NULL, &modules, 217e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com &frame_symbolizer); 2185a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 2192d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 2202d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 2212d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 2225a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(1U, modules_without_symbols.size()); 2235a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 2242d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 225a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy frames = call_stack.frames(); 226a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0)); 227a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // Check that the values from the original raw context made it 228a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // through to the context in the stack frame. 229281d52d944d63ddfbe933a7bbe8adbfba3523966ted.mielczarek EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); 230a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy} 231a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 2322d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.comclass GetCallerFrame: public StackwalkerX86Fixture, public Test { 2332d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com protected: 2342d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com void IPAddressIsNotInKnownModuleTestImpl(bool has_corrupt_symbols); 2352d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com}; 236a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 237a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// Walk a traditional frame. A traditional frame saves the caller's 238a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// %ebp just below the return address, and has its own %ebp pointing 239a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// at the saved %ebp. 240a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyTEST_F(GetCallerFrame, Traditional) { 241a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section.start() = 0x80000000; 242a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy Label frame0_ebp, frame1_ebp; 243a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section 244a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Append(12, 0) // frame 0: space 245a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame0_ebp) // frame 0 %ebp points here 246a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(frame1_ebp) // frame 0: saved %ebp 247a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x40008679) // frame 0: return address 248a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Append(8, 0) // frame 1: space 249a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame1_ebp) // frame 1 %ebp points here 250a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0) // frame 1: saved %ebp (stack end) 251a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0); // frame 1: return address (stack end) 252a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy RegionFromSection(); 253a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.eip = 0x4000c7a5; 254a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.esp = stack_section.start().Value(); 255a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.ebp = frame0_ebp.Value(); 256a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 2579753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 258a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 2599753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com &frame_symbolizer); 2605a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 2612d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 2622d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 2632d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 2645a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(1U, modules_without_symbols.size()); 2655a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 2662d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 267a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy frames = call_stack.frames(); 268a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy ASSERT_EQ(2U, frames->size()); 269a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 2702660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 2712660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 2722660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 2732660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 2742660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000c7a5U, frame0->instruction); 2752660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000c7a5U, frame0->context.eip); 2762660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp); 2772660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(NULL, frame0->windows_frame_info); 2782660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 2792660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 2802660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 2812660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1)); 2822660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust); 2832660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP 2842660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_ESP 2852660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EBP), 2862660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->context_validity); 2872660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40008679U, frame1->instruction + 1); 2882660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40008679U, frame1->context.eip); 2892660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); 2902660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(NULL, frame1->windows_frame_info); 2912660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 292a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy} 293a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 294a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// Walk a traditional frame, but use a bogus %ebp value, forcing a scan 295a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// of the stack for something that looks like a return address. 296a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyTEST_F(GetCallerFrame, TraditionalScan) { 297a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section.start() = 0x80000000; 298a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy Label frame1_ebp; 2997a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com Label frame1_esp; 300a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section 301a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 0 302a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0xf065dc76) // locals area: 303a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x46ee2167) // garbage that doesn't look like 304a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0xbab023ec) // a return address 305a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(frame1_ebp) // saved %ebp (%ebp fails to point here, forcing scan) 306a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x4000129d) // return address 307a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 1 3087a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame1_esp) 309a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Append(8, 0) // space 310a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame1_ebp) // %ebp points here 311a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0) // saved %ebp (stack end) 312a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0); // return address (stack end) 313a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 314a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy RegionFromSection(); 315a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.eip = 0x4000f49d; 316a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.esp = stack_section.start().Value(); 317a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // Make the frame pointer bogus, to make the stackwalker scan the stack 318a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // for something that looks like a return address. 319a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.ebp = 0xd43eed6e; 320a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 3219753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 322a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 3239753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com &frame_symbolizer); 3245a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 3252d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 3262d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 3272d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 3285a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(1U, modules_without_symbols.size()); 3295a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 3302d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 331a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy frames = call_stack.frames(); 332a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy ASSERT_EQ(2U, frames->size()); 333a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 3342660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 3352660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 3362660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 3372660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 3382660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000f49dU, frame0->instruction); 3392660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000f49dU, frame0->context.eip); 3402660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); 3412660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0xd43eed6eU, frame0->context.ebp); 3422660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(NULL, frame0->windows_frame_info); 3432660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 3442660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 3452660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 3462660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1)); 3472660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); 3482660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP 3492660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_ESP 3502660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EBP), 3512660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->context_validity); 3522660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000129dU, frame1->instruction + 1); 3532660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000129dU, frame1->context.eip); 3547a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); 3557a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); 3562660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(NULL, frame1->windows_frame_info); 3572660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 358a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy} 359a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 3609c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek// Force scanning for a return address a long way down the stack 3619c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarekTEST_F(GetCallerFrame, TraditionalScanLongWay) { 3629c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek stack_section.start() = 0x80000000; 3639c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek Label frame1_ebp; 3647a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com Label frame1_esp; 3659c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek stack_section 3669c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek // frame 0 3679c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek .D32(0xf065dc76) // locals area: 3689c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek .D32(0x46ee2167) // garbage that doesn't look like 3699c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek .D32(0xbab023ec) // a return address 3709c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek .Append(20 * 4, 0) // a bunch of space 3719c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek .D32(frame1_ebp) // saved %ebp (%ebp fails to point here, forcing scan) 3729c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek .D32(0x4000129d) // return address 3739c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek // frame 1 3747a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame1_esp) 3759c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek .Append(8, 0) // space 3769c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek .Mark(&frame1_ebp) // %ebp points here 3779c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek .D32(0) // saved %ebp (stack end) 3789c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek .D32(0); // return address (stack end) 3799c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek 3809c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek RegionFromSection(); 3819c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek raw_context.eip = 0x4000f49d; 3829c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek raw_context.esp = stack_section.start().Value(); 3839c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek // Make the frame pointer bogus, to make the stackwalker scan the stack 3849c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek // for something that looks like a return address. 3859c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek raw_context.ebp = 0xd43eed6e; 3869c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek 3879753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 3889c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 3899753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com &frame_symbolizer); 3905a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 3912d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 3922d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 3932d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 3945a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(1U, modules_without_symbols.size()); 3955a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 3962d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 3979c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek frames = call_stack.frames(); 3989c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek ASSERT_EQ(2U, frames->size()); 3999c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek 4002660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 4012660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 4022660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 4032660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 4042660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000f49dU, frame0->instruction); 4052660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000f49dU, frame0->context.eip); 4062660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); 4072660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0xd43eed6eU, frame0->context.ebp); 4082660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(NULL, frame0->windows_frame_info); 4092660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 4102660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 4112660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 4122660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1)); 4132660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); 4142660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP 4152660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_ESP 4162660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EBP), 4172660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->context_validity); 4182660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000129dU, frame1->instruction + 1); 4192660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000129dU, frame1->context.eip); 4207a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); 4217a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); 4222660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(NULL, frame1->windows_frame_info); 4232660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 42442b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com} 42542b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com 42642b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com// Test that set_max_frames_scanned prevents using stack scanning 42742b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com// to find caller frames. 42842b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.comTEST_F(GetCallerFrame, ScanningNotAllowed) { 42942b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com stack_section.start() = 0x80000000; 43042b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com Label frame1_ebp; 43142b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com stack_section 43242b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com // frame 0 43342b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com .D32(0xf065dc76) // locals area: 43442b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com .D32(0x46ee2167) // garbage that doesn't look like 43542b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com .D32(0xbab023ec) // a return address 43642b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com .D32(frame1_ebp) // saved %ebp (%ebp fails to point here, forcing scan) 43742b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com .D32(0x4000129d) // return address 43842b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com // frame 1 43942b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com .Append(8, 0) // space 44042b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com .Mark(&frame1_ebp) // %ebp points here 44142b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com .D32(0) // saved %ebp (stack end) 44242b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com .D32(0); // return address (stack end) 44342b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com 44442b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com RegionFromSection(); 44542b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com raw_context.eip = 0x4000f49d; 44642b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com raw_context.esp = stack_section.start().Value(); 44742b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com // Make the frame pointer bogus, to make the stackwalker scan the stack 44842b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com // for something that looks like a return address. 44942b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com raw_context.ebp = 0xd43eed6e; 45042b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com 45142b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 45242b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 45342b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com &frame_symbolizer); 45442b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com Stackwalker::set_max_frames_scanned(0); 45542b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com 45642b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com vector<const CodeModule*> modules_without_symbols; 45742b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 45842b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 45942b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com &modules_with_corrupt_symbols)); 46042b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com ASSERT_EQ(1U, modules_without_symbols.size()); 46142b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 46242b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 46342b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com frames = call_stack.frames(); 46442b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com ASSERT_EQ(1U, frames->size()); 46542b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com 46642b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com { // To avoid reusing locals by mistake 46742b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 46842b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 46942b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 47042b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com EXPECT_EQ(0x4000f49dU, frame0->instruction); 47142b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com EXPECT_EQ(0x4000f49dU, frame0->context.eip); 47242b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); 47342b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com EXPECT_EQ(0xd43eed6eU, frame0->context.ebp); 47442b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com EXPECT_EQ(NULL, frame0->windows_frame_info); 47542b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com } 4769c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek} 4779c30407f7f2c6e6a352cd62fe4be21fe55ee1879ted.mielczarek 478a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// Use Windows frame data (a "STACK WIN 4" record, from a 479a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// FrameTypeFrameData DIA record) to walk a stack frame. 480a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyTEST_F(GetCallerFrame, WindowsFrameData) { 481a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy SetModuleSymbols(&module1, 482a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy "STACK WIN 4 aa85 176 0 0 4 10 4 0 1" 483a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $T2 $esp .cbSavedRegs + =" 484a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $T0 .raSearchStart =" 485a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $eip $T0 ^ =" 486a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $esp $T0 4 + =" 487a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $ebx $T2 4 - ^ =" 488a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $edi $T2 8 - ^ =" 489a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $esi $T2 12 - ^ =" 490a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $ebp $T2 16 - ^ =\n"); 491a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy Label frame1_esp, frame1_ebp; 492a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section.start() = 0x80000000; 493a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section 494a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 0 495a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(frame1_ebp) // saved regs: %ebp 496a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0xa7120d1a) // %esi 497a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x630891be) // %edi 498a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x9068a878) // %ebx 499a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0xa08ea45f) // locals: unused 500a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x40001350) // return address 501a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 1 502a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame1_esp) 503a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Append(12, 0) // empty space 504a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame1_ebp) 505a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0) // saved %ebp (stack end) 506a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0); // saved %eip (stack end) 507a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 508a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy RegionFromSection(); 509a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.eip = 0x4000aa85; 510a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.esp = stack_section.start().Value(); 511a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.ebp = 0xf052c1de; // should not be needed to walk frame 512a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 5139753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 514a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 5159753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com &frame_symbolizer); 5165a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 5172d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 5182d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 5192d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 5205a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(0U, modules_without_symbols.size()); 5212d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 522a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy frames = call_stack.frames(); 523a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy ASSERT_EQ(2U, frames->size()); 524a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 5252660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 5262660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 5272660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 5282660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 5292660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000aa85U, frame0->instruction); 5302660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000aa85U, frame0->context.eip); 5312660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); 5322660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0xf052c1deU, frame0->context.ebp); 5332660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_TRUE(frame0->windows_frame_info != NULL); 5342660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 5352660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 5362660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 5372660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1)); 5382660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); 5392660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP 5402660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_ESP 5412660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EBP 5422660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EBX 5432660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_ESI 5442660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EDI), 5452660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->context_validity); 5462660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40001350U, frame1->instruction + 1); 5472660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40001350U, frame1->context.eip); 5482660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); 5492660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); 5502660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x9068a878U, frame1->context.ebx); 5512660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0xa7120d1aU, frame1->context.esi); 5522660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x630891beU, frame1->context.edi); 5532660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(NULL, frame1->windows_frame_info); 5542660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 555a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy} 556a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 557a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// Use Windows frame data (a "STACK WIN 4" record, from a 5586679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org// FrameTypeFrameData DIA record) to walk a stack frame where the stack 5596679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org// is aligned and we must search 5606679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.orgTEST_F(GetCallerFrame, WindowsFrameDataAligned) { 5616679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org SetModuleSymbols(&module1, 5626679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org "STACK WIN 4 aa85 176 0 0 4 4 8 0 1" 5637a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com " $T1 .raSearch =" 5647a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com " $T0 $T1 4 - 8 @ =" 5657a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com " $ebp $T1 4 - ^ =" 5667a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com " $eip $T1 ^ =" 5677a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com " $esp $T1 4 + ="); 56815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com Label frame0_esp, frame0_ebp; 5696679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org Label frame1_esp, frame1_ebp; 5706679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org stack_section.start() = 0x80000000; 5716679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org stack_section 5726679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org // frame 0 57315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .Mark(&frame0_esp) 5746679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org .D32(0x0ffa0ffa) // unused saved register 5756679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org .D32(0xdeaddead) // locals 5766679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org .D32(0xbeefbeef) 5776679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org .D32(0) // 8-byte alignment 57815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .Mark(&frame0_ebp) 57915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(frame1_ebp) // saved %ebp 5806679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org .D32(0x5000129d) // return address 5816679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org // frame 1 5826679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org .Mark(&frame1_esp) 5836679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org .D32(0x1) // parameter 5846679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org .Mark(&frame1_ebp) 5856679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org .D32(0) // saved %ebp (stack end) 5866679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org .D32(0); // saved %eip (stack end) 5876679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org 5886679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org RegionFromSection(); 5896679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org raw_context.eip = 0x4000aa85; 59015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com raw_context.esp = frame0_esp.Value(); 59115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com raw_context.ebp = frame0_ebp.Value(); 5926679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org 5939753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 5946679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 5959753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com &frame_symbolizer); 5965a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 5972d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 5982d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 5992d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 6005a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(1U, modules_without_symbols.size()); 6015a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ("module2", modules_without_symbols[0]->debug_file()); 6022d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 6036679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org frames = call_stack.frames(); 6046679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org ASSERT_EQ(2U, frames->size()); 6056679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org 6062660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 6072660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 6082660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 6092660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 6102660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000aa85U, frame0->instruction); 6112660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000aa85U, frame0->context.eip); 61215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(frame0_esp.Value(), frame0->context.esp); 61315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp); 6142660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_TRUE(frame0->windows_frame_info != NULL); 6152660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 6162660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 6172660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 6182660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1)); 6192660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); 6202660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP 6212660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_ESP 6222660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EBP), 6232660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->context_validity); 6242660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x5000129dU, frame1->instruction + 1); 6252660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x5000129dU, frame1->context.eip); 6262660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); 6272660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); 6282660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(NULL, frame1->windows_frame_info); 6292660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 6306679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org} 6316679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org 6326679ad568c3e3796acab4022dbfdcfad484e34e8mark@chromium.org// Use Windows frame data (a "STACK WIN 4" record, from a 633a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// FrameTypeFrameData DIA record) to walk a frame, and depend on the 634a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// parameter size from the callee as well. 635a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyTEST_F(GetCallerFrame, WindowsFrameDataParameterSize) { 636a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy SetModuleSymbols(&module1, "FUNC 1000 100 c module1::wheedle\n"); 637a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy SetModuleSymbols(&module2, 6386d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // Note bogus parameter size in FUNC record; the stack walker 6396d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // should prefer the STACK WIN record, and see '4' below. 640a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy "FUNC aa85 176 beef module2::whine\n" 641a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy "STACK WIN 4 aa85 176 0 0 4 10 4 0 1" 642a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $T2 $esp .cbLocals + .cbSavedRegs + =" 643a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $T0 .raSearchStart =" 644a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $eip $T0 ^ =" 645a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $esp $T0 4 + =" 646a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $ebp $T0 20 - ^ =" 647a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $ebx $T0 8 - ^ =\n"); 648a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy Label frame0_esp, frame0_ebp; 649a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy Label frame1_esp; 650a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy Label frame2_esp, frame2_ebp; 651a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section.start() = 0x80000000; 652a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section 653a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 0, in module1::wheedle. Traditional frame. 654a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame0_esp) 655a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Append(16, 0) // frame space 656a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame0_ebp) 657a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x6fa902e0) // saved %ebp. Not a frame pointer. 658a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x5000aa95) // return address, in module2::whine 659a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 1, in module2::whine. FrameData frame. 660a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame1_esp) 661a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0xbaa0cb7a) // argument 3 passed to module1::wheedle 662a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0xbdc92f9f) // argument 2 663a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x0b1d8442) // argument 1 664a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(frame2_ebp) // saved %ebp 665a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0xb1b90a15) // unused 666a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0xf18e072d) // unused 667a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x2558c7f3) // saved %ebx 668a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x0365e25e) // unused 669a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x2a179e38) // return address; $T0 points here 670a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 2, in no module 671a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame2_esp) 672a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Append(12, 0) // empty space 673a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame2_ebp) 674a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0) // saved %ebp (stack end) 675a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0); // saved %eip (stack end) 676a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 677a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy RegionFromSection(); 6787a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.eip = 0x40001004; // in module1::wheedle 679a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.esp = stack_section.start().Value(); 680a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.ebp = frame0_ebp.Value(); 681a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 6829753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 683a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 6849753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com &frame_symbolizer); 6855a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 6862d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 6872d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 6882d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 6895a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(0U, modules_without_symbols.size()); 6902d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 691a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy frames = call_stack.frames(); 692a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy ASSERT_EQ(3U, frames->size()); 693a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 6942660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 6952660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 6962660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 6972660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 6982660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40001004U, frame0->instruction); 6992660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40001004U, frame0->context.eip); 7002660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame0_esp.Value(), frame0->context.esp); 7012660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp); 7022660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(&module1, frame0->module); 7032660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ("module1::wheedle", frame0->function_name); 7042660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40001000U, frame0->function_base); 7052660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // The FUNC record for module1::wheedle should have produced a 7062660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // WindowsFrameInfo structure with only the parameter size valid. 7072660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_TRUE(frame0->windows_frame_info != NULL); 7082660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE, 7092660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame0->windows_frame_info->valid); 7102660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_UNKNOWN, 7112660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame0->windows_frame_info->type_); 7122660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(12U, frame0->windows_frame_info->parameter_size); 7132660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 7142660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 7152660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 7162660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1)); 7172660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust); 7182660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP 7192660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_ESP 7202660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EBP), 7212660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->context_validity); 7222660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x5000aa95U, frame1->instruction + 1); 7232660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x5000aa95U, frame1->context.eip); 7242660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); 7252660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x6fa902e0U, frame1->context.ebp); 7262660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(&module2, frame1->module); 7272660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ("module2::whine", frame1->function_name); 7282660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x5000aa85U, frame1->function_base); 7292660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_TRUE(frame1->windows_frame_info != NULL); 7302660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid); 7312660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, 7322660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->windows_frame_info->type_); 7332660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // This should not see the 0xbeef parameter size from the FUNC 7342660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // record, but should instead see the STACK WIN record. 7352660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(4U, frame1->windows_frame_info->parameter_size); 7362660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 7372660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 7382660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 7392660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame2 = static_cast<StackFrameX86 *>(frames->at(2)); 7402660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust); 7412660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP 7422660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_ESP 7432660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EBP 7442660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EBX), 7452660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame2->context_validity); 7462660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x2a179e38U, frame2->instruction + 1); 7472660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x2a179e38U, frame2->context.eip); 7482660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame2_esp.Value(), frame2->context.esp); 7492660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame2_ebp.Value(), frame2->context.ebp); 7502660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x2558c7f3U, frame2->context.ebx); 7512660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(NULL, frame2->module); 7522660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(NULL, frame2->windows_frame_info); 7532660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 754a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy} 755a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 756a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// Use Windows frame data (a "STACK WIN 4" record, from a 757a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// FrameTypeFrameData DIA record) to walk a stack frame, where the 7586d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy// expression fails to yield both an $eip and an $ebp value, and the stack 7596d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy// walker must scan. 760a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyTEST_F(GetCallerFrame, WindowsFrameDataScan) { 761a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy SetModuleSymbols(&module1, 762a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy "STACK WIN 4 c8c 111 0 0 4 10 4 0 1 bad program string\n"); 763a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // Mark frame 1's PC as the end of the stack. 764a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy SetModuleSymbols(&module2, 765a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy "FUNC 7c38 accf 0 module2::function\n" 766a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy "STACK WIN 4 7c38 accf 0 0 4 10 4 0 1 $eip 0 = $ebp 0 =\n"); 767a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy Label frame1_esp; 768a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section.start() = 0x80000000; 769a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section 770a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 0 771a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Append(16, 0x2a) // unused, garbage 772a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x50007ce9) // return address 773a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 1 774a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame1_esp) 775a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Append(8, 0); // empty space 776a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 777a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy RegionFromSection(); 778a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.eip = 0x40000c9c; 779a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.esp = stack_section.start().Value(); 780a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.ebp = 0x2ae314cd; // should not be needed to walk frame 781a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 7829753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 783a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 7849753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com &frame_symbolizer); 7855a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 7862d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 7872d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 7882d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 7895a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(0U, modules_without_symbols.size()); 7902d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 791a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy frames = call_stack.frames(); 792a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy ASSERT_EQ(2U, frames->size()); 793a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 7942660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 7952660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 7962660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 7972660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 7982660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40000c9cU, frame0->instruction); 7992660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40000c9cU, frame0->context.eip); 8002660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); 8012660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x2ae314cdU, frame0->context.ebp); 8022660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_TRUE(frame0->windows_frame_info != NULL); 8032660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 8042660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 8052660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 8062660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1)); 8072660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); 8082660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the walker 8092660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // does not actually fetch the EBP after a scan (forcing the next frame 8102660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // to be scanned as well). But let's grandfather the existing behavior in 8112660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // for now. 8122660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP 8132660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_ESP 8142660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EBP), 8152660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->context_validity); 8162660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x50007ce9U, frame1->instruction + 1); 8172660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x50007ce9U, frame1->context.eip); 8182660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); 8192660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_TRUE(frame1->windows_frame_info != NULL); 8202660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 821a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy} 822a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 823a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// Use Windows frame data (a "STACK WIN 4" record, from a 824a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// FrameTypeFrameData DIA record) to walk a stack frame, where the 8256d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy// expression yields an $eip that falls outside of any module, and the 8266d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy// stack walker must scan. 827a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyTEST_F(GetCallerFrame, WindowsFrameDataBadEIPScan) { 828a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy SetModuleSymbols(&module1, 829a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy "STACK WIN 4 6e6 e7 0 0 0 8 4 0 1" 830a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // A traditional frame, actually. 831a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy " $eip $ebp 4 + ^ = $esp $ebp 8 + = $ebp $ebp ^ =\n"); 832a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // Mark frame 1's PC as the end of the stack. 833a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy SetModuleSymbols(&module2, 834a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy "FUNC cfdb 8406 0 module2::function\n" 835a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy "STACK WIN 4 cfdb 8406 0 0 0 0 0 0 1 $eip 0 = $ebp 0 =\n"); 836a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section.start() = 0x80000000; 837a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 838a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // In this stack, the context's %ebp is pointing at the wrong place, so 8396d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // the stack walker needs to scan to find the return address, and then 8406d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // scan again to find the caller's saved %ebp. 841a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy Label frame0_ebp, frame1_ebp, frame1_esp; 842a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section 843a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 0 844a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Append(8, 0x2a) // garbage 845a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame0_ebp) // frame 0 %ebp points here, but should point 846a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // at *** below 847a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // The STACK WIN record says that the following two values are 848a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 1's saved %ebp and return address, but the %ebp is wrong; 8496d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // they're garbage. The stack walker will scan for the right values. 850a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x3d937b2b) // alleged to be frame 1's saved %ebp 851a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x17847f5b) // alleged to be frame 1's return address 852a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(frame1_ebp) // frame 1's real saved %ebp; scan will find 853a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x2b2b2b2b) // first word of realigned register save area 854a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // *** frame 0 %ebp ought to be pointing here 855a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x2c2c2c2c) // realigned locals area 856a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x5000d000) // frame 1's real saved %eip; scan will find 857a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // Frame 1, in module2::function. The STACK WIN record describes 858a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // this as the oldest frame, without referring to its contents, so 8596d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // we needn't to provide any actual data here. 860a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame1_esp) 861a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame1_ebp) // frame 1 %ebp points here 862a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // A dummy value for frame 1's %ebp to point at. The scan recognizes the 863a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // saved %ebp because it points to a valid word in the stack memory region. 864a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x2d2d2d2d); 865a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 866a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy RegionFromSection(); 867a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.eip = 0x40000700; 868a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.esp = stack_section.start().Value(); 869a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.ebp = frame0_ebp.Value(); 870a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 8719753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 872a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 8739753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com &frame_symbolizer); 8745a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 8752d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 8762d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 8772d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 8785a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(0U, modules_without_symbols.size()); 8792d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 880a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy frames = call_stack.frames(); 881a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy ASSERT_EQ(2U, frames->size()); 882a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 8832660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 8842660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 8852660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 8862660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 8872660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40000700U, frame0->instruction); 8882660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40000700U, frame0->context.eip); 8892660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); 8902660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp); 8912660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_TRUE(frame0->windows_frame_info != NULL); 8922660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 8932660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 8942660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 8952660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1)); 8962660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CFI_SCAN, frame1->trust); 8972660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the 8982660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // walker does not actually fetch the EBP after a scan (forcing the 8992660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // next frame to be scanned as well). But let's grandfather the existing 9002660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // behavior in for now. 9012660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP 9022660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_ESP 9032660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EBP), 9042660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->context_validity); 9052660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x5000d000U, frame1->instruction + 1); 9062660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x5000d000U, frame1->context.eip); 9072660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); 9082660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); 9092660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_TRUE(frame1->windows_frame_info != NULL); 9102660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 911a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy} 912a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 913a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// Use Windows FrameTypeFPO data to walk a stack frame for a function that 914a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// does not modify %ebp from the value it had in the caller. 915a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyTEST_F(GetCallerFrame, WindowsFPOUnchangedEBP) { 916a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy SetModuleSymbols(&module1, 9176d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // Note bogus parameter size in FUNC record; the walker 9186d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // should prefer the STACK WIN record, and see the '8' below. 919a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy "FUNC e8a8 100 feeb module1::discombobulated\n" 920a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy "STACK WIN 0 e8a8 100 0 0 8 4 10 0 0 0\n"); 921a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy Label frame0_esp; 922a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy Label frame1_esp, frame1_ebp; 923a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section.start() = 0x80000000; 924a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section 925a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 0, in module1::wheedle. FrameTypeFPO (STACK WIN 0) frame. 926a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame0_esp) 927a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // no outgoing parameters; this is the youngest frame. 9287a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x7c521352) // four bytes of saved registers 9297a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Append(0x10, 0x42) // local area 9307a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x40009b5b) // return address, in module1, no function 931a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 1, in module1, no function. 932a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame1_esp) 9337a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0xf60ea7fc) // junk 934a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame1_ebp) 9357a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0) // saved %ebp (stack end) 9367a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0); // saved %eip (stack end) 937a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 938a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy RegionFromSection(); 9397a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.eip = 0x4000e8b8; // in module1::whine 940a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.esp = stack_section.start().Value(); 941a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // Frame pointer unchanged from caller. 942a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.ebp = frame1_ebp.Value(); 943a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 9449753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 945a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 9469753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com &frame_symbolizer); 9475a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 9482d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 9492d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 9502d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 9515a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(0U, modules_without_symbols.size()); 9522d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 953a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy frames = call_stack.frames(); 954a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy ASSERT_EQ(2U, frames->size()); 955a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 9562660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 9572660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 9582660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 9592660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 9602660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000e8b8U, frame0->instruction); 9612660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000e8b8U, frame0->context.eip); 9622660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame0_esp.Value(), frame0->context.esp); 9637a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com // unchanged from caller 9647a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(frame1_ebp.Value(), frame0->context.ebp); 9652660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(&module1, frame0->module); 9662660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ("module1::discombobulated", frame0->function_name); 9672660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000e8a8U, frame0->function_base); 9682660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // The STACK WIN record for module1::discombobulated should have 9692660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // produced a fully populated WindowsFrameInfo structure. 9702660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_TRUE(frame0->windows_frame_info != NULL); 9712660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid); 9722660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO, 9732660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame0->windows_frame_info->type_); 9742660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x10U, frame0->windows_frame_info->local_size); 9752660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 9762660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 9772660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 9782660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1)); 9792660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); 9802660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP 9812660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_ESP 9822660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EBP), 9832660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->context_validity); 9842660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40009b5bU, frame1->instruction + 1); 9852660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40009b5bU, frame1->context.eip); 9862660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); 9872660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); 9882660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(&module1, frame1->module); 9892660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ("", frame1->function_name); 9902660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(NULL, frame1->windows_frame_info); 9912660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 992a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy} 993a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 994a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// Use Windows FrameTypeFPO data to walk a stack frame for a function 995a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// that uses %ebp for its own purposes, saving the value it had in the 996a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy// caller in the standard place in the saved register area. 997a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandyTEST_F(GetCallerFrame, WindowsFPOUsedEBP) { 998a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy SetModuleSymbols(&module1, 9996d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // Note bogus parameter size in FUNC record; the walker 10006d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // should prefer the STACK WIN record, and see the '8' below. 1001a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy "FUNC 9aa8 e6 abbe module1::RaisedByTheAliens\n" 1002a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy "STACK WIN 0 9aa8 e6 a 0 10 8 4 0 0 1\n"); 1003a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy Label frame0_esp; 1004a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy Label frame1_esp, frame1_ebp; 1005a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section.start() = 0x80000000; 1006a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy stack_section 1007a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 0, in module1::wheedle. FrameTypeFPO (STACK WIN 0) frame. 1008a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame0_esp) 1009a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // no outgoing parameters; this is the youngest frame. 1010a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(frame1_ebp) // saved register area: saved %ebp 1011a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0xb68bd5f9) // saved register area: something else 1012a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0xd25d05fc) // local area 1013a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0x4000debe) // return address, in module1, no function 1014a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // frame 1, in module1, no function. 1015a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame1_esp) 1016a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0xf0c9a974) // junk 1017a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .Mark(&frame1_ebp) 1018a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0) // saved %ebp (stack end) 1019a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy .D32(0); // saved %eip (stack end) 1020a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 1021a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy RegionFromSection(); 10227a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.eip = 0x40009ab8; // in module1::RaisedByTheAliens 1023a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.esp = stack_section.start().Value(); 1024a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy // RaisedByTheAliens uses %ebp for its own mysterious purposes. 1025a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy raw_context.ebp = 0xecbdd1a5; 1026a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 10279753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 1028a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 10299753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com &frame_symbolizer); 10305a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 10312d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 10322d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 10332d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 10345a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(0U, modules_without_symbols.size()); 10352d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 1036a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy frames = call_stack.frames(); 1037a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy ASSERT_EQ(2U, frames->size()); 1038a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy 10392660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 10402660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 10412660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 10422660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 10432660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40009ab8U, frame0->instruction); 10442660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40009ab8U, frame0->context.eip); 10452660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame0_esp.Value(), frame0->context.esp); 10462660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0xecbdd1a5, frame0->context.ebp); 10472660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(&module1, frame0->module); 10482660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ("module1::RaisedByTheAliens", frame0->function_name); 10492660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40009aa8U, frame0->function_base); 10502660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // The STACK WIN record for module1::RaisedByTheAliens should have 10512660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // produced a fully populated WindowsFrameInfo structure. 10522660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_TRUE(frame0->windows_frame_info != NULL); 10532660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid); 10542660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO, 10552660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame0->windows_frame_info->type_); 10562660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ("", frame0->windows_frame_info->program_string); 10572660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_TRUE(frame0->windows_frame_info->allocates_base_pointer); 10582660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 10592660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 10602660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 10612660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1)); 10622660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); 10632660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP 10642660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_ESP 10652660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EBP), 10662660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->context_validity); 10672660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000debeU, frame1->instruction + 1); 10682660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x4000debeU, frame1->context.eip); 10692660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); 10702660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); 10712660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(&module1, frame1->module); 10722660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ("", frame1->function_name); 10732660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(NULL, frame1->windows_frame_info); 10742660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 10752660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com} 10762660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 10772660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com// This is a regression unit test which covers a bug which has to do with 10782660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com// FPO-optimized Windows system call stubs in the context frame. There is 10792660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com// a more recent Windows system call dispatch mechanism which differs from 10802660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com// the one which is being tested here. The newer system call dispatch 10812660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com// mechanism creates an extra context frame (KiFastSystemCallRet). 10822660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.comTEST_F(GetCallerFrame, WindowsFPOSystemCall) { 10832660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com SetModuleSymbols(&module3, // ntdll.dll 10842660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "PUBLIC 1f8ac c ZwWaitForSingleObject\n" 10852660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "STACK WIN 0 1f8ac 1b 0 0 c 0 0 0 0 0\n"); 10862660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com SetModuleSymbols(&module4, // kernelbase.dll 10872660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "PUBLIC 109f9 c WaitForSingleObjectEx\n" 10882660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "PUBLIC 36590 0 _except_handler4\n" 10892660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "STACK WIN 4 109f9 df c 0 c c 48 0 1 $T0 $ebp = $eip " 10902660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L " 10912660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n" 10922660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "STACK WIN 4 36590 154 17 0 10 0 14 0 1 $T0 $ebp = $eip " 10932660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 " 10942660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ".cbSavedRegs - = $P $T0 8 + .cbParams + =\n"); 10952660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com SetModuleSymbols(&module5, // kernel32.dll 10962660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "PUBLIC 11136 8 WaitForSingleObject\n" 10972660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "PUBLIC 11151 c WaitForSingleObjectExImplementation\n" 10982660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "STACK WIN 4 11136 16 5 0 8 0 0 0 1 $T0 $ebp = $eip " 10992660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L " 11002660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n" 11012660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "STACK WIN 4 11151 7a 5 0 c 0 0 0 1 $T0 $ebp = $eip " 11022660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L " 11032660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n"); 11042660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com SetModuleSymbols(&module6, // chrome.dll 11052660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "FILE 7038 some_file_name.h\n" 11062660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "FILE 839776 some_file_name.cc\n" 11072660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "FUNC 217fda 17 4 function_217fda\n" 11082660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "217fda 4 102 839776\n" 11092660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "FUNC 217ff1 a 4 function_217ff1\n" 11102660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "217ff1 0 594 7038\n" 11112660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "217ff1 a 596 7038\n" 11122660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "STACK WIN 0 217ff1 a 0 0 4 0 0 0 0 0\n"); 11132660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 11142660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com Label frame0_esp, frame1_esp; 11152660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com Label frame1_ebp, frame2_ebp, frame3_ebp; 11162660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com stack_section.start() = 0x002ff290; 11172660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com stack_section 11182660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .Mark(&frame0_esp) 11192660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x771ef8c1) // EIP in frame 0 (system call) 11202660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x75fa0a91) // return address of frame 0 11212660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .Mark(&frame1_esp) 11222660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x000017b0) // args to child 11232660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000000) 11242660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x002ff2d8) 11252660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x88014a2e) 11262660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x002ff364) 11272660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x000017b0) 11282660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000000) 11292660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000024) 11302660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000001) 11312660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000000) 11322660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000000) 11332660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000000) 11342660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000000) 11352660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000000) 11362660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000000) 11372660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000000) 11382660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x9e3b9800) 11392660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0xfffffff7) 11402660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000000) 11412660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x002ff2a4) 11422660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x64a07ff1) // random value to be confused with a return address 11432660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x002ff8dc) 11442660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x75fc6590) // random value to be confused with a return address 11452660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0xfdd2c6ea) 11462660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000000) 11472660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .Mark(&frame1_ebp) 11482660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(frame2_ebp) // Child EBP 11492660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x75741194) // return address of frame 1 11502660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x000017b0) // args to child 11512660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x0036ee80) 11522660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000000) 11532660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x65bc7d14) 11542660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .Mark(&frame2_ebp) 11552660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(frame3_ebp) // Child EBP 11562660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x75741148) // return address of frame 2 11572660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x000017b0) // args to child 11582660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x0036ee80) 11592660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0x00000000) 11602660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .Mark(&frame3_ebp) 11612660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0) // saved %ebp (stack end) 11622660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com .D32(0); // saved %eip (stack end) 11632660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 11642660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com RegionFromSection(); 11652660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com raw_context.eip = 0x771ef8c1; // in ntdll::ZwWaitForSingleObject 11662660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com raw_context.esp = stack_section.start().Value(); 11672660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_TRUE(raw_context.esp == frame0_esp.Value()); 11682660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com raw_context.ebp = frame1_ebp.Value(); 11692660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 11709753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 11712660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 11729753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com &frame_symbolizer); 11735a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 11742d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 11752d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 11762d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 11775a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(0U, modules_without_symbols.size()); 11782d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 11792660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frames = call_stack.frames(); 11802660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 11812660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ(4U, frames->size()); 11822660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 11832660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 11842660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 11852660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 11862660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 11872660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x771ef8c1U, frame0->instruction); 11882660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x771ef8c1U, frame0->context.eip); 11892660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame0_esp.Value(), frame0->context.esp); 11902660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_ebp.Value(), frame0->context.ebp); 11912660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(&module3, frame0->module); 11922660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ("ZwWaitForSingleObject", frame0->function_name); 11932660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // The STACK WIN record for module3!ZwWaitForSingleObject should have 11942660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // produced a fully populated WindowsFrameInfo structure. 11952660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_TRUE(frame0->windows_frame_info != NULL); 11962660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid); 11972660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO, 11982660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame0->windows_frame_info->type_); 11992660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ("", frame0->windows_frame_info->program_string); 12002660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_FALSE(frame0->windows_frame_info->allocates_base_pointer); 12012660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 12022660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 12032660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 12042660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1)); 12052660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); 12062660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP 12072660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_ESP 12082660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com | StackFrameX86::CONTEXT_VALID_EBP), 12092660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->context_validity); 12102660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x75fa0a91U, frame1->instruction + 1); 12112660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x75fa0a91U, frame1->context.eip); 12122660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); 12132660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); 12142660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(&module4, frame1->module); 12152660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ("WaitForSingleObjectEx", frame1->function_name); 12162660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // The STACK WIN record for module4!WaitForSingleObjectEx should have 12172660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com // produced a fully populated WindowsFrameInfo structure. 12182660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_TRUE(frame1->windows_frame_info != NULL); 12192660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid); 12202660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, 12212660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->windows_frame_info->type_); 12222660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L " 12232660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =", 12242660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->windows_frame_info->program_string); 12252660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer); 12262660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 1227a7eb2329ded3a3315be997a7bc7ba64c5c759bd6jimblandy} 12286d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 12293108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com// Scan the stack for a better return address and potentially skip frames 12307a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com// when the calculated return address is not in a known module. Note, that 12317a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com// the span of this scan is somewhat arbitrarily limited to 120 search words 12327a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com// for the context frame and 30 search words (pointers) for the other frames: 12333108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com// const int kRASearchWords = 30; 12343108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com// This means that frames can be skipped only when their size is relatively 12357a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com// small: smaller than 4 * kRASearchWords * sizeof(InstructionType) 12363108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.comTEST_F(GetCallerFrame, ReturnAddressIsNotInKnownModule) { 12373108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com MockCodeModule msvcrt_dll(0x77be0000, 0x58000, "msvcrt.dll", "version1"); 12383108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com SetModuleSymbols(&msvcrt_dll, // msvcrt.dll 12393108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "PUBLIC 38180 0 wcsstr\n" 12403108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "STACK WIN 4 38180 61 10 0 8 0 0 0 1 $T0 $ebp = $eip $T0 " 12413108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs " 12423108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "- = $P $T0 4 + .cbParams + =\n"); 12433108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com 12443108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com MockCodeModule kernel32_dll(0x7c800000, 0x103000, "kernel32.dll", "version1"); 12453108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com SetModuleSymbols(&kernel32_dll, // kernel32.dll 12463108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "PUBLIC efda 8 FindNextFileW\n" 12473108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "STACK WIN 4 efda 1bb c 0 8 8 3c 0 1 $T0 $ebp = $eip $T0 " 12483108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs " 12493108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "- = $P $T0 4 + .cbParams + =\n"); 12503108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com 12513108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com MockCodeModule chrome_dll(0x1c30000, 0x28C8000, "chrome.dll", "version1"); 12523108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com SetModuleSymbols(&chrome_dll, // chrome.dll 12533108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "FUNC e3cff 4af 0 file_util::FileEnumerator::Next()\n" 12543108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "e3cff 1a 711 2505\n" 12553108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "STACK WIN 4 e3cff 4af 20 0 4 c 94 0 1 $T1 .raSearch = " 12563108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "$T0 $T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp " 12573108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "$T1 4 + = $20 $T0 152 - ^ = $23 $T0 156 - ^ = $24 " 12583108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "$T0 160 - ^ =\n"); 12593108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com 12603108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com // Create some modules with some stock debugging information. 12613108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com MockCodeModules local_modules; 12623108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com local_modules.Add(&msvcrt_dll); 12633108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com local_modules.Add(&kernel32_dll); 12643108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com local_modules.Add(&chrome_dll); 12653108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com 12663108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com Label frame0_esp; 12673108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com Label frame0_ebp; 12683108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com Label frame1_ebp; 12693108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com Label frame2_ebp; 12703108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com Label frame3_ebp; 12713108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com 12723108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com stack_section.start() = 0x0932f2d0; 12733108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com stack_section 12743108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .Mark(&frame0_esp) 12753108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0764e000) 12763108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0764e068) 12773108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .Mark(&frame0_ebp) 12783108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(frame1_ebp) // Child EBP 12793108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x001767a0) // return address of frame 0 12803108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com // Not in known module 12813108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0764e0c6) 12823108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x001bb1b8) 12833108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0764e068) 12843108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000003) 12853108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0764e068) 12863108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000003) 12873108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x07578828) 12883108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0764e000) 12893108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 12903108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x001c0010) 12913108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0764e0c6) 12923108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .Mark(&frame1_ebp) 12933108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(frame2_ebp) // Child EBP 12943108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x7c80f10f) // return address of frame 1 12953108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com // inside kernel32!FindNextFileW 12963108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x000008f8) 12973108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 12983108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 12993108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 13003108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f34c) 13013108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0764e000) 13023108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00001000) 13033108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 13043108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000001) 13053108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 13063108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 13073108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f6a8) 13083108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 13093108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f6d8) 13103108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 13113108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x000000d6) 13123108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0764e000) 13133108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x7ff9a000) 13143108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f3fc) 13153108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000001) 13163108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000001) 13173108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x07578828) 13183108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0000002e) 13193108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f340) 13203108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932eef4) 13213108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932ffdc) 13223108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x7c839ad8) 13233108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x7c80f0d8) 13243108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 13253108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .Mark(&frame2_ebp) 13263108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(frame3_ebp) // Child EBP 13273108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x01d13f91) // return address of frame 2 13283108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com // inside chrome_dll!file_util::FileEnumerator::Next 13293108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x07578828) 13303108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f6ac) 13313108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f9c4) 13323108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f9b4) 13333108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 13343108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000003) 13353108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f978) 13363108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x01094330) 13373108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 13383108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000001) 13393108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x01094330) 13403108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 13413108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 13423108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x07f30000) 13433108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x01c3ba17) 13443108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x08bab840) 13453108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x07f31580) 13463108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 13473108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000007) 13483108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f940) 13493108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0000002e) 13503108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f40c) 13513108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x01d13b53) 13523108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f958) 13533108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000001) 13543108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000007) 13553108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f940) 13563108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0000002e) 13573108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 13583108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f6ac) 13593108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x01e13ef0) 13603108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000001) 13613108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000007) 13623108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f958) 13633108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x08bab840) 13643108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f9b4) 13653108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x00000000) 13663108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f9b4) 13673108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x000000a7) 13683108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x000000a7) 13693108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x0932f998) 13703108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0x579627a2) 13713108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .Mark(&frame3_ebp) 13723108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0) // saved %ebp (stack end) 13733108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com .D32(0); // saved %eip (stack end) 13743108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com 13753108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com RegionFromSection(); 13763108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com raw_context.eip = 0x77c181cd; // inside msvcrt!wcsstr 13773108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com raw_context.esp = frame0_esp.Value(); 13783108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com raw_context.ebp = frame0_ebp.Value(); 13793108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com // sanity 13803108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com ASSERT_TRUE(raw_context.esp == stack_section.start().Value()); 13813108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com ASSERT_TRUE(raw_context.ebp == stack_section.start().Value() + 8); 13823108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com 13833108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 13843108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com StackwalkerX86 walker(&system_info, &raw_context, &stack_region, 13853108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com &local_modules, &frame_symbolizer); 13865a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 13872d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 13882d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 13892d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 13905a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(0U, modules_without_symbols.size()); 13912d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 13923108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com frames = call_stack.frames(); 13933108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com 13943108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com ASSERT_EQ(3U, frames->size()); 13953108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com 13963108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com { // To avoid reusing locals by mistake 13973108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 13983108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 13993108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 14003108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(0x77c181cdU, frame0->instruction); 14013108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(0x77c181cdU, frame0->context.eip); 14023108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(frame0_esp.Value(), frame0->context.esp); 14033108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp); 14043108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(&msvcrt_dll, frame0->module); 14053108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ("wcsstr", frame0->function_name); 14063108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com ASSERT_TRUE(frame0->windows_frame_info != NULL); 14073108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid); 14083108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, 14093108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com frame0->windows_frame_info->type_); 14103108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ("$T0 $ebp = $eip $T0 " 14113108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs " 14123108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "- = $P $T0 4 + .cbParams + =", 14133108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com frame0->windows_frame_info->program_string); 14143108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com // It has program string, so allocates_base_pointer is not expected 14153108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_FALSE(frame0->windows_frame_info->allocates_base_pointer); 14163108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com } 14173108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com 14183108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com { // To avoid reusing locals by mistake 14193108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1)); 14203108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CFI_SCAN, frame1->trust); 14213108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | 14223108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_ESP | 14233108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_EBP), 14243108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com frame1->context_validity); 14253108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(0x7c80f10fU, frame1->instruction + 1); 14263108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(0x7c80f10fU, frame1->context.eip); 14273108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com // frame 1 was skipped, so intead of frame1_ebp compare with frame2_ebp. 14283108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(frame2_ebp.Value(), frame1->context.ebp); 14293108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(&kernel32_dll, frame1->module); 14303108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ("FindNextFileW", frame1->function_name); 14313108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com ASSERT_TRUE(frame1->windows_frame_info != NULL); 14323108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid); 14333108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, 14343108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com frame1->windows_frame_info->type_); 14353108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ("$T0 $ebp = $eip $T0 " 14363108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs " 14373108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "- = $P $T0 4 + .cbParams + =", 14383108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com frame1->windows_frame_info->program_string); 14393108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer); 14403108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com } 14413108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com 14423108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com { // To avoid reusing locals by mistake 14433108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com StackFrameX86 *frame2 = static_cast<StackFrameX86 *>(frames->at(2)); 14443108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust); 14453108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | 14463108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_ESP | 14473108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_EBP), 14483108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com frame2->context_validity); 14493108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(0x01d13f91U, frame2->instruction + 1); 14503108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(0x01d13f91U, frame2->context.eip); 14513108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com // frame 1 was skipped, so intead of frame2_ebp compare with frame3_ebp. 14523108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(frame3_ebp.Value(), frame2->context.ebp); 14533108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(&chrome_dll, frame2->module); 14543108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ("file_util::FileEnumerator::Next()", frame2->function_name); 14553108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com ASSERT_TRUE(frame2->windows_frame_info != NULL); 14563108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame2->windows_frame_info->valid); 14573108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, 14583108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com frame2->windows_frame_info->type_); 14593108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_EQ("$T1 .raSearch = " 14603108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "$T0 $T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp " 14613108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "$T1 4 + = $20 $T0 152 - ^ = $23 $T0 156 - ^ = $24 " 14623108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com "$T0 160 - ^ =", 14633108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com frame2->windows_frame_info->program_string); 14643108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com EXPECT_FALSE(frame2->windows_frame_info->allocates_base_pointer); 14653108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com } 14663108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com} 14673108b9dd7bbac28dd01d78f9264fe494ee9c95a0ivan.penkov@gmail.com 146815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com// Test the .raSearchStart/.raSearch calculation when alignment operators are 146915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com// used in the program string. The current %ebp must be valid and it is the 147015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com// only reliable data point that can be used for that calculation. 147115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.comTEST_F(GetCallerFrame, HandleAlignmentInProgramString) { 147215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com MockCodeModule chrome_dll(0x59630000, 0x19e3000, "chrome.dll", "version1"); 147315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com SetModuleSymbols(&chrome_dll, // chrome.dll 147415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "FUNC 56422 50c 8 base::MessageLoop::RunTask" 147515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "(base::PendingTask const &)\n" 147615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "56422 e 458 4589\n" 147715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "STACK WIN 4 56422 50c 11 0 8 c ac 0 1 $T1 .raSearch = $T0 " 147815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "$T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + = " 147915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "$20 $T0 176 - ^ = $23 $T0 180 - ^ = $24 $T0 184 - ^ =\n" 148015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "FUNC 55d34 34a 0 base::MessageLoop::DoWork()\n" 148115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "55d34 11 596 4589\n" 148215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "STACK WIN 4 55d34 34a 19 0 0 c 134 0 1 $T1 .raSearch = " 148315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "$T0 $T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp " 148415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "$T1 4 + = $20 $T0 312 - ^ = $23 $T0 316 - ^ = $24 $T0 " 148515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "320 - ^ =\n" 148615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "FUNC 55c39 fb 0 base::MessagePumpForIO::DoRunLoop()\n" 148715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "55c39 d 518 19962\n" 148815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "STACK WIN 4 55c39 fb d 0 0 c 34 0 1 $T1 .raSearch = $T0 " 148915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "$T1 4 - 64 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + " 149015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "= $20 $T0 56 - ^ = $23 $T0 60 - ^ = $24 $T0 64 - ^ =\n" 149115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "FUNC 55bf0 49 4 base::MessagePumpWin::Run(base::" 149215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "MessagePump::Delegate *)\n" 149315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "55bf0 49 48 4724\n" 149415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "STACK WIN 4 55bf0 49 c 0 4 0 10 0 1 $T0 $ebp = $eip $T0 4 " 149515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "+ ^ = $ebp $T0 ^ = $esp $T0 8 + =\n" 149615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "FUNC 165d de 4 malloc\n" 149715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "165d 6 119 54\n" 149815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "STACK WIN 4 165d de d 0 4 8 0 0 1 $T1 .raSearch = $T0 " 149915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "$T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 " 150015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "+ = $23 $T0 4 - ^ = $24 $T0 8 - ^ =\n" 150115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "FUNC 55ac9 79 0 base::MessageLoop::RunInternal()\n" 150215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "55ac9 d 427 4589\n" 150315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "STACK WIN 4 55ac9 79 d 0 0 8 10 0 1 $T1 .raSearch = $T0 " 150415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "$T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + = " 150515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "$23 $T0 20 - ^ = $24 $T0 24 - ^ =\n"); 150615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com 150715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com // Create some modules with some stock debugging information. 150815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com MockCodeModules local_modules; 150915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com local_modules.Add(&chrome_dll); 151015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com 151115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com Label frame0_esp; 151215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com Label frame0_ebp; 151315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com Label frame1_esp; 151415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com Label frame1_ebp; 151515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com Label frame2_esp; 151615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com Label frame2_ebp; 151715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com Label frame3_esp; 151815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com Label frame3_ebp; 151915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com 152015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com stack_section.start() = 0x046bfc80; 152115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com stack_section 152215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0) 152315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .Mark(&frame0_esp) 152415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x01e235a0) 152515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00000000) 152615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x01e9f580) 152715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x01e9f580) 152815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00000020) 152915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00000000) 153015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00463674) 153115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00000020) 153215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00000000) 153315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x046bfcd8) 153415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x046bfcd8) 153515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x0001204b) 153615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00000000) 153715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0xfdddb523) 153815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00000000) 153915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00000007) 154015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00000040) 154115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00000000) 154215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x59631693) // chrome_59630000!malloc+0x36 154315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x01e9f580) 154415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x01e9f580) 154515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x046bfcf8) 154615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x77da6704) // ntdll!NtSetIoCompletion+0xc 154715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x046bfd4c) 154815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x59685bec) // chrome_59630000!base::MessageLoop::StartHistogrammer.. 154915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x01e235a0) 155015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com 155115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .Mark(&frame0_ebp) 155215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(frame1_ebp) // Child EBP .D32(0x046bfd0c) 155315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x59685c2e) // Return address in 155415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com // chrome_59630000!base::MessagePumpWin::Run+0x3e 155515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .Mark(&frame1_esp) 155615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x01e75a90) 155715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x046bfd4c) 155815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x01e75a90) 155915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00000000) 156015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00000300) 156115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00000001) 156215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com 156315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .Mark(&frame1_ebp) 156415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(frame2_ebp) // Child EBP .D32(0x046bfd30) 156515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x59685b3c) // Return address in 156615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com // chrome_59630000!base::MessageLoop::RunInternal+0x73 156715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .Mark(&frame2_esp) 156815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x01e75a90) 156915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x00000000) 157015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x046bfd4c) 157115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x59658123) // chrome_59630000!std::deque.. 157215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x046bfda0) 157315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x01e79d70) 157415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0x046bfda0) 157515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com 157615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .Mark(&frame2_ebp) // .D32(0x046bfd40) 157715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0) // saved %ebp (stack end) 157815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com .D32(0); // saved %eip (stack end) 157915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com 158015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com RegionFromSection(); 158115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com raw_context.eip = 0x59685c46; // Context frame in 158215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com // base::MessagePumpForIO::DoRunLoop 158315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com raw_context.esp = frame0_esp.Value(); 158415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com raw_context.ebp = frame0_ebp.Value(); 158515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com 158615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 158715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com StackwalkerX86 walker(&system_info, &raw_context, &stack_region, 158815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com &local_modules, &frame_symbolizer); 158915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 159015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 159115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 159215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 159315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com ASSERT_EQ(0U, modules_without_symbols.size()); 159415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 159515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com frames = call_stack.frames(); 159615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com 159715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com ASSERT_EQ(3U, frames->size()); 159815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com 159915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com { // To avoid reusing locals by mistake 160015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0)); 160115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame->trust); 160215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame->context_validity); 160315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ("base::MessagePumpForIO::DoRunLoop()", frame->function_name); 160415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(0x59685c46U, frame->instruction); 160515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(0x59685c46U, frame->context.eip); 160615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(frame0_esp.Value(), frame->context.esp); 160715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(frame0_ebp.Value(), frame->context.ebp); 160815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(&chrome_dll, frame->module); 160915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com ASSERT_TRUE(frame->windows_frame_info != NULL); 161015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame->windows_frame_info->valid); 161115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, 161215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com frame->windows_frame_info->type_); 161315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ("$T1 .raSearch = $T0 " 161415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "$T1 4 - 64 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + " 161515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "= $20 $T0 56 - ^ = $23 $T0 60 - ^ = $24 $T0 64 - ^ =", 161615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com frame->windows_frame_info->program_string); 161715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_FALSE(frame->windows_frame_info->allocates_base_pointer); 161815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com } 161915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com 162015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com { // To avoid reusing locals by mistake 162115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(1)); 162215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame->trust); 162315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | 162415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_ESP | 162515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_EBP), 162615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com frame->context_validity); 162715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ("base::MessagePumpWin::Run(base::MessagePump::Delegate *)", 162815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com frame->function_name); 162915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(1500011566U, frame->instruction + 1); 163015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(1500011566U, frame->context.eip); 163115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(frame1_esp.Value(), frame->context.esp); 163215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(frame1_ebp.Value(), frame->context.ebp); 163315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(&chrome_dll, frame->module); 163415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com ASSERT_TRUE(frame->windows_frame_info != NULL); 163515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame->windows_frame_info->valid); 163615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, 163715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com frame->windows_frame_info->type_); 163815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =", 163915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com frame->windows_frame_info->program_string); 164015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_FALSE(frame->windows_frame_info->allocates_base_pointer); 164115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com } 164215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com 164315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com { // To avoid reusing locals by mistake 164415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(2)); 164515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame->trust); 164615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | 164715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_ESP | 164815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_EBP), 164915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com frame->context_validity); 165015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ("base::MessageLoop::RunInternal()", frame->function_name); 165115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(1500011324U, frame->instruction + 1); 165215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(1500011324U, frame->context.eip); 165315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(frame2_esp.Value(), frame->context.esp); 165415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(frame2_ebp.Value(), frame->context.ebp); 165515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(&chrome_dll, frame->module); 165615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com ASSERT_TRUE(frame->windows_frame_info != NULL); 165715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame->windows_frame_info->valid); 165815c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, 165915c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com frame->windows_frame_info->type_); 166015c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_EQ("$T1 .raSearch = $T0 " 166115c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "$T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + = " 166215c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com "$23 $T0 20 - ^ = $24 $T0 24 - ^ =", 166315c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com frame->windows_frame_info->program_string); 166415c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com EXPECT_FALSE(frame->windows_frame_info->allocates_base_pointer); 166515c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com } 166615c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com} 166715c17c68b68d60ba9736e49d0b4a46a2affbeaf7ivan.penkov@gmail.com 16687a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com// Scan the stack for a return address and potentially skip frames when the 16697a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com// current IP address is not in a known module. Note, that that the span of 16707a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com// this scan is limited to 120 search words for the context frame and 30 16717a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com// search words (pointers) for the other frames: 16727a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com// const int kRASearchWords = 30; 16732d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.comvoid GetCallerFrame::IPAddressIsNotInKnownModuleTestImpl( 16742d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com bool has_corrupt_symbols) { 16757a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com MockCodeModule remoting_core_dll(0x54080000, 0x501000, "remoting_core.dll", 16767a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com "version1"); 16772d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com string symbols_func_section = 16782d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com "FUNC 137214 17d 10 PK11_Verify\n" 16792d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com "FUNC 15c834 37 14 nsc_ECDSAVerifyStub\n" 16802d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com "FUNC 1611d3 91 14 NSC_Verify\n" 16812d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com "FUNC 162ff7 60 4 sftk_SessionFromHandle\n"; 16822d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com string symbols_stack_section = 16837a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com "STACK WIN 4 137214 17d 9 0 10 0 10 0 1 $T0 $ebp = " 16847a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com "$eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =\n" 16857a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com "STACK WIN 4 15c834 37 6 0 14 0 18 0 1 $T0 $ebp = " 16867a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com "$eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =\n" 16877a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com "STACK WIN 4 1611d3 91 7 0 14 0 8 0 1 $T0 $ebp = " 16887a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com "$eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =\n" 16897a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com "STACK WIN 4 162ff7 60 5 0 4 0 0 0 1 $T0 $ebp = " 16902d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com "$eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =\n"; 16912d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com 16922d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com string symbols = symbols_func_section; 16932d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com if (has_corrupt_symbols) { 16942d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com symbols.append(string(1, '\0')); // null terminator in the middle 16952d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com symbols.append("\n"); 16962d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com symbols.append("FUNC 1234\n" // invalid FUNC records 16972d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com "FUNNC 1234\n" 16982d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com "STACK WIN 4 1234 234 23 " // invalid STACK record 16992d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com "23423423 234 23 234 234 " 17002d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com "234 23 234 23 234 234 " 17012d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com "234 234 234\n"); 17022d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com } 17032d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com symbols.append(symbols_stack_section); 17042d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com SetModuleSymbols(&remoting_core_dll, symbols); 17057a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com 17067a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com // Create some modules with some stock debugging information. 17077a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com MockCodeModules local_modules; 17087a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com local_modules.Add(&remoting_core_dll); 17097a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com 17107a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com Label frame0_esp; 17117a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com Label frame0_ebp; 17127a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com Label frame1_ebp; 17137a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com Label frame1_esp; 17147a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com Label frame2_ebp; 17157a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com Label frame2_esp; 17167a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com Label frame3_ebp; 17177a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com Label frame3_esp; 17187a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com Label bogus_stack_location_1; 17197a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com Label bogus_stack_location_2; 17207a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com Label bogus_stack_location_3; 17217a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com 17227a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com stack_section.start() = 0x01a3ea28; 17237a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com stack_section 17247a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame0_esp) 17257a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(bogus_stack_location_2) 17267a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(bogus_stack_location_1) 17277a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x042478e4) 17287a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(bogus_stack_location_2) 17297a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000000) 17307a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x041f0420) 17317a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000000) 17327a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000000) 17337a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000040) 17347a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000001) 17357a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00b7e0d0) 17367a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000000) 17377a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000040) 17387a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000001) 17397a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00b7f570) 17407a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&bogus_stack_location_1) 17417a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000000) 17427a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000040) 17437a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000008) 17447a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x04289530) 17457a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000000) 17467a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000040) 17477a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000008) 17487a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00b7e910) 17497a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000000) 17507a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000040) 17517a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000008) 17527a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00b7d998) 17537a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000000) 17547a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000040) 17557a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000008) 17567a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00b7dec0) 17577a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&bogus_stack_location_2) 17587a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000000) 17597a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000040) 17607a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000008) 17617a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x04289428) 17627a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000000) 17637a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000040) 17647a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000008) 17657a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00b7f258) 17667a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&bogus_stack_location_3) 17677a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000000) 17687a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x041f3560) 17697a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000041) 17707a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000020) 17717a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0xffffffff) 17727a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame0_ebp) 17737a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(frame1_ebp) // Child %ebp 17747a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x541dc866) // return address of frame 0 17757a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com // inside remoting_core!nsc_ECDSAVerifyStub+0x32 17767a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame1_esp) 17777a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x04247860) 17787a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x01a3eaec) 17797a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x01a3eaf8) 17807a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x541e304f) // remoting_core!sftk_SessionFromHandle+0x58 17817a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x0404c620) 17827a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000040) 17837a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x01a3eb2c) 17847a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x01a3ec08) 17857a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000014) 17867a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame1_ebp) 17877a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(frame2_ebp) // Child %ebp 17887a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x541e1234) // return address of frame 1 17897a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com // inside remoting_core!NSC_Verify+0x61 17907a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame2_esp) 17917a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x04247858) 17927a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x0404c620) 17937a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000040) 17947a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x01a3ec08) 17957a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000014) 17967a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x01000005) 17977a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00b2f7a0) 17987a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x041f0420) 17997a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x041f3650) 18007a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame2_ebp) 18017a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(frame3_ebp) // Child %ebp 18027a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x541b734d) // return address of frame 1 18037a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com // inside remoting_core!PK11_Verify+0x139 18047a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame3_esp) 18057a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x01000005) 18067a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x01a3ec08) 18077a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000014) 18087a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x0404c620) 18097a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000040) 18107a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x04073e00) 18117a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x04073e00) 18127a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x04247050) 18137a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00001041) 18147a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000000) 18157a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000000) 18167a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x00000000) 18177a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame3_ebp) 18187a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0) // saved %ebp (stack end) 18197a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0); // saved %eip (stack end) 18207a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com 18217a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com RegionFromSection(); 18227a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.eip = 0x4247860; // IP address not in known module 18237a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.ebp = 0x5420362d; // bogus 18247a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.esp = frame0_esp.Value(); 18257a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com 18267a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com // sanity 18277a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com ASSERT_TRUE(raw_context.esp == stack_section.start().Value()); 18287a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com 18297a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 18307a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com StackwalkerX86 walker(&system_info, &raw_context, &stack_region, 18317a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com &local_modules, &frame_symbolizer); 18327a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 18332d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 18342d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 18352d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 18367a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com ASSERT_EQ(0U, modules_without_symbols.size()); 18372d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com if (has_corrupt_symbols) { 18382d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(1U, modules_with_corrupt_symbols.size()); 18392d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ("remoting_core.dll", 18402d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com modules_with_corrupt_symbols[0]->debug_file()); 18412d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com } else { 18422d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 18432d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com } 18447a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com frames = call_stack.frames(); 18457a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com 18467a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com ASSERT_EQ(4U, frames->size()); 18477a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com 18487a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com { // To avoid reusing locals by mistake 18497a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 18507a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 18517a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 18527a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(raw_context.eip, frame0->context.eip); 18537a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(raw_context.ebp, frame0->context.ebp); 18547a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(raw_context.esp, frame0->context.esp); 18557a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(NULL, frame0->module); // IP not in known module 18567a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ("", frame0->function_name); 18577a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com ASSERT_EQ(NULL, frame0->windows_frame_info); 18587a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com } 18597a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com 18607a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com { // To avoid reusing locals by mistake 18617a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1)); 18627a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); 18637a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | 18647a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_ESP | 18657a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_EBP), 18667a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com frame1->context_validity); 18677a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); 18687a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); 18697a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(&remoting_core_dll, frame1->module); 18707a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ("nsc_ECDSAVerifyStub", frame1->function_name); 18717a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com ASSERT_TRUE(frame1->windows_frame_info != NULL); 18727a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid); 18737a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, 18747a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com frame1->windows_frame_info->type_); 18757a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =", 18767a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com frame1->windows_frame_info->program_string); 18777a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer); 18787a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com } 18797a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com 18807a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com { // To avoid reusing locals by mistake 18817a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com StackFrameX86 *frame2 = static_cast<StackFrameX86 *>(frames->at(2)); 18827a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust); 18837a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | 18847a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_ESP | 18857a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_EBP), 18867a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com frame2->context_validity); 18877a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(frame2_ebp.Value(), frame2->context.ebp); 18887a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(frame2_esp.Value(), frame2->context.esp); 18897a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(&remoting_core_dll, frame2->module); 18907a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ("NSC_Verify", frame2->function_name); 18917a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com ASSERT_TRUE(frame2->windows_frame_info != NULL); 18927a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame2->windows_frame_info->valid); 18937a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, 18947a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com frame2->windows_frame_info->type_); 18957a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =", 18967a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com frame2->windows_frame_info->program_string); 18977a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_FALSE(frame2->windows_frame_info->allocates_base_pointer); 18987a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com } 18997a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com 19007a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com { // To avoid reusing locals by mistake 19017a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com StackFrameX86 *frame3 = static_cast<StackFrameX86 *>(frames->at(3)); 19027a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame3->trust); 19037a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | 19047a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_ESP | 19057a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_EBP), 19067a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com frame3->context_validity); 19077a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(frame3_ebp.Value(), frame3->context.ebp); 19087a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(frame3_esp.Value(), frame3->context.esp); 19097a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(&remoting_core_dll, frame3->module); 19107a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ("PK11_Verify", frame3->function_name); 19117a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com ASSERT_TRUE(frame3->windows_frame_info != NULL); 19127a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame3->windows_frame_info->valid); 19137a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, 19147a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com frame3->windows_frame_info->type_); 19157a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =", 19167a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com frame3->windows_frame_info->program_string); 19177a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com EXPECT_FALSE(frame3->windows_frame_info->allocates_base_pointer); 19187a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com } 19197a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com} 19207a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com 19212d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com// Runs IPAddressIsNotInKnownModule test with good symbols 19222d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.comTEST_F(GetCallerFrame, IPAddressIsNotInKnownModule) { 19232d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com IPAddressIsNotInKnownModuleTestImpl(false /* has_corrupt_modules */); 19242d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com} 19252d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com 19262d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com// Runs IPAddressIsNotInKnownModule test with corrupt symbols 19272d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.comTEST_F(GetCallerFrame, IPAddressIsNotInKnownModule_CorruptSymbols) { 19282d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com IPAddressIsNotInKnownModuleTestImpl(true /* has_corrupt_modules */); 19292d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com} 19302d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com 19316d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandystruct CFIFixture: public StackwalkerX86Fixture { 19326d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy CFIFixture() { 19336d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // Provide a bunch of STACK CFI records; individual tests walk to the 19346d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // caller from every point in this series, expecting to find the same 19356d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // set of register values. 19366d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy SetModuleSymbols(&module1, 19376d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // The youngest frame's function. 19386d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy "FUNC 4000 1000 10 enchiridion\n" 19396d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // Initially, just a return address. 19406d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy "STACK CFI INIT 4000 100 .cfa: $esp 4 + .ra: .cfa 4 - ^\n" 19416d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // Push %ebx. 19426d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy "STACK CFI 4001 .cfa: $esp 8 + $ebx: .cfa 8 - ^\n" 19436d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // Move %esi into %ebx. Weird, but permitted. 19446d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy "STACK CFI 4002 $esi: $ebx\n" 19456d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // Allocate frame space, and save %edi. 19466d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy "STACK CFI 4003 .cfa: $esp 20 + $edi: .cfa 16 - ^\n" 19476d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // Put the return address in %edi. 19486d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy "STACK CFI 4005 .ra: $edi\n" 19496d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // Save %ebp, and use it as a frame pointer. 19506d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy "STACK CFI 4006 .cfa: $ebp 8 + $ebp: .cfa 12 - ^\n" 19516d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 19526d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // The calling function. 19536d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy "FUNC 5000 1000 10 epictetus\n" 19546d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // Mark it as end of stack. 19556d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy "STACK CFI INIT 5000 1000 .cfa: $esp .ra 0\n"); 19566d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 19576d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // Provide some distinctive values for the caller's registers. 19586d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy expected.esp = 0x80000000; 19596d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy expected.eip = 0x40005510; 19606d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy expected.ebp = 0xc0d4aab9; 19616d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy expected.ebx = 0x60f20ce6; 19626d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy expected.esi = 0x53d1379d; 19636d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy expected.edi = 0xafbae234; 19646d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 19656d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // By default, registers are unchanged. 19666d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy raw_context = expected; 19676d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy } 19686d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 19696d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // Walk the stack, using stack_section as the contents of the stack 19706d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // and raw_context as the current register values. (Set 19716d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // raw_context.esp to the stack's starting address.) Expect two 19726d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // stack frames; in the older frame, expect the callee-saves 19736d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // registers to have values matching those in 'expected'. 19746d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy void CheckWalk() { 19756d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy RegionFromSection(); 19766d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy raw_context.esp = stack_section.start().Value(); 19776d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 19789753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 19796d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, 19809753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com &frame_symbolizer); 19815a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com vector<const CodeModule*> modules_without_symbols; 19822d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com vector<const CodeModule*> modules_with_corrupt_symbols; 19832d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 19842d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com &modules_with_corrupt_symbols)); 19855a2106b5f95f3232ac0e9aab5f081eb04313a8b6ivan.penkov@gmail.com ASSERT_EQ(0U, modules_without_symbols.size()); 19862d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 19876d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy frames = call_stack.frames(); 19886d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy ASSERT_EQ(2U, frames->size()); 19896d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 19902660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 19912660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0)); 19922660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 19932660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); 19942660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ("enchiridion", frame0->function_name); 19952660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(0x40004000U, frame0->function_base); 19962660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_TRUE(frame0->windows_frame_info != NULL); 19972660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE, 19982660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame0->windows_frame_info->valid); 19992660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_TRUE(frame0->cfi_frame_info != NULL); 20002660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 20012660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com 20022660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com { // To avoid reusing locals by mistake 20032660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1)); 20042660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); 20052660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP | 20062660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_ESP | 20072660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_EBP | 20082660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_EBX | 20092660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_ESI | 20102660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com StackFrameX86::CONTEXT_VALID_EDI), 20112660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com frame1->context_validity); 20122660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(expected.eip, frame1->context.eip); 20132660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(expected.esp, frame1->context.esp); 20142660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(expected.ebp, frame1->context.ebp); 20152660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(expected.ebx, frame1->context.ebx); 20162660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(expected.esi, frame1->context.esi); 20172660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ(expected.edi, frame1->context.edi); 20182660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com EXPECT_EQ("epictetus", frame1->function_name); 20192660caa1ad5b57ffa763a68c3b96abc10e7f16feivan.penkov@gmail.com } 20206d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy } 20216d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 20226d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy // The values the stack walker should find for the caller's registers. 20236d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy MDRawContextX86 expected; 20246d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy}; 20256d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 20266d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandyclass CFI: public CFIFixture, public Test { }; 20276d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 20286d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandyTEST_F(CFI, At4000) { 20296d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy Label frame1_esp = expected.esp; 20306d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy stack_section 20317a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x40005510) // return address 20327a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame1_esp); // This effectively sets stack_section.start(). 20336d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy raw_context.eip = 0x40004000; 20346d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy CheckWalk(); 20356d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy} 20366d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 20376d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandyTEST_F(CFI, At4001) { 20386d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy Label frame1_esp = expected.esp; 20396d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy stack_section 20407a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x60f20ce6) // saved %ebx 20417a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x40005510) // return address 20427a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame1_esp); // This effectively sets stack_section.start(). 20436d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy raw_context.eip = 0x40004001; 20447a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.ebx = 0x91aa9a8b; // callee's %ebx value 20456d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy CheckWalk(); 20466d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy} 20476d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 20486d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandyTEST_F(CFI, At4002) { 20496d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy Label frame1_esp = expected.esp; 20506d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy stack_section 20517a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x60f20ce6) // saved %ebx 20527a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x40005510) // return address 20537a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame1_esp); // This effectively sets stack_section.start(). 20546d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy raw_context.eip = 0x40004002; 20557a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.ebx = 0x53d1379d; // saved %esi 20567a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.esi = 0xa5c790ed; // callee's %esi value 20576d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy CheckWalk(); 20586d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy} 20596d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 20606d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandyTEST_F(CFI, At4003) { 20616d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy Label frame1_esp = expected.esp; 20626d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy stack_section 20637a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x56ec3db7) // garbage 20647a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0xafbae234) // saved %edi 20657a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x53d67131) // garbage 20667a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x60f20ce6) // saved %ebx 20677a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x40005510) // return address 20687a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame1_esp); // This effectively sets stack_section.start(). 20696d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy raw_context.eip = 0x40004003; 20707a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.ebx = 0x53d1379d; // saved %esi 20717a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.esi = 0xa97f229d; // callee's %esi 20727a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.edi = 0xb05cc997; // callee's %edi 20736d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy CheckWalk(); 20746d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy} 20756d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 20766d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy// The results here should be the same as those at module offset 20776d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy// 0x4003. 20786d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandyTEST_F(CFI, At4004) { 20796d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy Label frame1_esp = expected.esp; 20806d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy stack_section 20817a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0xe29782c2) // garbage 20827a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0xafbae234) // saved %edi 20837a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x5ba29ce9) // garbage 20847a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x60f20ce6) // saved %ebx 20857a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x40005510) // return address 20867a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame1_esp); // This effectively sets stack_section.start(). 20876d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy raw_context.eip = 0x40004004; 20887a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.ebx = 0x53d1379d; // saved %esi 20897a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.esi = 0x0fb7dc4e; // callee's %esi 20907a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.edi = 0x993b4280; // callee's %edi 20916d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy CheckWalk(); 20926d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy} 20936d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 20946d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandyTEST_F(CFI, At4005) { 20956d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy Label frame1_esp = expected.esp; 20966d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy stack_section 20977a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0xe29782c2) // garbage 20987a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0xafbae234) // saved %edi 20997a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x5ba29ce9) // garbage 21007a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x60f20ce6) // saved %ebx 21017a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x8036cc02) // garbage 21027a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame1_esp); // This effectively sets stack_section.start(). 21036d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy raw_context.eip = 0x40004005; 21047a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.ebx = 0x53d1379d; // saved %esi 21057a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.esi = 0x0fb7dc4e; // callee's %esi 21067a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.edi = 0x40005510; // return address 21076d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy CheckWalk(); 21086d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy} 21096d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 21106d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandyTEST_F(CFI, At4006) { 21116d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy Label frame0_ebp; 21126d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy Label frame1_esp = expected.esp; 21136d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy stack_section 21147a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0xdcdd25cd) // garbage 21157a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0xafbae234) // saved %edi 21167a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0xc0d4aab9) // saved %ebp 21177a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame0_ebp) // frame pointer points here 21187a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x60f20ce6) // saved %ebx 21197a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .D32(0x8036cc02) // garbage 21207a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com .Mark(&frame1_esp); // This effectively sets stack_section.start(). 21216d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy raw_context.eip = 0x40004006; 21226d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy raw_context.ebp = frame0_ebp.Value(); 21237a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.ebx = 0x53d1379d; // saved %esi 21247a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.esi = 0x743833c9; // callee's %esi 21257a58af62ecb1e3d76ea0c0d0ad6198e378b4e3f4ivan.penkov@gmail.com raw_context.edi = 0x40005510; // return address 21266d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy CheckWalk(); 21276d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy} 21286d3a825dbf5b924c2e754309b3008e462af1d8d2jimblandy 2129