PageRenderTime 103ms CodeModel.GetById 14ms app.highlight 80ms RepoModel.GetById 1ms app.codeStats 0ms

/thirdparty/breakpad/processor/stackwalker_x86_unittest.cc

http://github.com/tomahawk-player/tomahawk
C++ | 1246 lines | 973 code | 96 blank | 177 comment | 16 complexity | 30817944cd728fe20aee4051da486407 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1// Copyright (c) 2010, Google Inc.
   2// All rights reserved.
   3//
   4// Redistribution and use in source and binary forms, with or without
   5// modification, are permitted provided that the following conditions are
   6// met:
   7//
   8//     * Redistributions of source code must retain the above copyright
   9// notice, this list of conditions and the following disclaimer.
  10//     * Redistributions in binary form must reproduce the above
  11// copyright notice, this list of conditions and the following disclaimer
  12// in the documentation and/or other materials provided with the
  13// distribution.
  14//     * Neither the name of Google Inc. nor the names of its
  15// contributors may be used to endorse or promote products derived from
  16// this software without specific prior written permission.
  17//
  18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29
  30// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
  31
  32// stackwalker_x86_unittest.cc: Unit tests for StackwalkerX86 class.
  33
  34#include <string>
  35#include <vector>
  36
  37#include "breakpad_googletest_includes.h"
  38#include "common/test_assembler.h"
  39#include "google_breakpad/common/minidump_format.h"
  40#include "google_breakpad/processor/basic_source_line_resolver.h"
  41#include "google_breakpad/processor/call_stack.h"
  42#include "google_breakpad/processor/source_line_resolver_interface.h"
  43#include "google_breakpad/processor/stack_frame_cpu.h"
  44#include "processor/stackwalker_unittest_utils.h"
  45#include "processor/stackwalker_x86.h"
  46#include "processor/windows_frame_info.h"
  47
  48using google_breakpad::BasicSourceLineResolver;
  49using google_breakpad::CallStack;
  50using google_breakpad::StackFrame;
  51using google_breakpad::StackFrameX86;
  52using google_breakpad::StackwalkerX86;
  53using google_breakpad::SystemInfo;
  54using google_breakpad::WindowsFrameInfo;
  55using google_breakpad::test_assembler::kLittleEndian;
  56using google_breakpad::test_assembler::Label;
  57using google_breakpad::test_assembler::Section;
  58using std::string;
  59using std::vector;
  60using testing::_;
  61using testing::Return;
  62using testing::SetArgumentPointee;
  63using testing::Test;
  64
  65class StackwalkerX86Fixture {
  66 public:
  67  StackwalkerX86Fixture()
  68    : stack_section(kLittleEndian),
  69      // Give the two modules reasonable standard locations and names
  70      // for tests to play with.
  71      module1(0x40000000, 0x10000, "module1", "version1"),
  72      module2(0x50000000, 0x10000, "module2", "version2"),
  73      module3(0x771d0000, 0x180000, "module3", "version3"),
  74      module4(0x75f90000, 0x46000, "module4", "version4"),
  75      module5(0x75730000, 0x110000, "module5", "version5"),
  76      module6(0x647f0000, 0x1ba8000, "module6", "version6") {
  77    // Identify the system as a Linux system.
  78    system_info.os = "Linux";
  79    system_info.os_short = "linux";
  80    system_info.os_version = "Salacious Skink";
  81    system_info.cpu = "x86";
  82    system_info.cpu_info = "";
  83
  84    // Put distinctive values in the raw CPU context.
  85    BrandContext(&raw_context);
  86
  87    // Create some modules with some stock debugging information.
  88    modules.Add(&module1);
  89    modules.Add(&module2);
  90    modules.Add(&module3);
  91    modules.Add(&module4);
  92    modules.Add(&module5);
  93    modules.Add(&module6);
  94
  95    // By default, none of the modules have symbol info; call
  96    // SetModuleSymbols to override this.
  97    EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _))
  98      .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND));
  99  }
 100
 101  // Set the Breakpad symbol information that supplier should return for
 102  // MODULE to INFO.
 103  void SetModuleSymbols(MockCodeModule *module, const string &info) {
 104    unsigned int buffer_size = info.size() + 1;
 105    char *buffer = reinterpret_cast<char*>(operator new(buffer_size));
 106    strcpy(buffer, info.c_str());
 107    EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _))
 108      .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer),
 109                            Return(MockSymbolSupplier::FOUND)));
 110  }
 111
 112  // Populate stack_region with the contents of stack_section. Use
 113  // stack_section.start() as the region's starting address.
 114  void RegionFromSection() {
 115    string contents;
 116    ASSERT_TRUE(stack_section.GetContents(&contents));
 117    stack_region.Init(stack_section.start().Value(), contents);
 118  }
 119
 120  // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking.
 121  void BrandContext(MDRawContextX86 *raw_context) {
 122    u_int8_t x = 173;
 123    for (size_t i = 0; i < sizeof(*raw_context); i++)
 124      reinterpret_cast<u_int8_t *>(raw_context)[i] = (x += 17);
 125  }
 126  
 127  SystemInfo system_info;
 128  MDRawContextX86 raw_context;
 129  Section stack_section;
 130  MockMemoryRegion stack_region;
 131  MockCodeModule module1;
 132  MockCodeModule module2;
 133  MockCodeModule module3;
 134  MockCodeModule module4;
 135  MockCodeModule module5;
 136  MockCodeModule module6;
 137  MockCodeModules modules;
 138  MockSymbolSupplier supplier;
 139  BasicSourceLineResolver resolver;
 140  CallStack call_stack;
 141  const vector<StackFrame *> *frames;
 142};
 143
 144class SanityCheck: public StackwalkerX86Fixture, public Test { };
 145
 146TEST_F(SanityCheck, NoResolver) {
 147  stack_section.start() = 0x80000000;
 148  stack_section.D32(0).D32(0); // end-of-stack marker
 149  RegionFromSection();
 150  raw_context.eip = 0x40000200;
 151  raw_context.ebp = 0x80000000;
 152
 153  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
 154                        NULL, NULL);
 155  // This should succeed, even without a resolver or supplier.
 156  ASSERT_TRUE(walker.Walk(&call_stack));
 157  frames = call_stack.frames();
 158  StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
 159  // Check that the values from the original raw context made it
 160  // through to the context in the stack frame.
 161  EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
 162}
 163
 164class GetContextFrame: public StackwalkerX86Fixture, public Test { };
 165
 166TEST_F(GetContextFrame, Simple) {
 167  stack_section.start() = 0x80000000;
 168  stack_section.D32(0).D32(0); // end-of-stack marker
 169  RegionFromSection();
 170  raw_context.eip = 0x40000200;
 171  raw_context.ebp = 0x80000000;
 172
 173  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
 174                        &supplier, &resolver);
 175  ASSERT_TRUE(walker.Walk(&call_stack));
 176  frames = call_stack.frames();
 177  StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
 178  // Check that the values from the original raw context made it
 179  // through to the context in the stack frame.
 180  EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
 181}
 182
 183class GetCallerFrame: public StackwalkerX86Fixture, public Test { };
 184
 185// Walk a traditional frame. A traditional frame saves the caller's
 186// %ebp just below the return address, and has its own %ebp pointing
 187// at the saved %ebp.
 188TEST_F(GetCallerFrame, Traditional) {
 189  stack_section.start() = 0x80000000;
 190  Label frame0_ebp, frame1_ebp;
 191  stack_section
 192    .Append(12, 0)                      // frame 0: space
 193    .Mark(&frame0_ebp)                  // frame 0 %ebp points here
 194    .D32(frame1_ebp)                    // frame 0: saved %ebp
 195    .D32(0x40008679)                    // frame 0: return address
 196    .Append(8, 0)                       // frame 1: space
 197    .Mark(&frame1_ebp)                  // frame 1 %ebp points here
 198    .D32(0)                             // frame 1: saved %ebp (stack end)
 199    .D32(0);                            // frame 1: return address (stack end)
 200  RegionFromSection();
 201  raw_context.eip = 0x4000c7a5;
 202  raw_context.esp = stack_section.start().Value();
 203  raw_context.ebp = frame0_ebp.Value();
 204
 205  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
 206                        &supplier, &resolver);
 207  ASSERT_TRUE(walker.Walk(&call_stack));
 208  frames = call_stack.frames();
 209  ASSERT_EQ(2U, frames->size());
 210
 211  {  // To avoid reusing locals by mistake
 212    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
 213    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
 214    EXPECT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
 215    EXPECT_EQ(0x4000c7a5U, frame0->instruction);
 216    EXPECT_EQ(0x4000c7a5U, frame0->context.eip);
 217    EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
 218    EXPECT_EQ(NULL, frame0->windows_frame_info);
 219  }
 220
 221  {  // To avoid reusing locals by mistake
 222    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
 223    EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
 224    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
 225               | StackFrameX86::CONTEXT_VALID_ESP
 226               | StackFrameX86::CONTEXT_VALID_EBP),
 227              frame1->context_validity);
 228    EXPECT_EQ(0x40008679U, frame1->instruction + 1);
 229    EXPECT_EQ(0x40008679U, frame1->context.eip);
 230    EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
 231    EXPECT_EQ(NULL, frame1->windows_frame_info);
 232  }
 233}
 234
 235// Walk a traditional frame, but use a bogus %ebp value, forcing a scan
 236// of the stack for something that looks like a return address.
 237TEST_F(GetCallerFrame, TraditionalScan) {
 238  stack_section.start() = 0x80000000;
 239  Label frame1_ebp;
 240  stack_section
 241    // frame 0
 242    .D32(0xf065dc76)    // locals area:
 243    .D32(0x46ee2167)    // garbage that doesn't look like
 244    .D32(0xbab023ec)    // a return address
 245    .D32(frame1_ebp)    // saved %ebp (%ebp fails to point here, forcing scan)
 246    .D32(0x4000129d)    // return address
 247    // frame 1
 248    .Append(8, 0)       // space
 249    .Mark(&frame1_ebp)  // %ebp points here
 250    .D32(0)             // saved %ebp (stack end)
 251    .D32(0);            // return address (stack end)
 252
 253  RegionFromSection();
 254  raw_context.eip = 0x4000f49d;
 255  raw_context.esp = stack_section.start().Value();
 256  // Make the frame pointer bogus, to make the stackwalker scan the stack
 257  // for something that looks like a return address.
 258  raw_context.ebp = 0xd43eed6e;
 259
 260  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
 261                        &supplier, &resolver);
 262  ASSERT_TRUE(walker.Walk(&call_stack));
 263  frames = call_stack.frames();
 264  ASSERT_EQ(2U, frames->size());
 265
 266  {  // To avoid reusing locals by mistake
 267    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
 268    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
 269    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
 270    EXPECT_EQ(0x4000f49dU, frame0->instruction);
 271    EXPECT_EQ(0x4000f49dU, frame0->context.eip);
 272    EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
 273    EXPECT_EQ(0xd43eed6eU, frame0->context.ebp);
 274    EXPECT_EQ(NULL, frame0->windows_frame_info);
 275  }
 276
 277  {  // To avoid reusing locals by mistake
 278    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
 279    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
 280    // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the
 281    // walker does not actually fetch the EBP after a scan (forcing the
 282    // next frame to be scanned as well). But let's grandfather the existing
 283    // behavior in for now.
 284    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
 285               | StackFrameX86::CONTEXT_VALID_ESP
 286               | StackFrameX86::CONTEXT_VALID_EBP),
 287              frame1->context_validity);
 288    EXPECT_EQ(0x4000129dU, frame1->instruction + 1);
 289    EXPECT_EQ(0x4000129dU, frame1->context.eip);
 290    EXPECT_EQ(0x80000014U, frame1->context.esp);
 291    EXPECT_EQ(0xd43eed6eU, frame1->context.ebp);
 292    EXPECT_EQ(NULL, frame1->windows_frame_info);
 293  }
 294}
 295
 296// Force scanning for a return address a long way down the stack
 297TEST_F(GetCallerFrame, TraditionalScanLongWay) {
 298  stack_section.start() = 0x80000000;
 299  Label frame1_ebp;
 300  stack_section
 301    // frame 0
 302    .D32(0xf065dc76)    // locals area:
 303    .D32(0x46ee2167)    // garbage that doesn't look like
 304    .D32(0xbab023ec)    // a return address
 305    .Append(20 * 4, 0)  // a bunch of space
 306    .D32(frame1_ebp)    // saved %ebp (%ebp fails to point here, forcing scan)
 307    .D32(0x4000129d)    // return address
 308    // frame 1
 309    .Append(8, 0)       // space
 310    .Mark(&frame1_ebp)  // %ebp points here
 311    .D32(0)             // saved %ebp (stack end)
 312    .D32(0);            // return address (stack end)
 313
 314  RegionFromSection();
 315  raw_context.eip = 0x4000f49d;
 316  raw_context.esp = stack_section.start().Value();
 317  // Make the frame pointer bogus, to make the stackwalker scan the stack
 318  // for something that looks like a return address.
 319  raw_context.ebp = 0xd43eed6e;
 320
 321  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
 322                        &supplier, &resolver);
 323  ASSERT_TRUE(walker.Walk(&call_stack));
 324  frames = call_stack.frames();
 325  ASSERT_EQ(2U, frames->size());
 326
 327  {  // To avoid reusing locals by mistake
 328    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
 329    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
 330    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
 331    EXPECT_EQ(0x4000f49dU, frame0->instruction);
 332    EXPECT_EQ(0x4000f49dU, frame0->context.eip);
 333    EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
 334    EXPECT_EQ(0xd43eed6eU, frame0->context.ebp);
 335    EXPECT_EQ(NULL, frame0->windows_frame_info);
 336  }
 337
 338  {  // To avoid reusing locals by mistake
 339    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
 340    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
 341    // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the
 342    // walker does not actually fetch the EBP after a scan (forcing the
 343    // next frame to be scanned as well). But let's grandfather the existing
 344    // behavior in for now.
 345    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
 346               | StackFrameX86::CONTEXT_VALID_ESP
 347               | StackFrameX86::CONTEXT_VALID_EBP),
 348              frame1->context_validity);
 349    EXPECT_EQ(0x4000129dU, frame1->instruction + 1);
 350    EXPECT_EQ(0x4000129dU, frame1->context.eip);
 351    EXPECT_EQ(0x80000064U, frame1->context.esp);
 352    EXPECT_EQ(0xd43eed6eU, frame1->context.ebp);
 353    EXPECT_EQ(NULL, frame1->windows_frame_info);
 354  }
 355}
 356
 357// Use Windows frame data (a "STACK WIN 4" record, from a
 358// FrameTypeFrameData DIA record) to walk a stack frame.
 359TEST_F(GetCallerFrame, WindowsFrameData) {
 360  SetModuleSymbols(&module1,
 361                   "STACK WIN 4 aa85 176 0 0 4 10 4 0 1"
 362                   " $T2 $esp .cbSavedRegs + ="
 363                   " $T0 .raSearchStart ="
 364                   " $eip $T0 ^ ="
 365                   " $esp $T0 4 + ="
 366                   " $ebx $T2 4  - ^ ="
 367                   " $edi $T2 8  - ^ ="
 368                   " $esi $T2 12 - ^ ="
 369                   " $ebp $T2 16 - ^ =\n");
 370  Label frame1_esp, frame1_ebp;
 371  stack_section.start() = 0x80000000;
 372  stack_section
 373    // frame 0
 374    .D32(frame1_ebp)                    // saved regs: %ebp
 375    .D32(0xa7120d1a)                    //             %esi
 376    .D32(0x630891be)                    //             %edi
 377    .D32(0x9068a878)                    //             %ebx
 378    .D32(0xa08ea45f)                    // locals: unused
 379    .D32(0x40001350)                    // return address
 380    // frame 1
 381    .Mark(&frame1_esp)
 382    .Append(12, 0)                      // empty space
 383    .Mark(&frame1_ebp)
 384    .D32(0)                             // saved %ebp (stack end)
 385    .D32(0);                            // saved %eip (stack end)
 386
 387  RegionFromSection();
 388  raw_context.eip = 0x4000aa85;
 389  raw_context.esp = stack_section.start().Value();
 390  raw_context.ebp = 0xf052c1de;         // should not be needed to walk frame
 391
 392  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
 393                        &supplier, &resolver);
 394  ASSERT_TRUE(walker.Walk(&call_stack));
 395  frames = call_stack.frames();
 396  ASSERT_EQ(2U, frames->size());
 397
 398  {  // To avoid reusing locals by mistake
 399    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
 400    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
 401    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
 402    EXPECT_EQ(0x4000aa85U, frame0->instruction);
 403    EXPECT_EQ(0x4000aa85U, frame0->context.eip);
 404    EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
 405    EXPECT_EQ(0xf052c1deU, frame0->context.ebp);
 406    EXPECT_TRUE(frame0->windows_frame_info != NULL);
 407  }
 408
 409  {  // To avoid reusing locals by mistake
 410    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
 411    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
 412    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
 413               | StackFrameX86::CONTEXT_VALID_ESP
 414               | StackFrameX86::CONTEXT_VALID_EBP
 415               | StackFrameX86::CONTEXT_VALID_EBX
 416               | StackFrameX86::CONTEXT_VALID_ESI
 417               | StackFrameX86::CONTEXT_VALID_EDI),
 418              frame1->context_validity);
 419    EXPECT_EQ(0x40001350U, frame1->instruction + 1);
 420    EXPECT_EQ(0x40001350U, frame1->context.eip);
 421    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
 422    EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
 423    EXPECT_EQ(0x9068a878U, frame1->context.ebx);
 424    EXPECT_EQ(0xa7120d1aU, frame1->context.esi);
 425    EXPECT_EQ(0x630891beU, frame1->context.edi);
 426    EXPECT_EQ(NULL, frame1->windows_frame_info);
 427  }
 428}
 429
 430// Use Windows frame data (a "STACK WIN 4" record, from a
 431// FrameTypeFrameData DIA record) to walk a stack frame where the stack
 432// is aligned and we must search
 433TEST_F(GetCallerFrame, WindowsFrameDataAligned) {
 434  SetModuleSymbols(&module1,
 435                   "STACK WIN 4 aa85 176 0 0 4 4 8 0 1"
 436		   " $T1 .raSearch ="
 437		   " $T0 $T1 4 - 8 @ ="
 438		   " $ebp $T1 4 - ^ ="
 439		   " $eip $T1 ^ ="
 440		   " $esp $T1 4 + =");
 441  Label frame1_esp, frame1_ebp;
 442  stack_section.start() = 0x80000000;
 443  stack_section
 444    // frame 0
 445    .D32(0x0ffa0ffa)                    // unused saved register
 446    .D32(0xdeaddead)                    // locals
 447    .D32(0xbeefbeef)
 448    .D32(0)                             // 8-byte alignment
 449    .D32(frame1_ebp)
 450    .D32(0x5000129d)                    // return address
 451    // frame 1
 452    .Mark(&frame1_esp)
 453    .D32(0x1)                           // parameter
 454    .Mark(&frame1_ebp)
 455    .D32(0)                             // saved %ebp (stack end)
 456    .D32(0);                            // saved %eip (stack end)
 457
 458  RegionFromSection();
 459  raw_context.eip = 0x4000aa85;
 460  raw_context.esp = stack_section.start().Value();
 461  raw_context.ebp = 0xf052c1de;         // should not be needed to walk frame
 462
 463  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
 464                        &supplier, &resolver);
 465  ASSERT_TRUE(walker.Walk(&call_stack));
 466  frames = call_stack.frames();
 467  ASSERT_EQ(2U, frames->size());
 468
 469  {  // To avoid reusing locals by mistake
 470    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
 471    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
 472    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
 473    EXPECT_EQ(0x4000aa85U, frame0->instruction);
 474    EXPECT_EQ(0x4000aa85U, frame0->context.eip);
 475    EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
 476    EXPECT_EQ(0xf052c1deU, frame0->context.ebp);
 477    EXPECT_TRUE(frame0->windows_frame_info != NULL);
 478  }
 479
 480  {  // To avoid reusing locals by mistake
 481    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
 482    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
 483    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
 484               | StackFrameX86::CONTEXT_VALID_ESP
 485               | StackFrameX86::CONTEXT_VALID_EBP),
 486              frame1->context_validity);
 487    EXPECT_EQ(0x5000129dU, frame1->instruction + 1);
 488    EXPECT_EQ(0x5000129dU, frame1->context.eip);
 489    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
 490    EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
 491    EXPECT_EQ(NULL, frame1->windows_frame_info);
 492  }
 493}
 494
 495// Use Windows frame data (a "STACK WIN 4" record, from a
 496// FrameTypeFrameData DIA record) to walk a frame, and depend on the
 497// parameter size from the callee as well.
 498TEST_F(GetCallerFrame, WindowsFrameDataParameterSize) {
 499  SetModuleSymbols(&module1, "FUNC 1000 100 c module1::wheedle\n");
 500  SetModuleSymbols(&module2,
 501                   // Note bogus parameter size in FUNC record; the stack walker
 502                   // should prefer the STACK WIN record, and see '4' below.
 503                   "FUNC aa85 176 beef module2::whine\n"
 504                   "STACK WIN 4 aa85 176 0 0 4 10 4 0 1"
 505                   " $T2 $esp .cbLocals + .cbSavedRegs + ="
 506                   " $T0 .raSearchStart ="
 507                   " $eip $T0 ^ ="
 508                   " $esp $T0 4 + ="
 509                   " $ebp $T0 20 - ^ ="
 510                   " $ebx $T0 8 - ^ =\n");
 511  Label frame0_esp, frame0_ebp;
 512  Label frame1_esp;
 513  Label frame2_esp, frame2_ebp;
 514  stack_section.start() = 0x80000000;
 515  stack_section
 516    // frame 0, in module1::wheedle.  Traditional frame.
 517    .Mark(&frame0_esp)
 518    .Append(16, 0)      // frame space
 519    .Mark(&frame0_ebp)
 520    .D32(0x6fa902e0)    // saved %ebp.  Not a frame pointer.
 521    .D32(0x5000aa95)    // return address, in module2::whine
 522    // frame 1, in module2::whine.  FrameData frame.
 523    .Mark(&frame1_esp)
 524    .D32(0xbaa0cb7a)    // argument 3 passed to module1::wheedle
 525    .D32(0xbdc92f9f)    // argument 2
 526    .D32(0x0b1d8442)    // argument 1
 527    .D32(frame2_ebp)    // saved %ebp
 528    .D32(0xb1b90a15)    // unused
 529    .D32(0xf18e072d)    // unused
 530    .D32(0x2558c7f3)    // saved %ebx
 531    .D32(0x0365e25e)    // unused
 532    .D32(0x2a179e38)    // return address; $T0 points here
 533    // frame 2, in no module
 534    .Mark(&frame2_esp)
 535    .Append(12, 0)      // empty space
 536    .Mark(&frame2_ebp)
 537    .D32(0)             // saved %ebp (stack end)
 538    .D32(0);            // saved %eip (stack end)
 539
 540  RegionFromSection();
 541  raw_context.eip = 0x40001004; // in module1::wheedle
 542  raw_context.esp = stack_section.start().Value();
 543  raw_context.ebp = frame0_ebp.Value();
 544
 545  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
 546                        &supplier, &resolver);
 547  ASSERT_TRUE(walker.Walk(&call_stack));
 548  frames = call_stack.frames();
 549  ASSERT_EQ(3U, frames->size());
 550
 551  {  // To avoid reusing locals by mistake
 552    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
 553    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
 554    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
 555    EXPECT_EQ(0x40001004U, frame0->instruction);
 556    EXPECT_EQ(0x40001004U, frame0->context.eip);
 557    EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
 558    EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
 559    EXPECT_EQ(&module1, frame0->module);
 560    EXPECT_EQ("module1::wheedle", frame0->function_name);
 561    EXPECT_EQ(0x40001000U, frame0->function_base);
 562    // The FUNC record for module1::wheedle should have produced a
 563    // WindowsFrameInfo structure with only the parameter size valid.
 564    ASSERT_TRUE(frame0->windows_frame_info != NULL);
 565    EXPECT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE,
 566              frame0->windows_frame_info->valid);
 567    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_UNKNOWN,
 568              frame0->windows_frame_info->type_);
 569    EXPECT_EQ(12U, frame0->windows_frame_info->parameter_size);
 570  }
 571
 572  {  // To avoid reusing locals by mistake
 573    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
 574    EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
 575    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
 576               | StackFrameX86::CONTEXT_VALID_ESP
 577               | StackFrameX86::CONTEXT_VALID_EBP),
 578              frame1->context_validity);
 579    EXPECT_EQ(0x5000aa95U, frame1->instruction + 1);
 580    EXPECT_EQ(0x5000aa95U, frame1->context.eip);
 581    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
 582    EXPECT_EQ(0x6fa902e0U, frame1->context.ebp);
 583    EXPECT_EQ(&module2, frame1->module);
 584    EXPECT_EQ("module2::whine", frame1->function_name);
 585    EXPECT_EQ(0x5000aa85U, frame1->function_base);
 586    ASSERT_TRUE(frame1->windows_frame_info != NULL);
 587    EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid);
 588    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
 589              frame1->windows_frame_info->type_);
 590    // This should not see the 0xbeef parameter size from the FUNC
 591    // record, but should instead see the STACK WIN record.
 592    EXPECT_EQ(4U, frame1->windows_frame_info->parameter_size);
 593  }
 594
 595  {  // To avoid reusing locals by mistake
 596    StackFrameX86 *frame2 = static_cast<StackFrameX86 *>(frames->at(2));
 597    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust);
 598    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
 599               | StackFrameX86::CONTEXT_VALID_ESP
 600               | StackFrameX86::CONTEXT_VALID_EBP
 601               | StackFrameX86::CONTEXT_VALID_EBX),
 602              frame2->context_validity);
 603    EXPECT_EQ(0x2a179e38U, frame2->instruction + 1);
 604    EXPECT_EQ(0x2a179e38U, frame2->context.eip);
 605    EXPECT_EQ(frame2_esp.Value(), frame2->context.esp);
 606    EXPECT_EQ(frame2_ebp.Value(), frame2->context.ebp);
 607    EXPECT_EQ(0x2558c7f3U, frame2->context.ebx);
 608    EXPECT_EQ(NULL, frame2->module);
 609    EXPECT_EQ(NULL, frame2->windows_frame_info);
 610  }
 611}
 612
 613// Use Windows frame data (a "STACK WIN 4" record, from a
 614// FrameTypeFrameData DIA record) to walk a stack frame, where the
 615// expression fails to yield both an $eip and an $ebp value, and the stack
 616// walker must scan.
 617TEST_F(GetCallerFrame, WindowsFrameDataScan) {
 618  SetModuleSymbols(&module1,
 619                   "STACK WIN 4 c8c 111 0 0 4 10 4 0 1 bad program string\n");
 620  // Mark frame 1's PC as the end of the stack.
 621  SetModuleSymbols(&module2,
 622                   "FUNC 7c38 accf 0 module2::function\n"
 623                   "STACK WIN 4 7c38 accf 0 0 4 10 4 0 1 $eip 0 = $ebp 0 =\n");
 624  Label frame1_esp;
 625  stack_section.start() = 0x80000000;
 626  stack_section
 627    // frame 0
 628    .Append(16, 0x2a)                   // unused, garbage
 629    .D32(0x50007ce9)                    // return address
 630    // frame 1
 631    .Mark(&frame1_esp)
 632    .Append(8, 0);                      // empty space
 633
 634  RegionFromSection();
 635  raw_context.eip = 0x40000c9c;
 636  raw_context.esp = stack_section.start().Value();
 637  raw_context.ebp = 0x2ae314cd;         // should not be needed to walk frame
 638
 639  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
 640                        &supplier, &resolver);
 641  ASSERT_TRUE(walker.Walk(&call_stack));
 642  frames = call_stack.frames();
 643  ASSERT_EQ(2U, frames->size());
 644
 645  {  // To avoid reusing locals by mistake
 646    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
 647    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
 648    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
 649    EXPECT_EQ(0x40000c9cU, frame0->instruction);
 650    EXPECT_EQ(0x40000c9cU, frame0->context.eip);
 651    EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
 652    EXPECT_EQ(0x2ae314cdU, frame0->context.ebp);
 653    EXPECT_TRUE(frame0->windows_frame_info != NULL);
 654  }
 655
 656  {  // To avoid reusing locals by mistake
 657    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
 658    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
 659    // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the walker
 660    // does not actually fetch the EBP after a scan (forcing the next frame
 661    // to be scanned as well). But let's grandfather the existing behavior in
 662    // for now.
 663    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
 664               | StackFrameX86::CONTEXT_VALID_ESP
 665               | StackFrameX86::CONTEXT_VALID_EBP),
 666              frame1->context_validity);
 667    EXPECT_EQ(0x50007ce9U, frame1->instruction + 1);
 668    EXPECT_EQ(0x50007ce9U, frame1->context.eip);
 669    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
 670    EXPECT_TRUE(frame1->windows_frame_info != NULL);
 671  }
 672}
 673
 674// Use Windows frame data (a "STACK WIN 4" record, from a
 675// FrameTypeFrameData DIA record) to walk a stack frame, where the
 676// expression yields an $eip that falls outside of any module, and the
 677// stack walker must scan.
 678TEST_F(GetCallerFrame, WindowsFrameDataBadEIPScan) {
 679  SetModuleSymbols(&module1,
 680                   "STACK WIN 4 6e6 e7 0 0 0 8 4 0 1"
 681                   // A traditional frame, actually.
 682                   " $eip $ebp 4 + ^ = $esp $ebp 8 + = $ebp $ebp ^ =\n");
 683  // Mark frame 1's PC as the end of the stack.
 684  SetModuleSymbols(&module2,
 685                   "FUNC cfdb 8406 0 module2::function\n"
 686                   "STACK WIN 4 cfdb 8406 0 0 0 0 0 0 1 $eip 0 = $ebp 0 =\n");
 687  stack_section.start() = 0x80000000;
 688
 689  // In this stack, the context's %ebp is pointing at the wrong place, so
 690  // the stack walker needs to scan to find the return address, and then
 691  // scan again to find the caller's saved %ebp.
 692  Label frame0_ebp, frame1_ebp, frame1_esp;
 693  stack_section
 694    // frame 0
 695    .Append(8, 0x2a)            // garbage
 696    .Mark(&frame0_ebp)          // frame 0 %ebp points here, but should point
 697                                // at *** below
 698    // The STACK WIN record says that the following two values are
 699    // frame 1's saved %ebp and return address, but the %ebp is wrong;
 700    // they're garbage. The stack walker will scan for the right values.
 701    .D32(0x3d937b2b)            // alleged to be frame 1's saved %ebp
 702    .D32(0x17847f5b)            // alleged to be frame 1's return address
 703    .D32(frame1_ebp)            // frame 1's real saved %ebp; scan will find
 704    .D32(0x2b2b2b2b)            // first word of realigned register save area
 705    // *** frame 0 %ebp ought to be pointing here
 706    .D32(0x2c2c2c2c)            // realigned locals area
 707    .D32(0x5000d000)            // frame 1's real saved %eip; scan will find
 708    // Frame 1, in module2::function. The STACK WIN record describes
 709    // this as the oldest frame, without referring to its contents, so
 710    // we needn't to provide any actual data here.
 711    .Mark(&frame1_esp)
 712    .Mark(&frame1_ebp)          // frame 1 %ebp points here
 713    // A dummy value for frame 1's %ebp to point at. The scan recognizes the
 714    // saved %ebp because it points to a valid word in the stack memory region.
 715    .D32(0x2d2d2d2d);
 716
 717  RegionFromSection();
 718  raw_context.eip = 0x40000700;
 719  raw_context.esp = stack_section.start().Value();
 720  raw_context.ebp = frame0_ebp.Value();
 721
 722  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
 723                        &supplier, &resolver);
 724  ASSERT_TRUE(walker.Walk(&call_stack));
 725  frames = call_stack.frames();
 726  ASSERT_EQ(2U, frames->size());
 727
 728  {  // To avoid reusing locals by mistake
 729    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
 730    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
 731    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
 732    EXPECT_EQ(0x40000700U, frame0->instruction);
 733    EXPECT_EQ(0x40000700U, frame0->context.eip);
 734    EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
 735    EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
 736    EXPECT_TRUE(frame0->windows_frame_info != NULL);
 737  }
 738
 739  {  // To avoid reusing locals by mistake
 740    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
 741    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI_SCAN, frame1->trust);
 742    // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the
 743    // walker does not actually fetch the EBP after a scan (forcing the
 744    // next frame to be scanned as well). But let's grandfather the existing
 745    // behavior in for now.
 746    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
 747               | StackFrameX86::CONTEXT_VALID_ESP
 748               | StackFrameX86::CONTEXT_VALID_EBP),
 749              frame1->context_validity);
 750    EXPECT_EQ(0x5000d000U, frame1->instruction + 1);
 751    EXPECT_EQ(0x5000d000U, frame1->context.eip);
 752    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
 753    EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
 754    EXPECT_TRUE(frame1->windows_frame_info != NULL);
 755  }
 756}
 757
 758// Use Windows FrameTypeFPO data to walk a stack frame for a function that
 759// does not modify %ebp from the value it had in the caller.
 760TEST_F(GetCallerFrame, WindowsFPOUnchangedEBP) {
 761  SetModuleSymbols(&module1,
 762                   // Note bogus parameter size in FUNC record; the walker
 763                   // should prefer the STACK WIN record, and see the '8' below.
 764                   "FUNC e8a8 100 feeb module1::discombobulated\n"
 765                   "STACK WIN 0 e8a8 100 0 0 8 4 10 0 0 0\n");
 766  Label frame0_esp;
 767  Label frame1_esp, frame1_ebp;
 768  stack_section.start() = 0x80000000;
 769  stack_section
 770    // frame 0, in module1::wheedle.  FrameTypeFPO (STACK WIN 0) frame.
 771    .Mark(&frame0_esp)
 772    // no outgoing parameters; this is the youngest frame.
 773    .D32(0x7c521352)    // four bytes of saved registers
 774    .Append(0x10, 0x42) // local area
 775    .D32(0x40009b5b)    // return address, in module1, no function
 776    // frame 1, in module1, no function.
 777    .Mark(&frame1_esp)
 778    .D32(0xf60ea7fc)    // junk
 779    .Mark(&frame1_ebp)
 780    .D32(0)             // saved %ebp (stack end)
 781    .D32(0);            // saved %eip (stack end)
 782
 783  RegionFromSection();
 784  raw_context.eip = 0x4000e8b8; // in module1::whine
 785  raw_context.esp = stack_section.start().Value();
 786  // Frame pointer unchanged from caller.
 787  raw_context.ebp = frame1_ebp.Value();
 788
 789  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
 790                        &supplier, &resolver);
 791  ASSERT_TRUE(walker.Walk(&call_stack));
 792  frames = call_stack.frames();
 793  ASSERT_EQ(2U, frames->size());
 794
 795  {  // To avoid reusing locals by mistake
 796    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
 797    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
 798    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
 799    EXPECT_EQ(0x4000e8b8U, frame0->instruction);
 800    EXPECT_EQ(0x4000e8b8U, frame0->context.eip);
 801    EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
 802    EXPECT_EQ(frame1_ebp.Value(), frame0->context.ebp); // unchanged from caller
 803    EXPECT_EQ(&module1, frame0->module);
 804    EXPECT_EQ("module1::discombobulated", frame0->function_name);
 805    EXPECT_EQ(0x4000e8a8U, frame0->function_base);
 806    // The STACK WIN record for module1::discombobulated should have
 807    // produced a fully populated WindowsFrameInfo structure.
 808    ASSERT_TRUE(frame0->windows_frame_info != NULL);
 809    EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
 810    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
 811              frame0->windows_frame_info->type_);
 812    EXPECT_EQ(0x10U, frame0->windows_frame_info->local_size);
 813  }
 814
 815  {  // To avoid reusing locals by mistake
 816    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
 817    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
 818    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
 819               | StackFrameX86::CONTEXT_VALID_ESP
 820               | StackFrameX86::CONTEXT_VALID_EBP),
 821              frame1->context_validity);
 822    EXPECT_EQ(0x40009b5bU, frame1->instruction + 1);
 823    EXPECT_EQ(0x40009b5bU, frame1->context.eip);
 824    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
 825    EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
 826    EXPECT_EQ(&module1, frame1->module);
 827    EXPECT_EQ("", frame1->function_name);
 828    EXPECT_EQ(NULL, frame1->windows_frame_info);
 829  }
 830}
 831
 832// Use Windows FrameTypeFPO data to walk a stack frame for a function
 833// that uses %ebp for its own purposes, saving the value it had in the
 834// caller in the standard place in the saved register area.
 835TEST_F(GetCallerFrame, WindowsFPOUsedEBP) {
 836  SetModuleSymbols(&module1,
 837                   // Note bogus parameter size in FUNC record; the walker
 838                   // should prefer the STACK WIN record, and see the '8' below.
 839                   "FUNC 9aa8 e6 abbe module1::RaisedByTheAliens\n"
 840                   "STACK WIN 0 9aa8 e6 a 0 10 8 4 0 0 1\n");
 841  Label frame0_esp;
 842  Label frame1_esp, frame1_ebp;
 843  stack_section.start() = 0x80000000;
 844  stack_section
 845    // frame 0, in module1::wheedle.  FrameTypeFPO (STACK WIN 0) frame.
 846    .Mark(&frame0_esp)
 847    // no outgoing parameters; this is the youngest frame.
 848    .D32(frame1_ebp)    // saved register area: saved %ebp
 849    .D32(0xb68bd5f9)    // saved register area: something else
 850    .D32(0xd25d05fc)    // local area
 851    .D32(0x4000debe)    // return address, in module1, no function
 852    // frame 1, in module1, no function.
 853    .Mark(&frame1_esp)
 854    .D32(0xf0c9a974)    // junk
 855    .Mark(&frame1_ebp)
 856    .D32(0)             // saved %ebp (stack end)
 857    .D32(0);            // saved %eip (stack end)
 858
 859  RegionFromSection();
 860  raw_context.eip = 0x40009ab8; // in module1::RaisedByTheAliens
 861  raw_context.esp = stack_section.start().Value();
 862  // RaisedByTheAliens uses %ebp for its own mysterious purposes.
 863  raw_context.ebp = 0xecbdd1a5;
 864
 865  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
 866                        &supplier, &resolver);
 867  ASSERT_TRUE(walker.Walk(&call_stack));
 868  frames = call_stack.frames();
 869  ASSERT_EQ(2U, frames->size());
 870
 871  {  // To avoid reusing locals by mistake
 872    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
 873    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
 874    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
 875    EXPECT_EQ(0x40009ab8U, frame0->instruction);
 876    EXPECT_EQ(0x40009ab8U, frame0->context.eip);
 877    EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
 878    EXPECT_EQ(0xecbdd1a5, frame0->context.ebp);
 879    EXPECT_EQ(&module1, frame0->module);
 880    EXPECT_EQ("module1::RaisedByTheAliens", frame0->function_name);
 881    EXPECT_EQ(0x40009aa8U, frame0->function_base);
 882    // The STACK WIN record for module1::RaisedByTheAliens should have
 883    // produced a fully populated WindowsFrameInfo structure.
 884    ASSERT_TRUE(frame0->windows_frame_info != NULL);
 885    EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
 886    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
 887              frame0->windows_frame_info->type_);
 888    EXPECT_EQ("", frame0->windows_frame_info->program_string);
 889    EXPECT_TRUE(frame0->windows_frame_info->allocates_base_pointer);
 890  }
 891
 892  {  // To avoid reusing locals by mistake
 893    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
 894    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
 895    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
 896               | StackFrameX86::CONTEXT_VALID_ESP
 897               | StackFrameX86::CONTEXT_VALID_EBP),
 898              frame1->context_validity);
 899    EXPECT_EQ(0x4000debeU, frame1->instruction + 1);
 900    EXPECT_EQ(0x4000debeU, frame1->context.eip);
 901    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
 902    EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
 903    EXPECT_EQ(&module1, frame1->module);
 904    EXPECT_EQ("", frame1->function_name);
 905    EXPECT_EQ(NULL, frame1->windows_frame_info);
 906  }
 907}
 908
 909// This is a regression unit test which covers a bug which has to do with
 910// FPO-optimized Windows system call stubs in the context frame.  There is
 911// a more recent Windows system call dispatch mechanism which differs from
 912// the one which is being tested here.  The newer system call dispatch
 913// mechanism creates an extra context frame (KiFastSystemCallRet).
 914TEST_F(GetCallerFrame, WindowsFPOSystemCall) {
 915  SetModuleSymbols(&module3,  // ntdll.dll
 916                   "PUBLIC 1f8ac c ZwWaitForSingleObject\n"
 917                   "STACK WIN 0 1f8ac 1b 0 0 c 0 0 0 0 0\n");
 918  SetModuleSymbols(&module4,  // kernelbase.dll
 919                   "PUBLIC 109f9 c WaitForSingleObjectEx\n"
 920                   "PUBLIC 36590 0 _except_handler4\n"
 921                   "STACK WIN 4 109f9 df c 0 c c 48 0 1 $T0 $ebp = $eip "
 922                   "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
 923                   "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n"
 924                   "STACK WIN 4 36590 154 17 0 10 0 14 0 1 $T0 $ebp = $eip "
 925                   "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 "
 926                   ".cbSavedRegs - = $P $T0 8 + .cbParams + =\n");
 927  SetModuleSymbols(&module5,  // kernel32.dll
 928                   "PUBLIC 11136 8 WaitForSingleObject\n"
 929                   "PUBLIC 11151 c WaitForSingleObjectExImplementation\n"
 930                   "STACK WIN 4 11136 16 5 0 8 0 0 0 1 $T0 $ebp = $eip "
 931                   "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
 932                   "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n"
 933                   "STACK WIN 4 11151 7a 5 0 c 0 0 0 1 $T0 $ebp = $eip "
 934                   "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
 935                   "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n");
 936  SetModuleSymbols(&module6,  // chrome.dll
 937                   "FILE 7038 some_file_name.h\n"
 938                   "FILE 839776 some_file_name.cc\n"
 939                   "FUNC 217fda 17 4 function_217fda\n"
 940                   "217fda 4 102 839776\n"
 941                   "FUNC 217ff1 a 4 function_217ff1\n"
 942                   "217ff1 0 594 7038\n"
 943                   "217ff1 a 596 7038\n"
 944                   "STACK WIN 0 217ff1 a 0 0 4 0 0 0 0 0\n");
 945
 946  Label frame0_esp, frame1_esp;
 947  Label frame1_ebp, frame2_ebp, frame3_ebp;
 948  stack_section.start() = 0x002ff290;
 949  stack_section
 950    .Mark(&frame0_esp)
 951    .D32(0x771ef8c1)    // EIP in frame 0 (system call)
 952    .D32(0x75fa0a91)    // return address of frame 0
 953    .Mark(&frame1_esp)
 954    .D32(0x000017b0)    // args to child
 955    .D32(0x00000000)
 956    .D32(0x002ff2d8)
 957    .D32(0x88014a2e)
 958    .D32(0x002ff364)
 959    .D32(0x000017b0)
 960    .D32(0x00000000)
 961    .D32(0x00000024)
 962    .D32(0x00000001)
 963    .D32(0x00000000)
 964    .D32(0x00000000)
 965    .D32(0x00000000)
 966    .D32(0x00000000)
 967    .D32(0x00000000)
 968    .D32(0x00000000)
 969    .D32(0x00000000)
 970    .D32(0x9e3b9800)
 971    .D32(0xfffffff7)
 972    .D32(0x00000000)
 973    .D32(0x002ff2a4)
 974    .D32(0x64a07ff1)    // random value to be confused with a return address
 975    .D32(0x002ff8dc)
 976    .D32(0x75fc6590)    // random value to be confused with a return address
 977    .D32(0xfdd2c6ea)
 978    .D32(0x00000000)
 979    .Mark(&frame1_ebp)
 980    .D32(frame2_ebp)    // Child EBP
 981    .D32(0x75741194)    // return address of frame 1
 982    .D32(0x000017b0)    // args to child
 983    .D32(0x0036ee80)
 984    .D32(0x00000000)
 985    .D32(0x65bc7d14)
 986    .Mark(&frame2_ebp)
 987    .D32(frame3_ebp)    // Child EBP
 988    .D32(0x75741148)    // return address of frame 2
 989    .D32(0x000017b0)    // args to child
 990    .D32(0x0036ee80)
 991    .D32(0x00000000)
 992    .Mark(&frame3_ebp)
 993    .D32(0)             // saved %ebp (stack end)
 994    .D32(0);            // saved %eip (stack end)
 995
 996  RegionFromSection();
 997  raw_context.eip = 0x771ef8c1;  // in ntdll::ZwWaitForSingleObject
 998  raw_context.esp = stack_section.start().Value();
 999  ASSERT_TRUE(raw_context.esp == frame0_esp.Value());
1000  raw_context.ebp = frame1_ebp.Value();
1001
1002  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
1003                        &supplier, &resolver);
1004  ASSERT_TRUE(walker.Walk(&call_stack));
1005  frames = call_stack.frames();
1006
1007  ASSERT_EQ(4U, frames->size());
1008
1009  {  // To avoid reusing locals by mistake
1010    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
1011    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
1012    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
1013    EXPECT_EQ(0x771ef8c1U, frame0->instruction);
1014    EXPECT_EQ(0x771ef8c1U, frame0->context.eip);
1015    EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
1016    EXPECT_EQ(frame1_ebp.Value(), frame0->context.ebp);
1017    EXPECT_EQ(&module3, frame0->module);
1018    EXPECT_EQ("ZwWaitForSingleObject", frame0->function_name);
1019    // The STACK WIN record for module3!ZwWaitForSingleObject should have
1020    // produced a fully populated WindowsFrameInfo structure.
1021    ASSERT_TRUE(frame0->windows_frame_info != NULL);
1022    EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
1023    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
1024              frame0->windows_frame_info->type_);
1025    EXPECT_EQ("", frame0->windows_frame_info->program_string);
1026    EXPECT_FALSE(frame0->windows_frame_info->allocates_base_pointer);
1027  }
1028
1029  {  // To avoid reusing locals by mistake
1030    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
1031    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
1032    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
1033               | StackFrameX86::CONTEXT_VALID_ESP
1034               | StackFrameX86::CONTEXT_VALID_EBP),
1035              frame1->context_validity);
1036    EXPECT_EQ(0x75fa0a91U, frame1->instruction + 1);
1037    EXPECT_EQ(0x75fa0a91U, frame1->context.eip);
1038    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
1039    EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
1040    EXPECT_EQ(&module4, frame1->module);
1041    EXPECT_EQ("WaitForSingleObjectEx", frame1->function_name);
1042    // The STACK WIN record for module4!WaitForSingleObjectEx should have
1043    // produced a fully populated WindowsFrameInfo structure.
1044    ASSERT_TRUE(frame1->windows_frame_info != NULL);
1045    EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid);
1046    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
1047              frame1->windows_frame_info->type_);
1048    EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
1049              "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =",
1050              frame1->windows_frame_info->program_string);
1051    EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer);
1052  }
1053}
1054
1055struct CFIFixture: public StackwalkerX86Fixture {
1056  CFIFixture() {
1057    // Provide a bunch of STACK CFI records; individual tests walk to the
1058    // caller from every point in this series, expecting to find the same
1059    // set of register values.
1060    SetModuleSymbols(&module1,
1061                     // The youngest frame's function.
1062                     "FUNC 4000 1000 10 enchiridion\n"
1063                     // Initially, just a return address.
1064                     "STACK CFI INIT 4000 100 .cfa: $esp 4 + .ra: .cfa 4 - ^\n"
1065                     // Push %ebx.
1066                     "STACK CFI 4001 .cfa: $esp 8 + $ebx: .cfa 8 - ^\n"
1067                     // Move %esi into %ebx.  Weird, but permitted.
1068                     "STACK CFI 4002 $esi: $ebx\n"
1069                     // Allocate frame space, and save %edi.
1070                     "STACK CFI 4003 .cfa: $esp 20 + $edi: .cfa 16 - ^\n"
1071                     // Put the return address in %edi.
1072                     "STACK CFI 4005 .ra: $edi\n"
1073                     // Save %ebp, and use it as a frame pointer.
1074                     "STACK CFI 4006 .cfa: $ebp 8 + $ebp: .cfa 12 - ^\n"
1075
1076                     // The calling function.
1077                     "FUNC 5000 1000 10 epictetus\n"
1078                     // Mark it as end of stack.
1079                     "STACK CFI INIT 5000 1000 .cfa: $esp .ra 0\n");
1080
1081    // Provide some distinctive values for the caller's registers.
1082    expected.esp = 0x80000000;
1083    expected.eip = 0x40005510;
1084    expected.ebp = 0xc0d4aab9;
1085    expected.ebx = 0x60f20ce6;
1086    expected.esi = 0x53d1379d;
1087    expected.edi = 0xafbae234;
1088
1089    // By default, registers are unchanged.
1090    raw_context = expected;
1091  }
1092
1093  // Walk the stack, using stack_section as the contents of the stack
1094  // and raw_context as the current register values. (Set
1095  // raw_context.esp to the stack's starting address.) Expect two
1096  // stack frames; in the older frame, expect the callee-saves
1097  // registers to have values matching those in 'expected'.
1098  void CheckWalk() {
1099    RegionFromSection();
1100    raw_context.esp = stack_section.start().Value();
1101
1102    StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
1103                          &supplier, &resolver);
1104    ASSERT_TRUE(walker.Walk(&call_stack));
1105    frames = call_stack.frames();
1106    ASSERT_EQ(2U, frames->size());
1107
1108    {  // To avoid reusing locals by mistake
1109      StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
1110      EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
1111      ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
1112      EXPECT_EQ("enchiridion", frame0->function_name);
1113      EXPECT_EQ(0x40004000U, frame0->function_base);
1114      ASSERT_TRUE(frame0->windows_frame_info != NULL);
1115      ASSERT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE,
1116                frame0->windows_frame_info->valid);
1117      ASSERT_TRUE(frame0->cfi_frame_info != NULL);
1118    }
1119
1120    {  // To avoid reusing locals by mistake
1121      StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
1122      EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
1123      ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
1124                 StackFrameX86::CONTEXT_VALID_ESP |
1125                 StackFrameX86::CONTEXT_VALID_EBP |
1126                 StackFrameX86::CONTEXT_VALID_EBX |
1127                 StackFrameX86::CONTEXT_VALID_ESI |
1128                 StackFrameX86::CONTEXT_VALID_EDI),
1129                 frame1->context_validity);
1130      EXPECT_EQ(expected.eip, frame1->context.eip);
1131      EXPECT_EQ(expected.esp, frame1->context.esp);
1132      EXPECT_EQ(expected.ebp, frame1->context.ebp);
1133      EXPECT_EQ(expected.ebx, frame1->context.ebx);
1134      EXPECT_EQ(expected.esi, frame1->context.esi);
1135      EXPECT_EQ(expected.edi, frame1->context.edi);
1136      EXPECT_EQ("epictetus", frame1->function_name);
1137    }
1138  }
1139
1140  // The values the stack walker should find for the caller…

Large files files are truncated, but you can click here to view the full file