toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86_unittest.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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.
    30 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
    32 // stackwalker_x86_unittest.cc: Unit tests for StackwalkerX86 class.
    34 #include <string>
    35 #include <vector>
    37 #include "breakpad_googletest_includes.h"
    38 #include "common/test_assembler.h"
    39 #include "common/using_std_string.h"
    40 #include "google_breakpad/common/minidump_format.h"
    41 #include "google_breakpad/processor/basic_source_line_resolver.h"
    42 #include "google_breakpad/processor/call_stack.h"
    43 #include "google_breakpad/processor/code_module.h"
    44 #include "google_breakpad/processor/source_line_resolver_interface.h"
    45 #include "google_breakpad/processor/stack_frame_cpu.h"
    46 #include "processor/stackwalker_unittest_utils.h"
    47 #include "processor/stackwalker_x86.h"
    48 #include "processor/windows_frame_info.h"
    50 using google_breakpad::BasicSourceLineResolver;
    51 using google_breakpad::CallStack;
    52 using google_breakpad::CodeModule;
    53 using google_breakpad::StackFrameSymbolizer;
    54 using google_breakpad::StackFrame;
    55 using google_breakpad::StackFrameX86;
    56 using google_breakpad::StackwalkerX86;
    57 using google_breakpad::SystemInfo;
    58 using google_breakpad::WindowsFrameInfo;
    59 using google_breakpad::test_assembler::kLittleEndian;
    60 using google_breakpad::test_assembler::Label;
    61 using google_breakpad::test_assembler::Section;
    62 using std::vector;
    63 using testing::_;
    64 using testing::Return;
    65 using testing::SetArgumentPointee;
    66 using testing::Test;
    68 class StackwalkerX86Fixture {
    69  public:
    70   StackwalkerX86Fixture()
    71     : stack_section(kLittleEndian),
    72       // Give the two modules reasonable standard locations and names
    73       // for tests to play with.
    74       module1(0x40000000, 0x10000, "module1", "version1"),
    75       module2(0x50000000, 0x10000, "module2", "version2"),
    76       module3(0x771d0000, 0x180000, "module3", "version3"),
    77       module4(0x75f90000, 0x46000, "module4", "version4"),
    78       module5(0x75730000, 0x110000, "module5", "version5"),
    79       module6(0x647f0000, 0x1ba8000, "module6", "version6") {
    80     // Identify the system as a Linux system.
    81     system_info.os = "Linux";
    82     system_info.os_short = "linux";
    83     system_info.os_version = "Salacious Skink";
    84     system_info.cpu = "x86";
    85     system_info.cpu_info = "";
    87     // Put distinctive values in the raw CPU context.
    88     BrandContext(&raw_context);
    90     // Create some modules with some stock debugging information.
    91     modules.Add(&module1);
    92     modules.Add(&module2);
    93     modules.Add(&module3);
    94     modules.Add(&module4);
    95     modules.Add(&module5);
    96     modules.Add(&module6);
    98     // By default, none of the modules have symbol info; call
    99     // SetModuleSymbols to override this.
   100     EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _))
   101       .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND));
   102   }
   104   // Set the Breakpad symbol information that supplier should return for
   105   // MODULE to INFO.
   106   void SetModuleSymbols(MockCodeModule *module, const string &info) {
   107     char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info);
   108     EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _))
   109       .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer),
   110                             Return(MockSymbolSupplier::FOUND)));
   111   }
   113   // Populate stack_region with the contents of stack_section. Use
   114   // stack_section.start() as the region's starting address.
   115   void RegionFromSection() {
   116     string contents;
   117     ASSERT_TRUE(stack_section.GetContents(&contents));
   118     stack_region.Init(stack_section.start().Value(), contents);
   119   }
   121   // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking.
   122   void BrandContext(MDRawContextX86 *raw_context) {
   123     uint8_t x = 173;
   124     for (size_t i = 0; i < sizeof(*raw_context); i++)
   125       reinterpret_cast<uint8_t *>(raw_context)[i] = (x += 17);
   126   }
   128   SystemInfo system_info;
   129   MDRawContextX86 raw_context;
   130   Section stack_section;
   131   MockMemoryRegion stack_region;
   132   MockCodeModule module1;
   133   MockCodeModule module2;
   134   MockCodeModule module3;
   135   MockCodeModule module4;
   136   MockCodeModule module5;
   137   MockCodeModule module6;
   138   MockCodeModules modules;
   139   MockSymbolSupplier supplier;
   140   BasicSourceLineResolver resolver;
   141   CallStack call_stack;
   142   const vector<StackFrame *> *frames;
   143 };
   145 class SanityCheck: public StackwalkerX86Fixture, public Test { };
   147 TEST_F(SanityCheck, NoResolver) {
   148   stack_section.start() = 0x80000000;
   149   stack_section.D32(0).D32(0); // end-of-stack marker
   150   RegionFromSection();
   151   raw_context.eip = 0x40000200;
   152   raw_context.ebp = 0x80000000;
   154   StackFrameSymbolizer frame_symbolizer(NULL, NULL);
   155   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
   156                         &frame_symbolizer);
   157   // This should succeed, even without a resolver or supplier.
   158   vector<const CodeModule*> modules_without_symbols;
   159   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
   160   ASSERT_EQ(1U, modules_without_symbols.size());
   161   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   162   frames = call_stack.frames();
   163   StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
   164   // Check that the values from the original raw context made it
   165   // through to the context in the stack frame.
   166   EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
   167 }
   169 class GetContextFrame: public StackwalkerX86Fixture, public Test { };
   171 TEST_F(GetContextFrame, Simple) {
   172   stack_section.start() = 0x80000000;
   173   stack_section.D32(0).D32(0); // end-of-stack marker
   174   RegionFromSection();
   175   raw_context.eip = 0x40000200;
   176   raw_context.ebp = 0x80000000;
   178   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   179   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
   180                         &frame_symbolizer);
   181   vector<const CodeModule*> modules_without_symbols;
   182   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
   183   ASSERT_EQ(1U, modules_without_symbols.size());
   184   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   185   frames = call_stack.frames();
   186   StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
   187   // Check that the values from the original raw context made it
   188   // through to the context in the stack frame.
   189   EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
   190 }
   192 // The stackwalker should be able to produce the context frame even
   193 // without stack memory present.
   194 TEST_F(GetContextFrame, NoStackMemory) {
   195   raw_context.eip = 0x40000200;
   196   raw_context.ebp = 0x80000000;
   198   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   199   StackwalkerX86 walker(&system_info, &raw_context, NULL, &modules,
   200                         &frame_symbolizer);
   201   vector<const CodeModule*> modules_without_symbols;
   202   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
   203   ASSERT_EQ(1U, modules_without_symbols.size());
   204   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   205   frames = call_stack.frames();
   206   StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
   207   // Check that the values from the original raw context made it
   208   // through to the context in the stack frame.
   209   EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
   210 }
   212 class GetCallerFrame: public StackwalkerX86Fixture, public Test { };
   214 // Walk a traditional frame. A traditional frame saves the caller's
   215 // %ebp just below the return address, and has its own %ebp pointing
   216 // at the saved %ebp.
   217 TEST_F(GetCallerFrame, Traditional) {
   218   stack_section.start() = 0x80000000;
   219   Label frame0_ebp, frame1_ebp;
   220   stack_section
   221     .Append(12, 0)                      // frame 0: space
   222     .Mark(&frame0_ebp)                  // frame 0 %ebp points here
   223     .D32(frame1_ebp)                    // frame 0: saved %ebp
   224     .D32(0x40008679)                    // frame 0: return address
   225     .Append(8, 0)                       // frame 1: space
   226     .Mark(&frame1_ebp)                  // frame 1 %ebp points here
   227     .D32(0)                             // frame 1: saved %ebp (stack end)
   228     .D32(0);                            // frame 1: return address (stack end)
   229   RegionFromSection();
   230   raw_context.eip = 0x4000c7a5;
   231   raw_context.esp = stack_section.start().Value();
   232   raw_context.ebp = frame0_ebp.Value();
   234   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   235   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
   236                         &frame_symbolizer);
   237   vector<const CodeModule*> modules_without_symbols;
   238   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
   239   ASSERT_EQ(1U, modules_without_symbols.size());
   240   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   241   frames = call_stack.frames();
   242   ASSERT_EQ(2U, frames->size());
   244   {  // To avoid reusing locals by mistake
   245     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
   246     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
   247     EXPECT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
   248     EXPECT_EQ(0x4000c7a5U, frame0->instruction);
   249     EXPECT_EQ(0x4000c7a5U, frame0->context.eip);
   250     EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
   251     EXPECT_EQ(NULL, frame0->windows_frame_info);
   252   }
   254   {  // To avoid reusing locals by mistake
   255     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
   256     EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
   257     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
   258                | StackFrameX86::CONTEXT_VALID_ESP
   259                | StackFrameX86::CONTEXT_VALID_EBP),
   260               frame1->context_validity);
   261     EXPECT_EQ(0x40008679U, frame1->instruction + 1);
   262     EXPECT_EQ(0x40008679U, frame1->context.eip);
   263     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
   264     EXPECT_EQ(NULL, frame1->windows_frame_info);
   265   }
   266 }
   268 // Walk a traditional frame, but use a bogus %ebp value, forcing a scan
   269 // of the stack for something that looks like a return address.
   270 TEST_F(GetCallerFrame, TraditionalScan) {
   271   stack_section.start() = 0x80000000;
   272   Label frame1_ebp;
   273   stack_section
   274     // frame 0
   275     .D32(0xf065dc76)    // locals area:
   276     .D32(0x46ee2167)    // garbage that doesn't look like
   277     .D32(0xbab023ec)    // a return address
   278     .D32(frame1_ebp)    // saved %ebp (%ebp fails to point here, forcing scan)
   279     .D32(0x4000129d)    // return address
   280     // frame 1
   281     .Append(8, 0)       // space
   282     .Mark(&frame1_ebp)  // %ebp points here
   283     .D32(0)             // saved %ebp (stack end)
   284     .D32(0);            // return address (stack end)
   286   RegionFromSection();
   287   raw_context.eip = 0x4000f49d;
   288   raw_context.esp = stack_section.start().Value();
   289   // Make the frame pointer bogus, to make the stackwalker scan the stack
   290   // for something that looks like a return address.
   291   raw_context.ebp = 0xd43eed6e;
   293   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   294   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
   295                         &frame_symbolizer);
   296   vector<const CodeModule*> modules_without_symbols;
   297   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
   298   ASSERT_EQ(1U, modules_without_symbols.size());
   299   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   300   frames = call_stack.frames();
   301   ASSERT_EQ(2U, frames->size());
   303   {  // To avoid reusing locals by mistake
   304     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
   305     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
   306     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
   307     EXPECT_EQ(0x4000f49dU, frame0->instruction);
   308     EXPECT_EQ(0x4000f49dU, frame0->context.eip);
   309     EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
   310     EXPECT_EQ(0xd43eed6eU, frame0->context.ebp);
   311     EXPECT_EQ(NULL, frame0->windows_frame_info);
   312   }
   314   {  // To avoid reusing locals by mistake
   315     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
   316     EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
   317     // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the
   318     // walker does not actually fetch the EBP after a scan (forcing the
   319     // next frame to be scanned as well). But let's grandfather the existing
   320     // behavior in for now.
   321     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
   322                | StackFrameX86::CONTEXT_VALID_ESP
   323                | StackFrameX86::CONTEXT_VALID_EBP),
   324               frame1->context_validity);
   325     EXPECT_EQ(0x4000129dU, frame1->instruction + 1);
   326     EXPECT_EQ(0x4000129dU, frame1->context.eip);
   327     EXPECT_EQ(0x80000014U, frame1->context.esp);
   328     EXPECT_EQ(0xd43eed6eU, frame1->context.ebp);
   329     EXPECT_EQ(NULL, frame1->windows_frame_info);
   330   }
   331 }
   333 // Force scanning for a return address a long way down the stack
   334 TEST_F(GetCallerFrame, TraditionalScanLongWay) {
   335   stack_section.start() = 0x80000000;
   336   Label frame1_ebp;
   337   stack_section
   338     // frame 0
   339     .D32(0xf065dc76)    // locals area:
   340     .D32(0x46ee2167)    // garbage that doesn't look like
   341     .D32(0xbab023ec)    // a return address
   342     .Append(20 * 4, 0)  // a bunch of space
   343     .D32(frame1_ebp)    // saved %ebp (%ebp fails to point here, forcing scan)
   344     .D32(0x4000129d)    // return address
   345     // frame 1
   346     .Append(8, 0)       // space
   347     .Mark(&frame1_ebp)  // %ebp points here
   348     .D32(0)             // saved %ebp (stack end)
   349     .D32(0);            // return address (stack end)
   351   RegionFromSection();
   352   raw_context.eip = 0x4000f49d;
   353   raw_context.esp = stack_section.start().Value();
   354   // Make the frame pointer bogus, to make the stackwalker scan the stack
   355   // for something that looks like a return address.
   356   raw_context.ebp = 0xd43eed6e;
   358   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   359   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
   360                         &frame_symbolizer);
   361   vector<const CodeModule*> modules_without_symbols;
   362   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
   363   ASSERT_EQ(1U, modules_without_symbols.size());
   364   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
   365   frames = call_stack.frames();
   366   ASSERT_EQ(2U, frames->size());
   368   {  // To avoid reusing locals by mistake
   369     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
   370     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
   371     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
   372     EXPECT_EQ(0x4000f49dU, frame0->instruction);
   373     EXPECT_EQ(0x4000f49dU, frame0->context.eip);
   374     EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
   375     EXPECT_EQ(0xd43eed6eU, frame0->context.ebp);
   376     EXPECT_EQ(NULL, frame0->windows_frame_info);
   377   }
   379   {  // To avoid reusing locals by mistake
   380     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
   381     EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
   382     // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the
   383     // walker does not actually fetch the EBP after a scan (forcing the
   384     // next frame to be scanned as well). But let's grandfather the existing
   385     // behavior in for now.
   386     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
   387                | StackFrameX86::CONTEXT_VALID_ESP
   388                | StackFrameX86::CONTEXT_VALID_EBP),
   389               frame1->context_validity);
   390     EXPECT_EQ(0x4000129dU, frame1->instruction + 1);
   391     EXPECT_EQ(0x4000129dU, frame1->context.eip);
   392     EXPECT_EQ(0x80000064U, frame1->context.esp);
   393     EXPECT_EQ(0xd43eed6eU, frame1->context.ebp);
   394     EXPECT_EQ(NULL, frame1->windows_frame_info);
   395   }
   396 }
   398 // Use Windows frame data (a "STACK WIN 4" record, from a
   399 // FrameTypeFrameData DIA record) to walk a stack frame.
   400 TEST_F(GetCallerFrame, WindowsFrameData) {
   401   SetModuleSymbols(&module1,
   402                    "STACK WIN 4 aa85 176 0 0 4 10 4 0 1"
   403                    " $T2 $esp .cbSavedRegs + ="
   404                    " $T0 .raSearchStart ="
   405                    " $eip $T0 ^ ="
   406                    " $esp $T0 4 + ="
   407                    " $ebx $T2 4  - ^ ="
   408                    " $edi $T2 8  - ^ ="
   409                    " $esi $T2 12 - ^ ="
   410                    " $ebp $T2 16 - ^ =\n");
   411   Label frame1_esp, frame1_ebp;
   412   stack_section.start() = 0x80000000;
   413   stack_section
   414     // frame 0
   415     .D32(frame1_ebp)                    // saved regs: %ebp
   416     .D32(0xa7120d1a)                    //             %esi
   417     .D32(0x630891be)                    //             %edi
   418     .D32(0x9068a878)                    //             %ebx
   419     .D32(0xa08ea45f)                    // locals: unused
   420     .D32(0x40001350)                    // return address
   421     // frame 1
   422     .Mark(&frame1_esp)
   423     .Append(12, 0)                      // empty space
   424     .Mark(&frame1_ebp)
   425     .D32(0)                             // saved %ebp (stack end)
   426     .D32(0);                            // saved %eip (stack end)
   428   RegionFromSection();
   429   raw_context.eip = 0x4000aa85;
   430   raw_context.esp = stack_section.start().Value();
   431   raw_context.ebp = 0xf052c1de;         // should not be needed to walk frame
   433   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   434   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
   435                         &frame_symbolizer);
   436   vector<const CodeModule*> modules_without_symbols;
   437   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
   438   ASSERT_EQ(0U, modules_without_symbols.size());
   439   frames = call_stack.frames();
   440   ASSERT_EQ(2U, frames->size());
   442   {  // To avoid reusing locals by mistake
   443     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
   444     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
   445     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
   446     EXPECT_EQ(0x4000aa85U, frame0->instruction);
   447     EXPECT_EQ(0x4000aa85U, frame0->context.eip);
   448     EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
   449     EXPECT_EQ(0xf052c1deU, frame0->context.ebp);
   450     EXPECT_TRUE(frame0->windows_frame_info != NULL);
   451   }
   453   {  // To avoid reusing locals by mistake
   454     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
   455     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
   456     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
   457                | StackFrameX86::CONTEXT_VALID_ESP
   458                | StackFrameX86::CONTEXT_VALID_EBP
   459                | StackFrameX86::CONTEXT_VALID_EBX
   460                | StackFrameX86::CONTEXT_VALID_ESI
   461                | StackFrameX86::CONTEXT_VALID_EDI),
   462               frame1->context_validity);
   463     EXPECT_EQ(0x40001350U, frame1->instruction + 1);
   464     EXPECT_EQ(0x40001350U, frame1->context.eip);
   465     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
   466     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
   467     EXPECT_EQ(0x9068a878U, frame1->context.ebx);
   468     EXPECT_EQ(0xa7120d1aU, frame1->context.esi);
   469     EXPECT_EQ(0x630891beU, frame1->context.edi);
   470     EXPECT_EQ(NULL, frame1->windows_frame_info);
   471   }
   472 }
   474 // Use Windows frame data (a "STACK WIN 4" record, from a
   475 // FrameTypeFrameData DIA record) to walk a stack frame where the stack
   476 // is aligned and we must search
   477 TEST_F(GetCallerFrame, WindowsFrameDataAligned) {
   478   SetModuleSymbols(&module1,
   479                    "STACK WIN 4 aa85 176 0 0 4 4 8 0 1"
   480 		   " $T1 .raSearch ="
   481 		   " $T0 $T1 4 - 8 @ ="
   482 		   " $ebp $T1 4 - ^ ="
   483 		   " $eip $T1 ^ ="
   484 		   " $esp $T1 4 + =");
   485   Label frame1_esp, frame1_ebp;
   486   stack_section.start() = 0x80000000;
   487   stack_section
   488     // frame 0
   489     .D32(0x0ffa0ffa)                    // unused saved register
   490     .D32(0xdeaddead)                    // locals
   491     .D32(0xbeefbeef)
   492     .D32(0)                             // 8-byte alignment
   493     .D32(frame1_ebp)
   494     .D32(0x5000129d)                    // return address
   495     // frame 1
   496     .Mark(&frame1_esp)
   497     .D32(0x1)                           // parameter
   498     .Mark(&frame1_ebp)
   499     .D32(0)                             // saved %ebp (stack end)
   500     .D32(0);                            // saved %eip (stack end)
   502   RegionFromSection();
   503   raw_context.eip = 0x4000aa85;
   504   raw_context.esp = stack_section.start().Value();
   505   raw_context.ebp = 0xf052c1de;         // should not be needed to walk frame
   507   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   508   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
   509                         &frame_symbolizer);
   510   vector<const CodeModule*> modules_without_symbols;
   511   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
   512   ASSERT_EQ(1U, modules_without_symbols.size());
   513   ASSERT_EQ("module2", modules_without_symbols[0]->debug_file());
   514   frames = call_stack.frames();
   515   ASSERT_EQ(2U, frames->size());
   517   {  // To avoid reusing locals by mistake
   518     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
   519     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
   520     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
   521     EXPECT_EQ(0x4000aa85U, frame0->instruction);
   522     EXPECT_EQ(0x4000aa85U, frame0->context.eip);
   523     EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
   524     EXPECT_EQ(0xf052c1deU, frame0->context.ebp);
   525     EXPECT_TRUE(frame0->windows_frame_info != NULL);
   526   }
   528   {  // To avoid reusing locals by mistake
   529     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
   530     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
   531     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
   532                | StackFrameX86::CONTEXT_VALID_ESP
   533                | StackFrameX86::CONTEXT_VALID_EBP),
   534               frame1->context_validity);
   535     EXPECT_EQ(0x5000129dU, frame1->instruction + 1);
   536     EXPECT_EQ(0x5000129dU, frame1->context.eip);
   537     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
   538     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
   539     EXPECT_EQ(NULL, frame1->windows_frame_info);
   540   }
   541 }
   543 // Use Windows frame data (a "STACK WIN 4" record, from a
   544 // FrameTypeFrameData DIA record) to walk a frame, and depend on the
   545 // parameter size from the callee as well.
   546 TEST_F(GetCallerFrame, WindowsFrameDataParameterSize) {
   547   SetModuleSymbols(&module1, "FUNC 1000 100 c module1::wheedle\n");
   548   SetModuleSymbols(&module2,
   549                    // Note bogus parameter size in FUNC record; the stack walker
   550                    // should prefer the STACK WIN record, and see '4' below.
   551                    "FUNC aa85 176 beef module2::whine\n"
   552                    "STACK WIN 4 aa85 176 0 0 4 10 4 0 1"
   553                    " $T2 $esp .cbLocals + .cbSavedRegs + ="
   554                    " $T0 .raSearchStart ="
   555                    " $eip $T0 ^ ="
   556                    " $esp $T0 4 + ="
   557                    " $ebp $T0 20 - ^ ="
   558                    " $ebx $T0 8 - ^ =\n");
   559   Label frame0_esp, frame0_ebp;
   560   Label frame1_esp;
   561   Label frame2_esp, frame2_ebp;
   562   stack_section.start() = 0x80000000;
   563   stack_section
   564     // frame 0, in module1::wheedle.  Traditional frame.
   565     .Mark(&frame0_esp)
   566     .Append(16, 0)      // frame space
   567     .Mark(&frame0_ebp)
   568     .D32(0x6fa902e0)    // saved %ebp.  Not a frame pointer.
   569     .D32(0x5000aa95)    // return address, in module2::whine
   570     // frame 1, in module2::whine.  FrameData frame.
   571     .Mark(&frame1_esp)
   572     .D32(0xbaa0cb7a)    // argument 3 passed to module1::wheedle
   573     .D32(0xbdc92f9f)    // argument 2
   574     .D32(0x0b1d8442)    // argument 1
   575     .D32(frame2_ebp)    // saved %ebp
   576     .D32(0xb1b90a15)    // unused
   577     .D32(0xf18e072d)    // unused
   578     .D32(0x2558c7f3)    // saved %ebx
   579     .D32(0x0365e25e)    // unused
   580     .D32(0x2a179e38)    // return address; $T0 points here
   581     // frame 2, in no module
   582     .Mark(&frame2_esp)
   583     .Append(12, 0)      // empty space
   584     .Mark(&frame2_ebp)
   585     .D32(0)             // saved %ebp (stack end)
   586     .D32(0);            // saved %eip (stack end)
   588   RegionFromSection();
   589   raw_context.eip = 0x40001004; // in module1::wheedle
   590   raw_context.esp = stack_section.start().Value();
   591   raw_context.ebp = frame0_ebp.Value();
   593   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   594   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
   595                         &frame_symbolizer);
   596   vector<const CodeModule*> modules_without_symbols;
   597   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
   598   ASSERT_EQ(0U, modules_without_symbols.size());
   599   frames = call_stack.frames();
   600   ASSERT_EQ(3U, frames->size());
   602   {  // To avoid reusing locals by mistake
   603     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
   604     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
   605     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
   606     EXPECT_EQ(0x40001004U, frame0->instruction);
   607     EXPECT_EQ(0x40001004U, frame0->context.eip);
   608     EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
   609     EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
   610     EXPECT_EQ(&module1, frame0->module);
   611     EXPECT_EQ("module1::wheedle", frame0->function_name);
   612     EXPECT_EQ(0x40001000U, frame0->function_base);
   613     // The FUNC record for module1::wheedle should have produced a
   614     // WindowsFrameInfo structure with only the parameter size valid.
   615     ASSERT_TRUE(frame0->windows_frame_info != NULL);
   616     EXPECT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE,
   617               frame0->windows_frame_info->valid);
   618     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_UNKNOWN,
   619               frame0->windows_frame_info->type_);
   620     EXPECT_EQ(12U, frame0->windows_frame_info->parameter_size);
   621   }
   623   {  // To avoid reusing locals by mistake
   624     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
   625     EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
   626     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
   627                | StackFrameX86::CONTEXT_VALID_ESP
   628                | StackFrameX86::CONTEXT_VALID_EBP),
   629               frame1->context_validity);
   630     EXPECT_EQ(0x5000aa95U, frame1->instruction + 1);
   631     EXPECT_EQ(0x5000aa95U, frame1->context.eip);
   632     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
   633     EXPECT_EQ(0x6fa902e0U, frame1->context.ebp);
   634     EXPECT_EQ(&module2, frame1->module);
   635     EXPECT_EQ("module2::whine", frame1->function_name);
   636     EXPECT_EQ(0x5000aa85U, frame1->function_base);
   637     ASSERT_TRUE(frame1->windows_frame_info != NULL);
   638     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid);
   639     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
   640               frame1->windows_frame_info->type_);
   641     // This should not see the 0xbeef parameter size from the FUNC
   642     // record, but should instead see the STACK WIN record.
   643     EXPECT_EQ(4U, frame1->windows_frame_info->parameter_size);
   644   }
   646   {  // To avoid reusing locals by mistake
   647     StackFrameX86 *frame2 = static_cast<StackFrameX86 *>(frames->at(2));
   648     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust);
   649     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
   650                | StackFrameX86::CONTEXT_VALID_ESP
   651                | StackFrameX86::CONTEXT_VALID_EBP
   652                | StackFrameX86::CONTEXT_VALID_EBX),
   653               frame2->context_validity);
   654     EXPECT_EQ(0x2a179e38U, frame2->instruction + 1);
   655     EXPECT_EQ(0x2a179e38U, frame2->context.eip);
   656     EXPECT_EQ(frame2_esp.Value(), frame2->context.esp);
   657     EXPECT_EQ(frame2_ebp.Value(), frame2->context.ebp);
   658     EXPECT_EQ(0x2558c7f3U, frame2->context.ebx);
   659     EXPECT_EQ(NULL, frame2->module);
   660     EXPECT_EQ(NULL, frame2->windows_frame_info);
   661   }
   662 }
   664 // Use Windows frame data (a "STACK WIN 4" record, from a
   665 // FrameTypeFrameData DIA record) to walk a stack frame, where the
   666 // expression fails to yield both an $eip and an $ebp value, and the stack
   667 // walker must scan.
   668 TEST_F(GetCallerFrame, WindowsFrameDataScan) {
   669   SetModuleSymbols(&module1,
   670                    "STACK WIN 4 c8c 111 0 0 4 10 4 0 1 bad program string\n");
   671   // Mark frame 1's PC as the end of the stack.
   672   SetModuleSymbols(&module2,
   673                    "FUNC 7c38 accf 0 module2::function\n"
   674                    "STACK WIN 4 7c38 accf 0 0 4 10 4 0 1 $eip 0 = $ebp 0 =\n");
   675   Label frame1_esp;
   676   stack_section.start() = 0x80000000;
   677   stack_section
   678     // frame 0
   679     .Append(16, 0x2a)                   // unused, garbage
   680     .D32(0x50007ce9)                    // return address
   681     // frame 1
   682     .Mark(&frame1_esp)
   683     .Append(8, 0);                      // empty space
   685   RegionFromSection();
   686   raw_context.eip = 0x40000c9c;
   687   raw_context.esp = stack_section.start().Value();
   688   raw_context.ebp = 0x2ae314cd;         // should not be needed to walk frame
   690   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   691   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
   692                         &frame_symbolizer);
   693   vector<const CodeModule*> modules_without_symbols;
   694   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
   695   ASSERT_EQ(0U, modules_without_symbols.size());
   696   frames = call_stack.frames();
   697   ASSERT_EQ(2U, frames->size());
   699   {  // To avoid reusing locals by mistake
   700     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
   701     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
   702     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
   703     EXPECT_EQ(0x40000c9cU, frame0->instruction);
   704     EXPECT_EQ(0x40000c9cU, frame0->context.eip);
   705     EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
   706     EXPECT_EQ(0x2ae314cdU, frame0->context.ebp);
   707     EXPECT_TRUE(frame0->windows_frame_info != NULL);
   708   }
   710   {  // To avoid reusing locals by mistake
   711     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
   712     EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
   713     // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the walker
   714     // does not actually fetch the EBP after a scan (forcing the next frame
   715     // to be scanned as well). But let's grandfather the existing behavior in
   716     // for now.
   717     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
   718                | StackFrameX86::CONTEXT_VALID_ESP
   719                | StackFrameX86::CONTEXT_VALID_EBP),
   720               frame1->context_validity);
   721     EXPECT_EQ(0x50007ce9U, frame1->instruction + 1);
   722     EXPECT_EQ(0x50007ce9U, frame1->context.eip);
   723     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
   724     EXPECT_TRUE(frame1->windows_frame_info != NULL);
   725   }
   726 }
   728 // Use Windows frame data (a "STACK WIN 4" record, from a
   729 // FrameTypeFrameData DIA record) to walk a stack frame, where the
   730 // expression yields an $eip that falls outside of any module, and the
   731 // stack walker must scan.
   732 TEST_F(GetCallerFrame, WindowsFrameDataBadEIPScan) {
   733   SetModuleSymbols(&module1,
   734                    "STACK WIN 4 6e6 e7 0 0 0 8 4 0 1"
   735                    // A traditional frame, actually.
   736                    " $eip $ebp 4 + ^ = $esp $ebp 8 + = $ebp $ebp ^ =\n");
   737   // Mark frame 1's PC as the end of the stack.
   738   SetModuleSymbols(&module2,
   739                    "FUNC cfdb 8406 0 module2::function\n"
   740                    "STACK WIN 4 cfdb 8406 0 0 0 0 0 0 1 $eip 0 = $ebp 0 =\n");
   741   stack_section.start() = 0x80000000;
   743   // In this stack, the context's %ebp is pointing at the wrong place, so
   744   // the stack walker needs to scan to find the return address, and then
   745   // scan again to find the caller's saved %ebp.
   746   Label frame0_ebp, frame1_ebp, frame1_esp;
   747   stack_section
   748     // frame 0
   749     .Append(8, 0x2a)            // garbage
   750     .Mark(&frame0_ebp)          // frame 0 %ebp points here, but should point
   751                                 // at *** below
   752     // The STACK WIN record says that the following two values are
   753     // frame 1's saved %ebp and return address, but the %ebp is wrong;
   754     // they're garbage. The stack walker will scan for the right values.
   755     .D32(0x3d937b2b)            // alleged to be frame 1's saved %ebp
   756     .D32(0x17847f5b)            // alleged to be frame 1's return address
   757     .D32(frame1_ebp)            // frame 1's real saved %ebp; scan will find
   758     .D32(0x2b2b2b2b)            // first word of realigned register save area
   759     // *** frame 0 %ebp ought to be pointing here
   760     .D32(0x2c2c2c2c)            // realigned locals area
   761     .D32(0x5000d000)            // frame 1's real saved %eip; scan will find
   762     // Frame 1, in module2::function. The STACK WIN record describes
   763     // this as the oldest frame, without referring to its contents, so
   764     // we needn't to provide any actual data here.
   765     .Mark(&frame1_esp)
   766     .Mark(&frame1_ebp)          // frame 1 %ebp points here
   767     // A dummy value for frame 1's %ebp to point at. The scan recognizes the
   768     // saved %ebp because it points to a valid word in the stack memory region.
   769     .D32(0x2d2d2d2d);
   771   RegionFromSection();
   772   raw_context.eip = 0x40000700;
   773   raw_context.esp = stack_section.start().Value();
   774   raw_context.ebp = frame0_ebp.Value();
   776   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   777   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
   778                         &frame_symbolizer);
   779   vector<const CodeModule*> modules_without_symbols;
   780   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
   781   ASSERT_EQ(0U, modules_without_symbols.size());
   782   frames = call_stack.frames();
   783   ASSERT_EQ(2U, frames->size());
   785   {  // To avoid reusing locals by mistake
   786     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
   787     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
   788     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
   789     EXPECT_EQ(0x40000700U, frame0->instruction);
   790     EXPECT_EQ(0x40000700U, frame0->context.eip);
   791     EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
   792     EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
   793     EXPECT_TRUE(frame0->windows_frame_info != NULL);
   794   }
   796   {  // To avoid reusing locals by mistake
   797     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
   798     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI_SCAN, frame1->trust);
   799     // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the
   800     // walker does not actually fetch the EBP after a scan (forcing the
   801     // next frame to be scanned as well). But let's grandfather the existing
   802     // behavior in for now.
   803     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
   804                | StackFrameX86::CONTEXT_VALID_ESP
   805                | StackFrameX86::CONTEXT_VALID_EBP),
   806               frame1->context_validity);
   807     EXPECT_EQ(0x5000d000U, frame1->instruction + 1);
   808     EXPECT_EQ(0x5000d000U, frame1->context.eip);
   809     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
   810     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
   811     EXPECT_TRUE(frame1->windows_frame_info != NULL);
   812   }
   813 }
   815 // Use Windows FrameTypeFPO data to walk a stack frame for a function that
   816 // does not modify %ebp from the value it had in the caller.
   817 TEST_F(GetCallerFrame, WindowsFPOUnchangedEBP) {
   818   SetModuleSymbols(&module1,
   819                    // Note bogus parameter size in FUNC record; the walker
   820                    // should prefer the STACK WIN record, and see the '8' below.
   821                    "FUNC e8a8 100 feeb module1::discombobulated\n"
   822                    "STACK WIN 0 e8a8 100 0 0 8 4 10 0 0 0\n");
   823   Label frame0_esp;
   824   Label frame1_esp, frame1_ebp;
   825   stack_section.start() = 0x80000000;
   826   stack_section
   827     // frame 0, in module1::wheedle.  FrameTypeFPO (STACK WIN 0) frame.
   828     .Mark(&frame0_esp)
   829     // no outgoing parameters; this is the youngest frame.
   830     .D32(0x7c521352)    // four bytes of saved registers
   831     .Append(0x10, 0x42) // local area
   832     .D32(0x40009b5b)    // return address, in module1, no function
   833     // frame 1, in module1, no function.
   834     .Mark(&frame1_esp)
   835     .D32(0xf60ea7fc)    // junk
   836     .Mark(&frame1_ebp)
   837     .D32(0)             // saved %ebp (stack end)
   838     .D32(0);            // saved %eip (stack end)
   840   RegionFromSection();
   841   raw_context.eip = 0x4000e8b8; // in module1::whine
   842   raw_context.esp = stack_section.start().Value();
   843   // Frame pointer unchanged from caller.
   844   raw_context.ebp = frame1_ebp.Value();
   846   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   847   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
   848                         &frame_symbolizer);
   849   vector<const CodeModule*> modules_without_symbols;
   850   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
   851   ASSERT_EQ(0U, modules_without_symbols.size());
   852   frames = call_stack.frames();
   853   ASSERT_EQ(2U, frames->size());
   855   {  // To avoid reusing locals by mistake
   856     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
   857     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
   858     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
   859     EXPECT_EQ(0x4000e8b8U, frame0->instruction);
   860     EXPECT_EQ(0x4000e8b8U, frame0->context.eip);
   861     EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
   862     EXPECT_EQ(frame1_ebp.Value(), frame0->context.ebp); // unchanged from caller
   863     EXPECT_EQ(&module1, frame0->module);
   864     EXPECT_EQ("module1::discombobulated", frame0->function_name);
   865     EXPECT_EQ(0x4000e8a8U, frame0->function_base);
   866     // The STACK WIN record for module1::discombobulated should have
   867     // produced a fully populated WindowsFrameInfo structure.
   868     ASSERT_TRUE(frame0->windows_frame_info != NULL);
   869     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
   870     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
   871               frame0->windows_frame_info->type_);
   872     EXPECT_EQ(0x10U, frame0->windows_frame_info->local_size);
   873   }
   875   {  // To avoid reusing locals by mistake
   876     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
   877     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
   878     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
   879                | StackFrameX86::CONTEXT_VALID_ESP
   880                | StackFrameX86::CONTEXT_VALID_EBP),
   881               frame1->context_validity);
   882     EXPECT_EQ(0x40009b5bU, frame1->instruction + 1);
   883     EXPECT_EQ(0x40009b5bU, frame1->context.eip);
   884     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
   885     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
   886     EXPECT_EQ(&module1, frame1->module);
   887     EXPECT_EQ("", frame1->function_name);
   888     EXPECT_EQ(NULL, frame1->windows_frame_info);
   889   }
   890 }
   892 // Use Windows FrameTypeFPO data to walk a stack frame for a function
   893 // that uses %ebp for its own purposes, saving the value it had in the
   894 // caller in the standard place in the saved register area.
   895 TEST_F(GetCallerFrame, WindowsFPOUsedEBP) {
   896   SetModuleSymbols(&module1,
   897                    // Note bogus parameter size in FUNC record; the walker
   898                    // should prefer the STACK WIN record, and see the '8' below.
   899                    "FUNC 9aa8 e6 abbe module1::RaisedByTheAliens\n"
   900                    "STACK WIN 0 9aa8 e6 a 0 10 8 4 0 0 1\n");
   901   Label frame0_esp;
   902   Label frame1_esp, frame1_ebp;
   903   stack_section.start() = 0x80000000;
   904   stack_section
   905     // frame 0, in module1::wheedle.  FrameTypeFPO (STACK WIN 0) frame.
   906     .Mark(&frame0_esp)
   907     // no outgoing parameters; this is the youngest frame.
   908     .D32(frame1_ebp)    // saved register area: saved %ebp
   909     .D32(0xb68bd5f9)    // saved register area: something else
   910     .D32(0xd25d05fc)    // local area
   911     .D32(0x4000debe)    // return address, in module1, no function
   912     // frame 1, in module1, no function.
   913     .Mark(&frame1_esp)
   914     .D32(0xf0c9a974)    // junk
   915     .Mark(&frame1_ebp)
   916     .D32(0)             // saved %ebp (stack end)
   917     .D32(0);            // saved %eip (stack end)
   919   RegionFromSection();
   920   raw_context.eip = 0x40009ab8; // in module1::RaisedByTheAliens
   921   raw_context.esp = stack_section.start().Value();
   922   // RaisedByTheAliens uses %ebp for its own mysterious purposes.
   923   raw_context.ebp = 0xecbdd1a5;
   925   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
   926   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
   927                         &frame_symbolizer);
   928   vector<const CodeModule*> modules_without_symbols;
   929   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
   930   ASSERT_EQ(0U, modules_without_symbols.size());
   931   frames = call_stack.frames();
   932   ASSERT_EQ(2U, frames->size());
   934   {  // To avoid reusing locals by mistake
   935     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
   936     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
   937     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
   938     EXPECT_EQ(0x40009ab8U, frame0->instruction);
   939     EXPECT_EQ(0x40009ab8U, frame0->context.eip);
   940     EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
   941     EXPECT_EQ(0xecbdd1a5, frame0->context.ebp);
   942     EXPECT_EQ(&module1, frame0->module);
   943     EXPECT_EQ("module1::RaisedByTheAliens", frame0->function_name);
   944     EXPECT_EQ(0x40009aa8U, frame0->function_base);
   945     // The STACK WIN record for module1::RaisedByTheAliens should have
   946     // produced a fully populated WindowsFrameInfo structure.
   947     ASSERT_TRUE(frame0->windows_frame_info != NULL);
   948     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
   949     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
   950               frame0->windows_frame_info->type_);
   951     EXPECT_EQ("", frame0->windows_frame_info->program_string);
   952     EXPECT_TRUE(frame0->windows_frame_info->allocates_base_pointer);
   953   }
   955   {  // To avoid reusing locals by mistake
   956     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
   957     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
   958     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
   959                | StackFrameX86::CONTEXT_VALID_ESP
   960                | StackFrameX86::CONTEXT_VALID_EBP),
   961               frame1->context_validity);
   962     EXPECT_EQ(0x4000debeU, frame1->instruction + 1);
   963     EXPECT_EQ(0x4000debeU, frame1->context.eip);
   964     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
   965     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
   966     EXPECT_EQ(&module1, frame1->module);
   967     EXPECT_EQ("", frame1->function_name);
   968     EXPECT_EQ(NULL, frame1->windows_frame_info);
   969   }
   970 }
   972 // This is a regression unit test which covers a bug which has to do with
   973 // FPO-optimized Windows system call stubs in the context frame.  There is
   974 // a more recent Windows system call dispatch mechanism which differs from
   975 // the one which is being tested here.  The newer system call dispatch
   976 // mechanism creates an extra context frame (KiFastSystemCallRet).
   977 TEST_F(GetCallerFrame, WindowsFPOSystemCall) {
   978   SetModuleSymbols(&module3,  // ntdll.dll
   979                    "PUBLIC 1f8ac c ZwWaitForSingleObject\n"
   980                    "STACK WIN 0 1f8ac 1b 0 0 c 0 0 0 0 0\n");
   981   SetModuleSymbols(&module4,  // kernelbase.dll
   982                    "PUBLIC 109f9 c WaitForSingleObjectEx\n"
   983                    "PUBLIC 36590 0 _except_handler4\n"
   984                    "STACK WIN 4 109f9 df c 0 c c 48 0 1 $T0 $ebp = $eip "
   985                    "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
   986                    "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n"
   987                    "STACK WIN 4 36590 154 17 0 10 0 14 0 1 $T0 $ebp = $eip "
   988                    "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 "
   989                    ".cbSavedRegs - = $P $T0 8 + .cbParams + =\n");
   990   SetModuleSymbols(&module5,  // kernel32.dll
   991                    "PUBLIC 11136 8 WaitForSingleObject\n"
   992                    "PUBLIC 11151 c WaitForSingleObjectExImplementation\n"
   993                    "STACK WIN 4 11136 16 5 0 8 0 0 0 1 $T0 $ebp = $eip "
   994                    "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
   995                    "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n"
   996                    "STACK WIN 4 11151 7a 5 0 c 0 0 0 1 $T0 $ebp = $eip "
   997                    "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
   998                    "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n");
   999   SetModuleSymbols(&module6,  // chrome.dll
  1000                    "FILE 7038 some_file_name.h\n"
  1001                    "FILE 839776 some_file_name.cc\n"
  1002                    "FUNC 217fda 17 4 function_217fda\n"
  1003                    "217fda 4 102 839776\n"
  1004                    "FUNC 217ff1 a 4 function_217ff1\n"
  1005                    "217ff1 0 594 7038\n"
  1006                    "217ff1 a 596 7038\n"
  1007                    "STACK WIN 0 217ff1 a 0 0 4 0 0 0 0 0\n");
  1009   Label frame0_esp, frame1_esp;
  1010   Label frame1_ebp, frame2_ebp, frame3_ebp;
  1011   stack_section.start() = 0x002ff290;
  1012   stack_section
  1013     .Mark(&frame0_esp)
  1014     .D32(0x771ef8c1)    // EIP in frame 0 (system call)
  1015     .D32(0x75fa0a91)    // return address of frame 0
  1016     .Mark(&frame1_esp)
  1017     .D32(0x000017b0)    // args to child
  1018     .D32(0x00000000)
  1019     .D32(0x002ff2d8)
  1020     .D32(0x88014a2e)
  1021     .D32(0x002ff364)
  1022     .D32(0x000017b0)
  1023     .D32(0x00000000)
  1024     .D32(0x00000024)
  1025     .D32(0x00000001)
  1026     .D32(0x00000000)
  1027     .D32(0x00000000)
  1028     .D32(0x00000000)
  1029     .D32(0x00000000)
  1030     .D32(0x00000000)
  1031     .D32(0x00000000)
  1032     .D32(0x00000000)
  1033     .D32(0x9e3b9800)
  1034     .D32(0xfffffff7)
  1035     .D32(0x00000000)
  1036     .D32(0x002ff2a4)
  1037     .D32(0x64a07ff1)    // random value to be confused with a return address
  1038     .D32(0x002ff8dc)
  1039     .D32(0x75fc6590)    // random value to be confused with a return address
  1040     .D32(0xfdd2c6ea)
  1041     .D32(0x00000000)
  1042     .Mark(&frame1_ebp)
  1043     .D32(frame2_ebp)    // Child EBP
  1044     .D32(0x75741194)    // return address of frame 1
  1045     .D32(0x000017b0)    // args to child
  1046     .D32(0x0036ee80)
  1047     .D32(0x00000000)
  1048     .D32(0x65bc7d14)
  1049     .Mark(&frame2_ebp)
  1050     .D32(frame3_ebp)    // Child EBP
  1051     .D32(0x75741148)    // return address of frame 2
  1052     .D32(0x000017b0)    // args to child
  1053     .D32(0x0036ee80)
  1054     .D32(0x00000000)
  1055     .Mark(&frame3_ebp)
  1056     .D32(0)             // saved %ebp (stack end)
  1057     .D32(0);            // saved %eip (stack end)
  1059   RegionFromSection();
  1060   raw_context.eip = 0x771ef8c1;  // in ntdll::ZwWaitForSingleObject
  1061   raw_context.esp = stack_section.start().Value();
  1062   ASSERT_TRUE(raw_context.esp == frame0_esp.Value());
  1063   raw_context.ebp = frame1_ebp.Value();
  1065   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
  1066   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  1067                         &frame_symbolizer);
  1068   vector<const CodeModule*> modules_without_symbols;
  1069   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
  1070   ASSERT_EQ(0U, modules_without_symbols.size());
  1071   frames = call_stack.frames();
  1073   ASSERT_EQ(4U, frames->size());
  1075   {  // To avoid reusing locals by mistake
  1076     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  1077     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  1078     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  1079     EXPECT_EQ(0x771ef8c1U, frame0->instruction);
  1080     EXPECT_EQ(0x771ef8c1U, frame0->context.eip);
  1081     EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
  1082     EXPECT_EQ(frame1_ebp.Value(), frame0->context.ebp);
  1083     EXPECT_EQ(&module3, frame0->module);
  1084     EXPECT_EQ("ZwWaitForSingleObject", frame0->function_name);
  1085     // The STACK WIN record for module3!ZwWaitForSingleObject should have
  1086     // produced a fully populated WindowsFrameInfo structure.
  1087     ASSERT_TRUE(frame0->windows_frame_info != NULL);
  1088     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
  1089     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
  1090               frame0->windows_frame_info->type_);
  1091     EXPECT_EQ("", frame0->windows_frame_info->program_string);
  1092     EXPECT_FALSE(frame0->windows_frame_info->allocates_base_pointer);
  1095   {  // To avoid reusing locals by mistake
  1096     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  1097     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
  1098     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
  1099                | StackFrameX86::CONTEXT_VALID_ESP
  1100                | StackFrameX86::CONTEXT_VALID_EBP),
  1101               frame1->context_validity);
  1102     EXPECT_EQ(0x75fa0a91U, frame1->instruction + 1);
  1103     EXPECT_EQ(0x75fa0a91U, frame1->context.eip);
  1104     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
  1105     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
  1106     EXPECT_EQ(&module4, frame1->module);
  1107     EXPECT_EQ("WaitForSingleObjectEx", frame1->function_name);
  1108     // The STACK WIN record for module4!WaitForSingleObjectEx should have
  1109     // produced a fully populated WindowsFrameInfo structure.
  1110     ASSERT_TRUE(frame1->windows_frame_info != NULL);
  1111     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid);
  1112     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
  1113               frame1->windows_frame_info->type_);
  1114     EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
  1115               "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =",
  1116               frame1->windows_frame_info->program_string);
  1117     EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer);
  1121 // Scan the stack for a better return address and potentially skip frames
  1122 // when the calculated return address is not in a known module.
  1123 // Note, that the span of this scan is somewhat arbitrarily limited to 30
  1124 // search words (pointers):
  1125 //     const int kRASearchWords = 30;
  1126 // This means that frames can be skipped only when their size is relatively
  1127 // small: smaller than kRASearchWords * sizeof(InstructionType)
  1128 TEST_F(GetCallerFrame, ReturnAddressIsNotInKnownModule) {
  1129   MockCodeModule msvcrt_dll(0x77be0000, 0x58000, "msvcrt.dll", "version1");
  1130   SetModuleSymbols(&msvcrt_dll,  // msvcrt.dll
  1131                    "PUBLIC 38180 0 wcsstr\n"
  1132                    "STACK WIN 4 38180 61 10 0 8 0 0 0 1 $T0 $ebp = $eip $T0 "
  1133                    "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs "
  1134                    "- = $P $T0 4 + .cbParams + =\n");
  1136   MockCodeModule kernel32_dll(0x7c800000, 0x103000, "kernel32.dll", "version1");
  1137   SetModuleSymbols(&kernel32_dll,  // kernel32.dll
  1138                    "PUBLIC efda 8 FindNextFileW\n"
  1139                    "STACK WIN 4 efda 1bb c 0 8 8 3c 0 1 $T0 $ebp = $eip $T0 "
  1140                    "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs "
  1141                    "- = $P $T0 4 + .cbParams + =\n");
  1143   MockCodeModule chrome_dll(0x1c30000, 0x28C8000, "chrome.dll", "version1");
  1144   SetModuleSymbols(&chrome_dll,  // chrome.dll
  1145                    "FUNC e3cff 4af 0 file_util::FileEnumerator::Next()\n"
  1146                    "e3cff 1a 711 2505\n"
  1147                    "STACK WIN 4 e3cff 4af 20 0 4 c 94 0 1 $T1 .raSearch = "
  1148                    "$T0  $T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp "
  1149                    "$T1 4 + = $20 $T0 152 - ^ =  $23 $T0 156 - ^ =  $24 "
  1150                    "$T0 160 - ^ =\n");
  1152   // Create some modules with some stock debugging information.
  1153   MockCodeModules local_modules;
  1154   local_modules.Add(&msvcrt_dll);
  1155   local_modules.Add(&kernel32_dll);
  1156   local_modules.Add(&chrome_dll);
  1158   Label frame0_esp;
  1159   Label frame0_ebp;
  1160   Label frame1_ebp;
  1161   Label frame2_ebp;
  1162   Label frame3_ebp;
  1164   stack_section.start() = 0x0932f2d0;
  1165   stack_section
  1166     .Mark(&frame0_esp)
  1167     .D32(0x0764e000)
  1168     .D32(0x0764e068)
  1169     .Mark(&frame0_ebp)
  1170     .D32(frame1_ebp)    // Child EBP
  1171     .D32(0x001767a0)    // return address of frame 0
  1172                         // Not in known module
  1173     .D32(0x0764e0c6)
  1174     .D32(0x001bb1b8)
  1175     .D32(0x0764e068)
  1176     .D32(0x00000003)
  1177     .D32(0x0764e068)
  1178     .D32(0x00000003)
  1179     .D32(0x07578828)
  1180     .D32(0x0764e000)
  1181     .D32(0x00000000)
  1182     .D32(0x001c0010)
  1183     .D32(0x0764e0c6)
  1184     .Mark(&frame1_ebp)
  1185     .D32(frame2_ebp)    // Child EBP
  1186     .D32(0x7c80f10f)    // return address of frame 1
  1187                         // inside kernel32!FindNextFileW
  1188     .D32(0x000008f8)
  1189     .D32(0x00000000)
  1190     .D32(0x00000000)
  1191     .D32(0x00000000)
  1192     .D32(0x0932f34c)
  1193     .D32(0x0764e000)
  1194     .D32(0x00001000)
  1195     .D32(0x00000000)
  1196     .D32(0x00000001)
  1197     .D32(0x00000000)
  1198     .D32(0x00000000)
  1199     .D32(0x0932f6a8)
  1200     .D32(0x00000000)
  1201     .D32(0x0932f6d8)
  1202     .D32(0x00000000)
  1203     .D32(0x000000d6)
  1204     .D32(0x0764e000)
  1205     .D32(0x7ff9a000)
  1206     .D32(0x0932f3fc)
  1207     .D32(0x00000001)
  1208     .D32(0x00000001)
  1209     .D32(0x07578828)
  1210     .D32(0x0000002e)
  1211     .D32(0x0932f340)
  1212     .D32(0x0932eef4)
  1213     .D32(0x0932ffdc)
  1214     .D32(0x7c839ad8)
  1215     .D32(0x7c80f0d8)
  1216     .D32(0x00000000)
  1217     .Mark(&frame2_ebp)
  1218     .D32(frame3_ebp)    // Child EBP
  1219     .D32(0x01d13f91)    // return address of frame 2
  1220                         // inside chrome_dll!file_util::FileEnumerator::Next
  1221     .D32(0x07578828)
  1222     .D32(0x0932f6ac)
  1223     .D32(0x0932f9c4)
  1224     .D32(0x0932f9b4)
  1225     .D32(0x00000000)
  1226     .D32(0x00000003)
  1227     .D32(0x0932f978)
  1228     .D32(0x01094330)
  1229     .D32(0x00000000)
  1230     .D32(0x00000001)
  1231     .D32(0x01094330)
  1232     .D32(0x00000000)
  1233     .D32(0x00000000)
  1234     .D32(0x07f30000)
  1235     .D32(0x01c3ba17)
  1236     .D32(0x08bab840)
  1237     .D32(0x07f31580)
  1238     .D32(0x00000000)
  1239     .D32(0x00000007)
  1240     .D32(0x0932f940)
  1241     .D32(0x0000002e)
  1242     .D32(0x0932f40c)
  1243     .D32(0x01d13b53)
  1244     .D32(0x0932f958)
  1245     .D32(0x00000001)
  1246     .D32(0x00000007)
  1247     .D32(0x0932f940)
  1248     .D32(0x0000002e)
  1249     .D32(0x00000000)
  1250     .D32(0x0932f6ac)
  1251     .D32(0x01e13ef0)
  1252     .D32(0x00000001)
  1253     .D32(0x00000007)
  1254     .D32(0x0932f958)
  1255     .D32(0x08bab840)
  1256     .D32(0x0932f9b4)
  1257     .D32(0x00000000)
  1258     .D32(0x0932f9b4)
  1259     .D32(0x000000a7)
  1260     .D32(0x000000a7)
  1261     .D32(0x0932f998)
  1262     .D32(0x579627a2)
  1263     .Mark(&frame3_ebp)
  1264     .D32(0)             // saved %ebp (stack end)
  1265     .D32(0);            // saved %eip (stack end)
  1267   RegionFromSection();
  1268   raw_context.eip = 0x77c181cd;  // inside msvcrt!wcsstr
  1269   raw_context.esp = frame0_esp.Value();
  1270   raw_context.ebp = frame0_ebp.Value();
  1271   // sanity
  1272   ASSERT_TRUE(raw_context.esp == stack_section.start().Value());
  1273   ASSERT_TRUE(raw_context.ebp == stack_section.start().Value() + 8);
  1275   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
  1276   StackwalkerX86 walker(&system_info, &raw_context, &stack_region,
  1277                         &local_modules, &frame_symbolizer);
  1278   vector<const CodeModule*> modules_without_symbols;
  1279   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
  1280   ASSERT_EQ(0U, modules_without_symbols.size());
  1281   frames = call_stack.frames();
  1283   ASSERT_EQ(3U, frames->size());
  1285   {  // To avoid reusing locals by mistake
  1286     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  1287     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  1288     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  1289     EXPECT_EQ(0x77c181cdU, frame0->instruction);
  1290     EXPECT_EQ(0x77c181cdU, frame0->context.eip);
  1291     EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
  1292     EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
  1293     EXPECT_EQ(&msvcrt_dll, frame0->module);
  1294     EXPECT_EQ("wcsstr", frame0->function_name);
  1295     ASSERT_TRUE(frame0->windows_frame_info != NULL);
  1296     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
  1297     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
  1298               frame0->windows_frame_info->type_);
  1299     EXPECT_EQ("$T0 $ebp = $eip $T0 "
  1300               "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs "
  1301               "- = $P $T0 4 + .cbParams + =",
  1302               frame0->windows_frame_info->program_string);
  1303     // It has program string, so allocates_base_pointer is not expected
  1304     EXPECT_FALSE(frame0->windows_frame_info->allocates_base_pointer);
  1307   {  // To avoid reusing locals by mistake
  1308     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  1309     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI_SCAN, frame1->trust);
  1310     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
  1311                StackFrameX86::CONTEXT_VALID_ESP |
  1312                StackFrameX86::CONTEXT_VALID_EBP),
  1313               frame1->context_validity);
  1314     EXPECT_EQ(0x7c80f10fU, frame1->instruction + 1);
  1315     EXPECT_EQ(0x7c80f10fU, frame1->context.eip);
  1316     // frame 1 was skipped, so intead of frame1_ebp compare with frame2_ebp.
  1317     EXPECT_EQ(frame2_ebp.Value(), frame1->context.ebp);
  1318     EXPECT_EQ(&kernel32_dll, frame1->module);
  1319     EXPECT_EQ("FindNextFileW", frame1->function_name);
  1320     ASSERT_TRUE(frame1->windows_frame_info != NULL);
  1321     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid);
  1322     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
  1323               frame1->windows_frame_info->type_);
  1324     EXPECT_EQ("$T0 $ebp = $eip $T0 "
  1325               "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs "
  1326               "- = $P $T0 4 + .cbParams + =",
  1327               frame1->windows_frame_info->program_string);
  1328     EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer);
  1331   {  // To avoid reusing locals by mistake
  1332     StackFrameX86 *frame2 = static_cast<StackFrameX86 *>(frames->at(2));
  1333     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust);
  1334     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
  1335                StackFrameX86::CONTEXT_VALID_ESP |
  1336                StackFrameX86::CONTEXT_VALID_EBP),
  1337               frame2->context_validity);
  1338     EXPECT_EQ(0x01d13f91U, frame2->instruction + 1);
  1339     EXPECT_EQ(0x01d13f91U, frame2->context.eip);
  1340     // frame 1 was skipped, so intead of frame2_ebp compare with frame3_ebp.
  1341     EXPECT_EQ(frame3_ebp.Value(), frame2->context.ebp);
  1342     EXPECT_EQ(&chrome_dll, frame2->module);
  1343     EXPECT_EQ("file_util::FileEnumerator::Next()", frame2->function_name);
  1344     ASSERT_TRUE(frame2->windows_frame_info != NULL);
  1345     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame2->windows_frame_info->valid);
  1346     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
  1347               frame2->windows_frame_info->type_);
  1348     EXPECT_EQ("$T1 .raSearch = "
  1349               "$T0  $T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp "
  1350               "$T1 4 + = $20 $T0 152 - ^ =  $23 $T0 156 - ^ =  $24 "
  1351               "$T0 160 - ^ =",
  1352               frame2->windows_frame_info->program_string);
  1353     EXPECT_FALSE(frame2->windows_frame_info->allocates_base_pointer);
  1357 struct CFIFixture: public StackwalkerX86Fixture {
  1358   CFIFixture() {
  1359     // Provide a bunch of STACK CFI records; individual tests walk to the
  1360     // caller from every point in this series, expecting to find the same
  1361     // set of register values.
  1362     SetModuleSymbols(&module1,
  1363                      // The youngest frame's function.
  1364                      "FUNC 4000 1000 10 enchiridion\n"
  1365                      // Initially, just a return address.
  1366                      "STACK CFI INIT 4000 100 .cfa: $esp 4 + .ra: .cfa 4 - ^\n"
  1367                      // Push %ebx.
  1368                      "STACK CFI 4001 .cfa: $esp 8 + $ebx: .cfa 8 - ^\n"
  1369                      // Move %esi into %ebx.  Weird, but permitted.
  1370                      "STACK CFI 4002 $esi: $ebx\n"
  1371                      // Allocate frame space, and save %edi.
  1372                      "STACK CFI 4003 .cfa: $esp 20 + $edi: .cfa 16 - ^\n"
  1373                      // Put the return address in %edi.
  1374                      "STACK CFI 4005 .ra: $edi\n"
  1375                      // Save %ebp, and use it as a frame pointer.
  1376                      "STACK CFI 4006 .cfa: $ebp 8 + $ebp: .cfa 12 - ^\n"
  1378                      // The calling function.
  1379                      "FUNC 5000 1000 10 epictetus\n"
  1380                      // Mark it as end of stack.
  1381                      "STACK CFI INIT 5000 1000 .cfa: $esp .ra 0\n");
  1383     // Provide some distinctive values for the caller's registers.
  1384     expected.esp = 0x80000000;
  1385     expected.eip = 0x40005510;
  1386     expected.ebp = 0xc0d4aab9;
  1387     expected.ebx = 0x60f20ce6;
  1388     expected.esi = 0x53d1379d;
  1389     expected.edi = 0xafbae234;
  1391     // By default, registers are unchanged.
  1392     raw_context = expected;
  1395   // Walk the stack, using stack_section as the contents of the stack
  1396   // and raw_context as the current register values. (Set
  1397   // raw_context.esp to the stack's starting address.) Expect two
  1398   // stack frames; in the older frame, expect the callee-saves
  1399   // registers to have values matching those in 'expected'.
  1400   void CheckWalk() {
  1401     RegionFromSection();
  1402     raw_context.esp = stack_section.start().Value();
  1404     StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
  1405     StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  1406                           &frame_symbolizer);
  1407     vector<const CodeModule*> modules_without_symbols;
  1408     ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols));
  1409     ASSERT_EQ(0U, modules_without_symbols.size());
  1410     frames = call_stack.frames();
  1411     ASSERT_EQ(2U, frames->size());
  1413     {  // To avoid reusing locals by mistake
  1414       StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  1415       EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  1416       ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  1417       EXPECT_EQ("enchiridion", frame0->function_name);
  1418       EXPECT_EQ(0x40004000U, frame0->function_base);
  1419       ASSERT_TRUE(frame0->windows_frame_info != NULL);
  1420       ASSERT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE,
  1421                 frame0->windows_frame_info->valid);
  1422       ASSERT_TRUE(frame0->cfi_frame_info != NULL);
  1425     {  // To avoid reusing locals by mistake
  1426       StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  1427       EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
  1428       ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
  1429                  StackFrameX86::CONTEXT_VALID_ESP |
  1430                  StackFrameX86::CONTEXT_VALID_EBP |
  1431                  StackFrameX86::CONTEXT_VALID_EBX |
  1432                  StackFrameX86::CONTEXT_VALID_ESI |
  1433                  StackFrameX86::CONTEXT_VALID_EDI),
  1434                  frame1->context_validity);
  1435       EXPECT_EQ(expected.eip, frame1->context.eip);
  1436       EXPECT_EQ(expected.esp, frame1->context.esp);
  1437       EXPECT_EQ(expected.ebp, frame1->context.ebp);
  1438       EXPECT_EQ(expected.ebx, frame1->context.ebx);
  1439       EXPECT_EQ(expected.esi, frame1->context.esi);
  1440       EXPECT_EQ(expected.edi, frame1->context.edi);
  1441       EXPECT_EQ("epictetus", frame1->function_name);
  1445   // The values the stack walker should find for the caller's registers.
  1446   MDRawContextX86 expected;
  1447 };
  1449 class CFI: public CFIFixture, public Test { };
  1451 TEST_F(CFI, At4000) {
  1452   Label frame1_esp = expected.esp;
  1453   stack_section
  1454     .D32(0x40005510)            // return address
  1455     .Mark(&frame1_esp);         // This effectively sets stack_section.start().
  1456   raw_context.eip = 0x40004000;
  1457   CheckWalk();
  1460 TEST_F(CFI, At4001) {
  1461   Label frame1_esp = expected.esp;
  1462   stack_section
  1463     .D32(0x60f20ce6)            // saved %ebx
  1464     .D32(0x40005510)            // return address
  1465     .Mark(&frame1_esp);         // This effectively sets stack_section.start().
  1466   raw_context.eip = 0x40004001;
  1467   raw_context.ebx = 0x91aa9a8b; // callee's %ebx value
  1468   CheckWalk();
  1471 TEST_F(CFI, At4002) {
  1472   Label frame1_esp = expected.esp;
  1473   stack_section
  1474     .D32(0x60f20ce6)            // saved %ebx
  1475     .D32(0x40005510)            // return address
  1476     .Mark(&frame1_esp);         // This effectively sets stack_section.start().
  1477   raw_context.eip = 0x40004002;
  1478   raw_context.ebx = 0x53d1379d; // saved %esi
  1479   raw_context.esi = 0xa5c790ed; // callee's %esi value
  1480   CheckWalk();
  1483 TEST_F(CFI, At4003) {
  1484   Label frame1_esp = expected.esp;
  1485   stack_section
  1486     .D32(0x56ec3db7)            // garbage
  1487     .D32(0xafbae234)            // saved %edi
  1488     .D32(0x53d67131)            // garbage
  1489     .D32(0x60f20ce6)            // saved %ebx
  1490     .D32(0x40005510)            // return address
  1491     .Mark(&frame1_esp);         // This effectively sets stack_section.start().
  1492   raw_context.eip = 0x40004003;
  1493   raw_context.ebx = 0x53d1379d; // saved %esi
  1494   raw_context.esi = 0xa97f229d; // callee's %esi
  1495   raw_context.edi = 0xb05cc997; // callee's %edi
  1496   CheckWalk();
  1499 // The results here should be the same as those at module offset
  1500 // 0x4003.
  1501 TEST_F(CFI, At4004) {
  1502   Label frame1_esp = expected.esp;
  1503   stack_section
  1504     .D32(0xe29782c2)            // garbage
  1505     .D32(0xafbae234)            // saved %edi
  1506     .D32(0x5ba29ce9)            // garbage
  1507     .D32(0x60f20ce6)            // saved %ebx
  1508     .D32(0x40005510)            // return address
  1509     .Mark(&frame1_esp);         // This effectively sets stack_section.start().
  1510   raw_context.eip = 0x40004004;
  1511   raw_context.ebx = 0x53d1379d; // saved %esi
  1512   raw_context.esi = 0x0fb7dc4e; // callee's %esi
  1513   raw_context.edi = 0x993b4280; // callee's %edi
  1514   CheckWalk();
  1517 TEST_F(CFI, At4005) {
  1518   Label frame1_esp = expected.esp;
  1519   stack_section
  1520     .D32(0xe29782c2)            // garbage
  1521     .D32(0xafbae234)            // saved %edi
  1522     .D32(0x5ba29ce9)            // garbage
  1523     .D32(0x60f20ce6)            // saved %ebx
  1524     .D32(0x8036cc02)            // garbage
  1525     .Mark(&frame1_esp);         // This effectively sets stack_section.start().
  1526   raw_context.eip = 0x40004005;
  1527   raw_context.ebx = 0x53d1379d; // saved %esi
  1528   raw_context.esi = 0x0fb7dc4e; // callee's %esi
  1529   raw_context.edi = 0x40005510; // return address
  1530   CheckWalk();
  1533 TEST_F(CFI, At4006) {
  1534   Label frame0_ebp;
  1535   Label frame1_esp = expected.esp;
  1536   stack_section
  1537     .D32(0xdcdd25cd)            // garbage
  1538     .D32(0xafbae234)            // saved %edi
  1539     .D32(0xc0d4aab9)            // saved %ebp
  1540     .Mark(&frame0_ebp)          // frame pointer points here
  1541     .D32(0x60f20ce6)            // saved %ebx
  1542     .D32(0x8036cc02)            // garbage
  1543     .Mark(&frame1_esp);         // This effectively sets stack_section.start().
  1544   raw_context.eip = 0x40004006;
  1545   raw_context.ebp = frame0_ebp.Value();
  1546   raw_context.ebx = 0x53d1379d; // saved %esi
  1547   raw_context.esi = 0x743833c9; // callee's %esi
  1548   raw_context.edi = 0x40005510; // return address
  1549   CheckWalk();

mercurial