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 "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"
49 
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::Stackwalker;
57 using google_breakpad::StackwalkerX86;
58 using google_breakpad::SystemInfo;
59 using google_breakpad::WindowsFrameInfo;
60 using google_breakpad::test_assembler::kLittleEndian;
61 using google_breakpad::test_assembler::Label;
62 using google_breakpad::test_assembler::Section;
63 using std::vector;
64 using testing::_;
65 using testing::AnyNumber;
66 using testing::DoAll;
67 using testing::Return;
68 using testing::SetArgumentPointee;
69 using testing::Test;
70 
71 class StackwalkerX86Fixture {
72  public:
StackwalkerX86Fixture()73   StackwalkerX86Fixture()
74     : stack_section(kLittleEndian),
75       // Give the two modules reasonable standard locations and names
76       // for tests to play with.
77       module1(0x40000000, 0x10000, "module1", "version1"),
78       module2(0x50000000, 0x10000, "module2", "version2"),
79       module3(0x771d0000, 0x180000, "module3", "version3"),
80       module4(0x75f90000, 0x46000, "module4", "version4"),
81       module5(0x75730000, 0x110000, "module5", "version5"),
82       module6(0x647f0000, 0x1ba8000, "module6", "version6") {
83     // Identify the system as a Linux system.
84     system_info.os = "Linux";
85     system_info.os_short = "linux";
86     system_info.os_version = "Salacious Skink";
87     system_info.cpu = "x86";
88     system_info.cpu_info = "";
89 
90     // Put distinctive values in the raw CPU context.
91     BrandContext(&raw_context);
92 
93     // Create some modules with some stock debugging information.
94     modules.Add(&module1);
95     modules.Add(&module2);
96     modules.Add(&module3);
97     modules.Add(&module4);
98     modules.Add(&module5);
99     modules.Add(&module6);
100 
101     // By default, none of the modules have symbol info; call
102     // SetModuleSymbols to override this.
103     EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _))
104       .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND));
105 
106     // Avoid GMOCK WARNING "Uninteresting mock function call - returning
107     // directly" for FreeSymbolData().
108     EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber());
109 
110     // Reset max_frames_scanned since it's static.
111     Stackwalker::set_max_frames_scanned(1024);
112   }
113 
114   // Set the Breakpad symbol information that supplier should return for
115   // MODULE to INFO.
SetModuleSymbols(MockCodeModule * module,const string & info)116   void SetModuleSymbols(MockCodeModule *module, const string &info) {
117     size_t buffer_size;
118     char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size);
119     EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _))
120       .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer),
121                             SetArgumentPointee<4>(buffer_size),
122                             Return(MockSymbolSupplier::FOUND)));
123   }
124 
125   // Populate stack_region with the contents of stack_section. Use
126   // stack_section.start() as the region's starting address.
RegionFromSection()127   void RegionFromSection() {
128     string contents;
129     ASSERT_TRUE(stack_section.GetContents(&contents));
130     stack_region.Init(stack_section.start().Value(), contents);
131   }
132 
133   // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking.
BrandContext(MDRawContextX86 * raw_context)134   void BrandContext(MDRawContextX86 *raw_context) {
135     uint8_t x = 173;
136     for (size_t i = 0; i < sizeof(*raw_context); i++)
137       reinterpret_cast<uint8_t *>(raw_context)[i] = (x += 17);
138   }
139 
140   SystemInfo system_info;
141   MDRawContextX86 raw_context;
142   Section stack_section;
143   MockMemoryRegion stack_region;
144   MockCodeModule module1;
145   MockCodeModule module2;
146   MockCodeModule module3;
147   MockCodeModule module4;
148   MockCodeModule module5;
149   MockCodeModule module6;
150   MockCodeModules modules;
151   MockSymbolSupplier supplier;
152   BasicSourceLineResolver resolver;
153   CallStack call_stack;
154   const vector<StackFrame *> *frames;
155 };
156 
157 class SanityCheck: public StackwalkerX86Fixture, public Test { };
158 
TEST_F(SanityCheck,NoResolver)159 TEST_F(SanityCheck, NoResolver) {
160   stack_section.start() = 0x80000000;
161   stack_section.D32(0).D32(0);  // end-of-stack marker
162   RegionFromSection();
163   raw_context.eip = 0x40000200;
164   raw_context.ebp = 0x80000000;
165 
166   StackFrameSymbolizer frame_symbolizer(NULL, NULL);
167   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
168                         &frame_symbolizer);
169   // This should succeed, even without a resolver or supplier.
170   vector<const CodeModule*> modules_without_symbols;
171   vector<const CodeModule*> modules_with_corrupt_symbols;
172   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
173                           &modules_with_corrupt_symbols));
174   ASSERT_EQ(1U, modules_without_symbols.size());
175   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
176   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
177   frames = call_stack.frames();
178   StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
179   // Check that the values from the original raw context made it
180   // through to the context in the stack frame.
181   EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
182 }
183 
184 class GetContextFrame: public StackwalkerX86Fixture, public Test { };
185 
TEST_F(GetContextFrame,Simple)186 TEST_F(GetContextFrame, Simple) {
187   stack_section.start() = 0x80000000;
188   stack_section.D32(0).D32(0);  // end-of-stack marker
189   RegionFromSection();
190   raw_context.eip = 0x40000200;
191   raw_context.ebp = 0x80000000;
192 
193   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
194   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
195                         &frame_symbolizer);
196   vector<const CodeModule*> modules_without_symbols;
197   vector<const CodeModule*> modules_with_corrupt_symbols;
198   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
199                           &modules_with_corrupt_symbols));
200   ASSERT_EQ(1U, modules_without_symbols.size());
201   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
202   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
203   frames = call_stack.frames();
204   StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
205   // Check that the values from the original raw context made it
206   // through to the context in the stack frame.
207   EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
208 }
209 
210 // The stackwalker should be able to produce the context frame even
211 // without stack memory present.
TEST_F(GetContextFrame,NoStackMemory)212 TEST_F(GetContextFrame, NoStackMemory) {
213   raw_context.eip = 0x40000200;
214   raw_context.ebp = 0x80000000;
215 
216   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
217   StackwalkerX86 walker(&system_info, &raw_context, NULL, &modules,
218                         &frame_symbolizer);
219   vector<const CodeModule*> modules_without_symbols;
220   vector<const CodeModule*> modules_with_corrupt_symbols;
221   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
222                           &modules_with_corrupt_symbols));
223   ASSERT_EQ(1U, modules_without_symbols.size());
224   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
225   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
226   frames = call_stack.frames();
227   StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
228   // Check that the values from the original raw context made it
229   // through to the context in the stack frame.
230   EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
231 }
232 
233 class GetCallerFrame: public StackwalkerX86Fixture, public Test {
234  protected:
235   void IPAddressIsNotInKnownModuleTestImpl(bool has_corrupt_symbols);
236 };
237 
238 // Walk a traditional frame. A traditional frame saves the caller's
239 // %ebp just below the return address, and has its own %ebp pointing
240 // at the saved %ebp.
TEST_F(GetCallerFrame,Traditional)241 TEST_F(GetCallerFrame, Traditional) {
242   stack_section.start() = 0x80000000;
243   Label frame0_ebp, frame1_ebp;
244   stack_section
245     .Append(12, 0)                      // frame 0: space
246     .Mark(&frame0_ebp)                  // frame 0 %ebp points here
247     .D32(frame1_ebp)                    // frame 0: saved %ebp
248     .D32(0x40008679)                    // frame 0: return address
249     .Append(8, 0)                       // frame 1: space
250     .Mark(&frame1_ebp)                  // frame 1 %ebp points here
251     .D32(0)                             // frame 1: saved %ebp (stack end)
252     .D32(0);                            // frame 1: return address (stack end)
253   RegionFromSection();
254   raw_context.eip = 0x4000c7a5;
255   raw_context.esp = stack_section.start().Value();
256   raw_context.ebp = frame0_ebp.Value();
257 
258   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
259   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
260                         &frame_symbolizer);
261   vector<const CodeModule*> modules_without_symbols;
262   vector<const CodeModule*> modules_with_corrupt_symbols;
263   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
264                           &modules_with_corrupt_symbols));
265   ASSERT_EQ(1U, modules_without_symbols.size());
266   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
267   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
268   frames = call_stack.frames();
269   ASSERT_EQ(2U, frames->size());
270 
271   {  // To avoid reusing locals by mistake
272     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
273     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
274     EXPECT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
275     EXPECT_EQ(0x4000c7a5U, frame0->instruction);
276     EXPECT_EQ(0x4000c7a5U, frame0->context.eip);
277     EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
278     EXPECT_EQ(NULL, frame0->windows_frame_info);
279   }
280 
281   {  // To avoid reusing locals by mistake
282     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
283     EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
284     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
285                | StackFrameX86::CONTEXT_VALID_ESP
286                | StackFrameX86::CONTEXT_VALID_EBP),
287               frame1->context_validity);
288     EXPECT_EQ(0x40008679U, frame1->instruction + 1);
289     EXPECT_EQ(0x40008679U, frame1->context.eip);
290     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
291     EXPECT_EQ(NULL, frame1->windows_frame_info);
292   }
293 }
294 
295 // Walk a traditional frame, but use a bogus %ebp value, forcing a scan
296 // of the stack for something that looks like a return address.
TEST_F(GetCallerFrame,TraditionalScan)297 TEST_F(GetCallerFrame, TraditionalScan) {
298   stack_section.start() = 0x80000000;
299   Label frame1_ebp;
300   Label frame1_esp;
301   stack_section
302     // frame 0
303     .D32(0xf065dc76)    // locals area:
304     .D32(0x46ee2167)    // garbage that doesn't look like
305     .D32(0xbab023ec)    // a return address
306     .D32(frame1_ebp)    // saved %ebp (%ebp fails to point here, forcing scan)
307     .D32(0x4000129d)    // return address
308     // frame 1
309     .Mark(&frame1_esp)
310     .Append(8, 0)       // space
311     .Mark(&frame1_ebp)  // %ebp points here
312     .D32(0)             // saved %ebp (stack end)
313     .D32(0);            // return address (stack end)
314 
315   RegionFromSection();
316   raw_context.eip = 0x4000f49d;
317   raw_context.esp = stack_section.start().Value();
318   // Make the frame pointer bogus, to make the stackwalker scan the stack
319   // for something that looks like a return address.
320   raw_context.ebp = 0xd43eed6e;
321 
322   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
323   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
324                         &frame_symbolizer);
325   vector<const CodeModule*> modules_without_symbols;
326   vector<const CodeModule*> modules_with_corrupt_symbols;
327   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
328                           &modules_with_corrupt_symbols));
329   ASSERT_EQ(1U, modules_without_symbols.size());
330   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
331   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
332   frames = call_stack.frames();
333   ASSERT_EQ(2U, frames->size());
334 
335   {  // To avoid reusing locals by mistake
336     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
337     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
338     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
339     EXPECT_EQ(0x4000f49dU, frame0->instruction);
340     EXPECT_EQ(0x4000f49dU, frame0->context.eip);
341     EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
342     EXPECT_EQ(0xd43eed6eU, frame0->context.ebp);
343     EXPECT_EQ(NULL, frame0->windows_frame_info);
344   }
345 
346   {  // To avoid reusing locals by mistake
347     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
348     EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
349     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
350                | StackFrameX86::CONTEXT_VALID_ESP
351                | StackFrameX86::CONTEXT_VALID_EBP),
352               frame1->context_validity);
353     EXPECT_EQ(0x4000129dU, frame1->instruction + 1);
354     EXPECT_EQ(0x4000129dU, frame1->context.eip);
355     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
356     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
357     EXPECT_EQ(NULL, frame1->windows_frame_info);
358   }
359 }
360 
361 // Force scanning for a return address a long way down the stack
TEST_F(GetCallerFrame,TraditionalScanLongWay)362 TEST_F(GetCallerFrame, TraditionalScanLongWay) {
363   stack_section.start() = 0x80000000;
364   Label frame1_ebp;
365   Label frame1_esp;
366   stack_section
367     // frame 0
368     .D32(0xf065dc76)    // locals area:
369     .D32(0x46ee2167)    // garbage that doesn't look like
370     .D32(0xbab023ec)    // a return address
371     .Append(20 * 4, 0)  // a bunch of space
372     .D32(frame1_ebp)    // saved %ebp (%ebp fails to point here, forcing scan)
373     .D32(0x4000129d)    // return address
374     // frame 1
375     .Mark(&frame1_esp)
376     .Append(8, 0)       // space
377     .Mark(&frame1_ebp)  // %ebp points here
378     .D32(0)             // saved %ebp (stack end)
379     .D32(0);            // return address (stack end)
380 
381   RegionFromSection();
382   raw_context.eip = 0x4000f49d;
383   raw_context.esp = stack_section.start().Value();
384   // Make the frame pointer bogus, to make the stackwalker scan the stack
385   // for something that looks like a return address.
386   raw_context.ebp = 0xd43eed6e;
387 
388   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
389   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
390                         &frame_symbolizer);
391   vector<const CodeModule*> modules_without_symbols;
392   vector<const CodeModule*> modules_with_corrupt_symbols;
393   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
394                           &modules_with_corrupt_symbols));
395   ASSERT_EQ(1U, modules_without_symbols.size());
396   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
397   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
398   frames = call_stack.frames();
399   ASSERT_EQ(2U, frames->size());
400 
401   {  // To avoid reusing locals by mistake
402     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
403     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
404     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
405     EXPECT_EQ(0x4000f49dU, frame0->instruction);
406     EXPECT_EQ(0x4000f49dU, frame0->context.eip);
407     EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
408     EXPECT_EQ(0xd43eed6eU, frame0->context.ebp);
409     EXPECT_EQ(NULL, frame0->windows_frame_info);
410   }
411 
412   {  // To avoid reusing locals by mistake
413     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
414     EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
415     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
416                | StackFrameX86::CONTEXT_VALID_ESP
417                | StackFrameX86::CONTEXT_VALID_EBP),
418               frame1->context_validity);
419     EXPECT_EQ(0x4000129dU, frame1->instruction + 1);
420     EXPECT_EQ(0x4000129dU, frame1->context.eip);
421     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
422     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
423     EXPECT_EQ(NULL, frame1->windows_frame_info);
424   }
425 }
426 
427 // Test that set_max_frames_scanned prevents using stack scanning
428 // to find caller frames.
TEST_F(GetCallerFrame,ScanningNotAllowed)429 TEST_F(GetCallerFrame, ScanningNotAllowed) {
430   stack_section.start() = 0x80000000;
431   Label frame1_ebp;
432   stack_section
433     // frame 0
434     .D32(0xf065dc76)    // locals area:
435     .D32(0x46ee2167)    // garbage that doesn't look like
436     .D32(0xbab023ec)    // a return address
437     .D32(frame1_ebp)    // saved %ebp (%ebp fails to point here, forcing scan)
438     .D32(0x4000129d)    // return address
439     // frame 1
440     .Append(8, 0)       // space
441     .Mark(&frame1_ebp)  // %ebp points here
442     .D32(0)             // saved %ebp (stack end)
443     .D32(0);            // return address (stack end)
444 
445   RegionFromSection();
446   raw_context.eip = 0x4000f49d;
447   raw_context.esp = stack_section.start().Value();
448   // Make the frame pointer bogus, to make the stackwalker scan the stack
449   // for something that looks like a return address.
450   raw_context.ebp = 0xd43eed6e;
451 
452   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
453   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
454                         &frame_symbolizer);
455   Stackwalker::set_max_frames_scanned(0);
456 
457   vector<const CodeModule*> modules_without_symbols;
458   vector<const CodeModule*> modules_with_corrupt_symbols;
459   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
460                           &modules_with_corrupt_symbols));
461   ASSERT_EQ(1U, modules_without_symbols.size());
462   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
463   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
464   frames = call_stack.frames();
465   ASSERT_EQ(1U, frames->size());
466 
467   {  // To avoid reusing locals by mistake
468     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
469     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
470     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
471     EXPECT_EQ(0x4000f49dU, frame0->instruction);
472     EXPECT_EQ(0x4000f49dU, frame0->context.eip);
473     EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
474     EXPECT_EQ(0xd43eed6eU, frame0->context.ebp);
475     EXPECT_EQ(NULL, frame0->windows_frame_info);
476   }
477 }
478 
479 // Use Windows frame data (a "STACK WIN 4" record, from a
480 // FrameTypeFrameData DIA record) to walk a stack frame.
TEST_F(GetCallerFrame,WindowsFrameData)481 TEST_F(GetCallerFrame, WindowsFrameData) {
482   SetModuleSymbols(&module1,
483                    "STACK WIN 4 aa85 176 0 0 4 10 4 0 1"
484                    " $T2 $esp .cbSavedRegs + ="
485                    " $T0 .raSearchStart ="
486                    " $eip $T0 ^ ="
487                    " $esp $T0 4 + ="
488                    " $ebx $T2 4  - ^ ="
489                    " $edi $T2 8  - ^ ="
490                    " $esi $T2 12 - ^ ="
491                    " $ebp $T2 16 - ^ =\n");
492   Label frame1_esp, frame1_ebp;
493   stack_section.start() = 0x80000000;
494   stack_section
495     // frame 0
496     .D32(frame1_ebp)                    // saved regs: %ebp
497     .D32(0xa7120d1a)                    //             %esi
498     .D32(0x630891be)                    //             %edi
499     .D32(0x9068a878)                    //             %ebx
500     .D32(0xa08ea45f)                    // locals: unused
501     .D32(0x40001350)                    // return address
502     // frame 1
503     .Mark(&frame1_esp)
504     .Append(12, 0)                      // empty space
505     .Mark(&frame1_ebp)
506     .D32(0)                             // saved %ebp (stack end)
507     .D32(0);                            // saved %eip (stack end)
508 
509   RegionFromSection();
510   raw_context.eip = 0x4000aa85;
511   raw_context.esp = stack_section.start().Value();
512   raw_context.ebp = 0xf052c1de;         // should not be needed to walk frame
513 
514   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
515   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
516                         &frame_symbolizer);
517   vector<const CodeModule*> modules_without_symbols;
518   vector<const CodeModule*> modules_with_corrupt_symbols;
519   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
520                           &modules_with_corrupt_symbols));
521   ASSERT_EQ(0U, modules_without_symbols.size());
522   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
523   frames = call_stack.frames();
524   ASSERT_EQ(2U, frames->size());
525 
526   {  // To avoid reusing locals by mistake
527     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
528     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
529     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
530     EXPECT_EQ(0x4000aa85U, frame0->instruction);
531     EXPECT_EQ(0x4000aa85U, frame0->context.eip);
532     EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
533     EXPECT_EQ(0xf052c1deU, frame0->context.ebp);
534     EXPECT_TRUE(frame0->windows_frame_info != NULL);
535   }
536 
537   {  // To avoid reusing locals by mistake
538     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
539     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
540     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
541                | StackFrameX86::CONTEXT_VALID_ESP
542                | StackFrameX86::CONTEXT_VALID_EBP
543                | StackFrameX86::CONTEXT_VALID_EBX
544                | StackFrameX86::CONTEXT_VALID_ESI
545                | StackFrameX86::CONTEXT_VALID_EDI),
546               frame1->context_validity);
547     EXPECT_EQ(0x40001350U, frame1->instruction + 1);
548     EXPECT_EQ(0x40001350U, frame1->context.eip);
549     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
550     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
551     EXPECT_EQ(0x9068a878U, frame1->context.ebx);
552     EXPECT_EQ(0xa7120d1aU, frame1->context.esi);
553     EXPECT_EQ(0x630891beU, frame1->context.edi);
554     EXPECT_EQ(NULL, frame1->windows_frame_info);
555   }
556 }
557 
558 // Use Windows frame data (a "STACK WIN 4" record, from a
559 // FrameTypeFrameData DIA record) to walk a stack frame where the stack
560 // is aligned and we must search
TEST_F(GetCallerFrame,WindowsFrameDataAligned)561 TEST_F(GetCallerFrame, WindowsFrameDataAligned) {
562   SetModuleSymbols(&module1,
563                    "STACK WIN 4 aa85 176 0 0 4 4 8 0 1"
564                    " $T1 .raSearch ="
565                    " $T0 $T1 4 - 8 @ ="
566                    " $ebp $T1 4 - ^ ="
567                    " $eip $T1 ^ ="
568                    " $esp $T1 4 + =");
569   Label frame0_esp, frame0_ebp;
570   Label frame1_esp, frame1_ebp;
571   stack_section.start() = 0x80000000;
572   stack_section
573     // frame 0
574     .Mark(&frame0_esp)
575     .D32(0x0ffa0ffa)                    // unused saved register
576     .D32(0xdeaddead)                    // locals
577     .D32(0xbeefbeef)
578     .D32(0)                             // 8-byte alignment
579     .Mark(&frame0_ebp)
580     .D32(frame1_ebp)                    // saved %ebp
581     .D32(0x5000129d)                    // return address
582     // frame 1
583     .Mark(&frame1_esp)
584     .D32(0x1)                           // parameter
585     .Mark(&frame1_ebp)
586     .D32(0)                             // saved %ebp (stack end)
587     .D32(0);                            // saved %eip (stack end)
588 
589   RegionFromSection();
590   raw_context.eip = 0x4000aa85;
591   raw_context.esp = frame0_esp.Value();
592   raw_context.ebp = frame0_ebp.Value();
593 
594   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
595   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
596                         &frame_symbolizer);
597   vector<const CodeModule*> modules_without_symbols;
598   vector<const CodeModule*> modules_with_corrupt_symbols;
599   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
600                           &modules_with_corrupt_symbols));
601   ASSERT_EQ(1U, modules_without_symbols.size());
602   ASSERT_EQ("module2", modules_without_symbols[0]->debug_file());
603   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
604   frames = call_stack.frames();
605   ASSERT_EQ(2U, frames->size());
606 
607   {  // To avoid reusing locals by mistake
608     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
609     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
610     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
611     EXPECT_EQ(0x4000aa85U, frame0->instruction);
612     EXPECT_EQ(0x4000aa85U, frame0->context.eip);
613     EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
614     EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
615     EXPECT_TRUE(frame0->windows_frame_info != NULL);
616   }
617 
618   {  // To avoid reusing locals by mistake
619     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
620     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
621     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
622                | StackFrameX86::CONTEXT_VALID_ESP
623                | StackFrameX86::CONTEXT_VALID_EBP),
624               frame1->context_validity);
625     EXPECT_EQ(0x5000129dU, frame1->instruction + 1);
626     EXPECT_EQ(0x5000129dU, frame1->context.eip);
627     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
628     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
629     EXPECT_EQ(NULL, frame1->windows_frame_info);
630   }
631 }
632 
633 // Use Windows frame data (a "STACK WIN 4" record, from a
634 // FrameTypeFrameData DIA record) to walk a frame, and depend on the
635 // parameter size from the callee as well.
TEST_F(GetCallerFrame,WindowsFrameDataParameterSize)636 TEST_F(GetCallerFrame, WindowsFrameDataParameterSize) {
637   SetModuleSymbols(&module1, "FUNC 1000 100 c module1::wheedle\n");
638   SetModuleSymbols(&module2,
639                    // Note bogus parameter size in FUNC record; the stack walker
640                    // should prefer the STACK WIN record, and see '4' below.
641                    "FUNC aa85 176 beef module2::whine\n"
642                    "STACK WIN 4 aa85 176 0 0 4 10 4 0 1"
643                    " $T2 $esp .cbLocals + .cbSavedRegs + ="
644                    " $T0 .raSearchStart ="
645                    " $eip $T0 ^ ="
646                    " $esp $T0 4 + ="
647                    " $ebp $T0 20 - ^ ="
648                    " $ebx $T0 8 - ^ =\n");
649   Label frame0_esp, frame0_ebp;
650   Label frame1_esp;
651   Label frame2_esp, frame2_ebp;
652   stack_section.start() = 0x80000000;
653   stack_section
654     // frame 0, in module1::wheedle.  Traditional frame.
655     .Mark(&frame0_esp)
656     .Append(16, 0)      // frame space
657     .Mark(&frame0_ebp)
658     .D32(0x6fa902e0)    // saved %ebp.  Not a frame pointer.
659     .D32(0x5000aa95)    // return address, in module2::whine
660     // frame 1, in module2::whine.  FrameData frame.
661     .Mark(&frame1_esp)
662     .D32(0xbaa0cb7a)    // argument 3 passed to module1::wheedle
663     .D32(0xbdc92f9f)    // argument 2
664     .D32(0x0b1d8442)    // argument 1
665     .D32(frame2_ebp)    // saved %ebp
666     .D32(0xb1b90a15)    // unused
667     .D32(0xf18e072d)    // unused
668     .D32(0x2558c7f3)    // saved %ebx
669     .D32(0x0365e25e)    // unused
670     .D32(0x2a179e38)    // return address; $T0 points here
671     // frame 2, in no module
672     .Mark(&frame2_esp)
673     .Append(12, 0)      // empty space
674     .Mark(&frame2_ebp)
675     .D32(0)             // saved %ebp (stack end)
676     .D32(0);            // saved %eip (stack end)
677 
678   RegionFromSection();
679   raw_context.eip = 0x40001004;  // in module1::wheedle
680   raw_context.esp = stack_section.start().Value();
681   raw_context.ebp = frame0_ebp.Value();
682 
683   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
684   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
685                         &frame_symbolizer);
686   vector<const CodeModule*> modules_without_symbols;
687   vector<const CodeModule*> modules_with_corrupt_symbols;
688   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
689                           &modules_with_corrupt_symbols));
690   ASSERT_EQ(0U, modules_without_symbols.size());
691   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
692   frames = call_stack.frames();
693   ASSERT_EQ(3U, frames->size());
694 
695   {  // To avoid reusing locals by mistake
696     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
697     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
698     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
699     EXPECT_EQ(0x40001004U, frame0->instruction);
700     EXPECT_EQ(0x40001004U, frame0->context.eip);
701     EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
702     EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
703     EXPECT_EQ(&module1, frame0->module);
704     EXPECT_EQ("module1::wheedle", frame0->function_name);
705     EXPECT_EQ(0x40001000U, frame0->function_base);
706     // The FUNC record for module1::wheedle should have produced a
707     // WindowsFrameInfo structure with only the parameter size valid.
708     ASSERT_TRUE(frame0->windows_frame_info != NULL);
709     EXPECT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE,
710               frame0->windows_frame_info->valid);
711     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_UNKNOWN,
712               frame0->windows_frame_info->type_);
713     EXPECT_EQ(12U, frame0->windows_frame_info->parameter_size);
714   }
715 
716   {  // To avoid reusing locals by mistake
717     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
718     EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
719     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
720                | StackFrameX86::CONTEXT_VALID_ESP
721                | StackFrameX86::CONTEXT_VALID_EBP),
722               frame1->context_validity);
723     EXPECT_EQ(0x5000aa95U, frame1->instruction + 1);
724     EXPECT_EQ(0x5000aa95U, frame1->context.eip);
725     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
726     EXPECT_EQ(0x6fa902e0U, frame1->context.ebp);
727     EXPECT_EQ(&module2, frame1->module);
728     EXPECT_EQ("module2::whine", frame1->function_name);
729     EXPECT_EQ(0x5000aa85U, frame1->function_base);
730     ASSERT_TRUE(frame1->windows_frame_info != NULL);
731     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid);
732     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
733               frame1->windows_frame_info->type_);
734     // This should not see the 0xbeef parameter size from the FUNC
735     // record, but should instead see the STACK WIN record.
736     EXPECT_EQ(4U, frame1->windows_frame_info->parameter_size);
737   }
738 
739   {  // To avoid reusing locals by mistake
740     StackFrameX86 *frame2 = static_cast<StackFrameX86 *>(frames->at(2));
741     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust);
742     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
743                | StackFrameX86::CONTEXT_VALID_ESP
744                | StackFrameX86::CONTEXT_VALID_EBP
745                | StackFrameX86::CONTEXT_VALID_EBX),
746               frame2->context_validity);
747     EXPECT_EQ(0x2a179e38U, frame2->instruction + 1);
748     EXPECT_EQ(0x2a179e38U, frame2->context.eip);
749     EXPECT_EQ(frame2_esp.Value(), frame2->context.esp);
750     EXPECT_EQ(frame2_ebp.Value(), frame2->context.ebp);
751     EXPECT_EQ(0x2558c7f3U, frame2->context.ebx);
752     EXPECT_EQ(NULL, frame2->module);
753     EXPECT_EQ(NULL, frame2->windows_frame_info);
754   }
755 }
756 
757 // Use Windows frame data (a "STACK WIN 4" record, from a
758 // FrameTypeFrameData DIA record) to walk a stack frame, where the
759 // expression fails to yield both an $eip and an $ebp value, and the stack
760 // walker must scan.
TEST_F(GetCallerFrame,WindowsFrameDataScan)761 TEST_F(GetCallerFrame, WindowsFrameDataScan) {
762   SetModuleSymbols(&module1,
763                    "STACK WIN 4 c8c 111 0 0 4 10 4 0 1 bad program string\n");
764   // Mark frame 1's PC as the end of the stack.
765   SetModuleSymbols(&module2,
766                    "FUNC 7c38 accf 0 module2::function\n"
767                    "STACK WIN 4 7c38 accf 0 0 4 10 4 0 1 $eip 0 = $ebp 0 =\n");
768   Label frame1_esp;
769   stack_section.start() = 0x80000000;
770   stack_section
771     // frame 0
772     .Append(16, 0x2a)                   // unused, garbage
773     .D32(0x50007ce9)                    // return address
774     // frame 1
775     .Mark(&frame1_esp)
776     .Append(8, 0);                      // empty space
777 
778   RegionFromSection();
779   raw_context.eip = 0x40000c9c;
780   raw_context.esp = stack_section.start().Value();
781   raw_context.ebp = 0x2ae314cd;         // should not be needed to walk frame
782 
783   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
784   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
785                         &frame_symbolizer);
786   vector<const CodeModule*> modules_without_symbols;
787   vector<const CodeModule*> modules_with_corrupt_symbols;
788   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
789                           &modules_with_corrupt_symbols));
790   ASSERT_EQ(0U, modules_without_symbols.size());
791   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
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(0x40000c9cU, frame0->instruction);
800     EXPECT_EQ(0x40000c9cU, frame0->context.eip);
801     EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
802     EXPECT_EQ(0x2ae314cdU, frame0->context.ebp);
803     EXPECT_TRUE(frame0->windows_frame_info != NULL);
804   }
805 
806   {  // To avoid reusing locals by mistake
807     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
808     EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
809     // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the walker
810     // does not actually fetch the EBP after a scan (forcing the next frame
811     // to be scanned as well). But let's grandfather the existing behavior in
812     // for now.
813     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
814                | StackFrameX86::CONTEXT_VALID_ESP
815                | StackFrameX86::CONTEXT_VALID_EBP),
816               frame1->context_validity);
817     EXPECT_EQ(0x50007ce9U, frame1->instruction + 1);
818     EXPECT_EQ(0x50007ce9U, frame1->context.eip);
819     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
820     EXPECT_TRUE(frame1->windows_frame_info != NULL);
821   }
822 }
823 
824 // Use Windows frame data (a "STACK WIN 4" record, from a
825 // FrameTypeFrameData DIA record) to walk a stack frame, where the
826 // expression yields an $eip that falls outside of any module, and the
827 // stack walker must scan.
TEST_F(GetCallerFrame,WindowsFrameDataBadEIPScan)828 TEST_F(GetCallerFrame, WindowsFrameDataBadEIPScan) {
829   SetModuleSymbols(&module1,
830                    "STACK WIN 4 6e6 e7 0 0 0 8 4 0 1"
831                    // A traditional frame, actually.
832                    " $eip $ebp 4 + ^ = $esp $ebp 8 + = $ebp $ebp ^ =\n");
833   // Mark frame 1's PC as the end of the stack.
834   SetModuleSymbols(&module2,
835                    "FUNC cfdb 8406 0 module2::function\n"
836                    "STACK WIN 4 cfdb 8406 0 0 0 0 0 0 1 $eip 0 = $ebp 0 =\n");
837   stack_section.start() = 0x80000000;
838 
839   // In this stack, the context's %ebp is pointing at the wrong place, so
840   // the stack walker needs to scan to find the return address, and then
841   // scan again to find the caller's saved %ebp.
842   Label frame0_ebp, frame1_ebp, frame1_esp;
843   stack_section
844     // frame 0
845     .Append(8, 0x2a)            // garbage
846     .Mark(&frame0_ebp)          // frame 0 %ebp points here, but should point
847                                 // at *** below
848     // The STACK WIN record says that the following two values are
849     // frame 1's saved %ebp and return address, but the %ebp is wrong;
850     // they're garbage. The stack walker will scan for the right values.
851     .D32(0x3d937b2b)            // alleged to be frame 1's saved %ebp
852     .D32(0x17847f5b)            // alleged to be frame 1's return address
853     .D32(frame1_ebp)            // frame 1's real saved %ebp; scan will find
854     .D32(0x2b2b2b2b)            // first word of realigned register save area
855     // *** frame 0 %ebp ought to be pointing here
856     .D32(0x2c2c2c2c)            // realigned locals area
857     .D32(0x5000d000)            // frame 1's real saved %eip; scan will find
858     // Frame 1, in module2::function. The STACK WIN record describes
859     // this as the oldest frame, without referring to its contents, so
860     // we needn't to provide any actual data here.
861     .Mark(&frame1_esp)
862     .Mark(&frame1_ebp)          // frame 1 %ebp points here
863     // A dummy value for frame 1's %ebp to point at. The scan recognizes the
864     // saved %ebp because it points to a valid word in the stack memory region.
865     .D32(0x2d2d2d2d);
866 
867   RegionFromSection();
868   raw_context.eip = 0x40000700;
869   raw_context.esp = stack_section.start().Value();
870   raw_context.ebp = frame0_ebp.Value();
871 
872   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
873   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
874                         &frame_symbolizer);
875   vector<const CodeModule*> modules_without_symbols;
876   vector<const CodeModule*> modules_with_corrupt_symbols;
877   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
878                           &modules_with_corrupt_symbols));
879   ASSERT_EQ(0U, modules_without_symbols.size());
880   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
881   frames = call_stack.frames();
882   ASSERT_EQ(2U, frames->size());
883 
884   {  // To avoid reusing locals by mistake
885     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
886     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
887     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
888     EXPECT_EQ(0x40000700U, frame0->instruction);
889     EXPECT_EQ(0x40000700U, frame0->context.eip);
890     EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
891     EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
892     EXPECT_TRUE(frame0->windows_frame_info != NULL);
893   }
894 
895   {  // To avoid reusing locals by mistake
896     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
897     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI_SCAN, frame1->trust);
898     // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the
899     // walker does not actually fetch the EBP after a scan (forcing the
900     // next frame to be scanned as well). But let's grandfather the existing
901     // behavior in for now.
902     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
903                | StackFrameX86::CONTEXT_VALID_ESP
904                | StackFrameX86::CONTEXT_VALID_EBP),
905               frame1->context_validity);
906     EXPECT_EQ(0x5000d000U, frame1->instruction + 1);
907     EXPECT_EQ(0x5000d000U, frame1->context.eip);
908     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
909     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
910     EXPECT_TRUE(frame1->windows_frame_info != NULL);
911   }
912 }
913 
914 // Use Windows FrameTypeFPO data to walk a stack frame for a function that
915 // does not modify %ebp from the value it had in the caller.
TEST_F(GetCallerFrame,WindowsFPOUnchangedEBP)916 TEST_F(GetCallerFrame, WindowsFPOUnchangedEBP) {
917   SetModuleSymbols(&module1,
918                    // Note bogus parameter size in FUNC record; the walker
919                    // should prefer the STACK WIN record, and see the '8' below.
920                    "FUNC e8a8 100 feeb module1::discombobulated\n"
921                    "STACK WIN 0 e8a8 100 0 0 8 4 10 0 0 0\n");
922   Label frame0_esp;
923   Label frame1_esp, frame1_ebp;
924   stack_section.start() = 0x80000000;
925   stack_section
926     // frame 0, in module1::wheedle.  FrameTypeFPO (STACK WIN 0) frame.
927     .Mark(&frame0_esp)
928     // no outgoing parameters; this is the youngest frame.
929     .D32(0x7c521352)     // four bytes of saved registers
930     .Append(0x10, 0x42)  // local area
931     .D32(0x40009b5b)     // return address, in module1, no function
932     // frame 1, in module1, no function.
933     .Mark(&frame1_esp)
934     .D32(0xf60ea7fc)     // junk
935     .Mark(&frame1_ebp)
936     .D32(0)              // saved %ebp (stack end)
937     .D32(0);             // saved %eip (stack end)
938 
939   RegionFromSection();
940   raw_context.eip = 0x4000e8b8;  // in module1::whine
941   raw_context.esp = stack_section.start().Value();
942   // Frame pointer unchanged from caller.
943   raw_context.ebp = frame1_ebp.Value();
944 
945   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
946   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
947                         &frame_symbolizer);
948   vector<const CodeModule*> modules_without_symbols;
949   vector<const CodeModule*> modules_with_corrupt_symbols;
950   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
951                           &modules_with_corrupt_symbols));
952   ASSERT_EQ(0U, modules_without_symbols.size());
953   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
954   frames = call_stack.frames();
955   ASSERT_EQ(2U, frames->size());
956 
957   {  // To avoid reusing locals by mistake
958     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
959     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
960     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
961     EXPECT_EQ(0x4000e8b8U, frame0->instruction);
962     EXPECT_EQ(0x4000e8b8U, frame0->context.eip);
963     EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
964     // unchanged from caller
965     EXPECT_EQ(frame1_ebp.Value(), frame0->context.ebp);
966     EXPECT_EQ(&module1, frame0->module);
967     EXPECT_EQ("module1::discombobulated", frame0->function_name);
968     EXPECT_EQ(0x4000e8a8U, frame0->function_base);
969     // The STACK WIN record for module1::discombobulated should have
970     // produced a fully populated WindowsFrameInfo structure.
971     ASSERT_TRUE(frame0->windows_frame_info != NULL);
972     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
973     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
974               frame0->windows_frame_info->type_);
975     EXPECT_EQ(0x10U, frame0->windows_frame_info->local_size);
976   }
977 
978   {  // To avoid reusing locals by mistake
979     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
980     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
981     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
982                | StackFrameX86::CONTEXT_VALID_ESP
983                | StackFrameX86::CONTEXT_VALID_EBP
984                | StackFrameX86::CONTEXT_VALID_EBX),
985               frame1->context_validity);
986     EXPECT_EQ(0x40009b5bU, frame1->instruction + 1);
987     EXPECT_EQ(0x40009b5bU, frame1->context.eip);
988     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
989     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
990     EXPECT_EQ(&module1, frame1->module);
991     EXPECT_EQ("", frame1->function_name);
992     EXPECT_EQ(NULL, frame1->windows_frame_info);
993   }
994 }
995 
996 // Use Windows FrameTypeFPO data to walk a stack frame for a function
997 // that uses %ebp for its own purposes, saving the value it had in the
998 // caller in the standard place in the saved register area.
TEST_F(GetCallerFrame,WindowsFPOUsedEBP)999 TEST_F(GetCallerFrame, WindowsFPOUsedEBP) {
1000   SetModuleSymbols(&module1,
1001                    // Note bogus parameter size in FUNC record; the walker
1002                    // should prefer the STACK WIN record, and see the '8' below.
1003                    "FUNC 9aa8 e6 abbe module1::RaisedByTheAliens\n"
1004                    "STACK WIN 0 9aa8 e6 a 0 10 8 4 0 0 1\n");
1005   Label frame0_esp;
1006   Label frame1_esp, frame1_ebp;
1007   stack_section.start() = 0x80000000;
1008   stack_section
1009     // frame 0, in module1::wheedle.  FrameTypeFPO (STACK WIN 0) frame.
1010     .Mark(&frame0_esp)
1011     // no outgoing parameters; this is the youngest frame.
1012     .D32(frame1_ebp)    // saved register area: saved %ebp
1013     .D32(0xb68bd5f9)    // saved register area: something else
1014     .D32(0xd25d05fc)    // local area
1015     .D32(0x4000debe)    // return address, in module1, no function
1016     // frame 1, in module1, no function.
1017     .Mark(&frame1_esp)
1018     .D32(0xf0c9a974)    // junk
1019     .Mark(&frame1_ebp)
1020     .D32(0)             // saved %ebp (stack end)
1021     .D32(0);            // saved %eip (stack end)
1022 
1023   RegionFromSection();
1024   raw_context.eip = 0x40009ab8;  // in module1::RaisedByTheAliens
1025   raw_context.esp = stack_section.start().Value();
1026   // RaisedByTheAliens uses %ebp for its own mysterious purposes.
1027   raw_context.ebp = 0xecbdd1a5;
1028 
1029   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
1030   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
1031                         &frame_symbolizer);
1032   vector<const CodeModule*> modules_without_symbols;
1033   vector<const CodeModule*> modules_with_corrupt_symbols;
1034   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
1035                           &modules_with_corrupt_symbols));
1036   ASSERT_EQ(0U, modules_without_symbols.size());
1037   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
1038   frames = call_stack.frames();
1039   ASSERT_EQ(2U, frames->size());
1040 
1041   {  // To avoid reusing locals by mistake
1042     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
1043     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
1044     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
1045     EXPECT_EQ(0x40009ab8U, frame0->instruction);
1046     EXPECT_EQ(0x40009ab8U, frame0->context.eip);
1047     EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
1048     EXPECT_EQ(0xecbdd1a5, frame0->context.ebp);
1049     EXPECT_EQ(&module1, frame0->module);
1050     EXPECT_EQ("module1::RaisedByTheAliens", frame0->function_name);
1051     EXPECT_EQ(0x40009aa8U, frame0->function_base);
1052     // The STACK WIN record for module1::RaisedByTheAliens should have
1053     // produced a fully populated WindowsFrameInfo structure.
1054     ASSERT_TRUE(frame0->windows_frame_info != NULL);
1055     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
1056     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
1057               frame0->windows_frame_info->type_);
1058     EXPECT_EQ("", frame0->windows_frame_info->program_string);
1059     EXPECT_TRUE(frame0->windows_frame_info->allocates_base_pointer);
1060   }
1061 
1062   {  // To avoid reusing locals by mistake
1063     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
1064     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
1065     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
1066                | StackFrameX86::CONTEXT_VALID_ESP
1067                | StackFrameX86::CONTEXT_VALID_EBP),
1068               frame1->context_validity);
1069     EXPECT_EQ(0x4000debeU, frame1->instruction + 1);
1070     EXPECT_EQ(0x4000debeU, frame1->context.eip);
1071     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
1072     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
1073     EXPECT_EQ(&module1, frame1->module);
1074     EXPECT_EQ("", frame1->function_name);
1075     EXPECT_EQ(NULL, frame1->windows_frame_info);
1076   }
1077 }
1078 
1079 // This is a regression test for FPO code that references the initial value of
1080 // EBX.
TEST_F(GetCallerFrame,WindowsFPOReferencesEBX)1081 TEST_F(GetCallerFrame, WindowsFPOReferencesEBX) {
1082   MockCodeModule ntdll(0x776e0000, 0x142000, "ntdll", "ntdllver");
1083   MockCodeModule kernel32(0x77250000, 0xd5000, "kernel32", "kernel32ver");
1084   MockCodeModule chrome_child(0x5a710000, 0x2b7c000, "chrome_child",
1085                               "chrome_childver");
1086   MockCodeModules modules;
1087   modules.Add(&ntdll);
1088   modules.Add(&kernel32);
1089   modules.Add(&chrome_child);
1090   SetModuleSymbols(&ntdll,
1091                    "PUBLIC 46bf4 0 KiFastSystemCallRet\n"
1092                    "STACK WIN 0 46bf4 1 0 0 0 0 0 0 0 0\n"
1093 
1094                    "PUBLIC 46550 10 NtWaitForKeyedEvent\n"
1095                    "STACK WIN 0 46550 f 0 0 10 0 0 0 0 0\n"
1096 
1097                    "PUBLIC 4965 10 RtlSleepConditionVariableSRW\n"
1098 
1099                    "STACK WIN 4 4965 23 23 0 10 8 38 0 1 $T0 $ebx = "
1100                    "$eip $T0 4 + ^ = $ebx $T0 ^ = $esp $T0 8 + = "
1101                    "$ebp $ebp ^ = $L $ebp = $P $T0 8 + .cbParams + =\n"
1102 
1103                    "STACK WIN 4 4988 e3 0 0 10 8 38 0 1 $T0 $ebx = "
1104                    "$eip $T0 4 + ^ = $ebx $T0 ^ = $esp $T0 8 + = "
1105                    "$ebp $ebp ^ = $L $ebp = $P $T0 8 + .cbParams + =\n"
1106 
1107                    "STACK WIN 4 4b2e b 0 0 10 8 38 0 1 $T0 $ebx = "
1108                    "$eip $T0 4 + ^ = $ebx $T0 ^ = $esp $T0 8 + = "
1109                    "$ebp $ebp ^ = $L $ebp = $P $T0 8 + .cbParams + =\n");
1110 
1111   SetModuleSymbols(&kernel32,
1112                    "PUBLIC 3217a 10 SleepConditionVariableSRW\n"
1113                    "STACK WIN 4 3217a 40 8 0 10 0 8 0 1 $T0 $ebp = $eip $T0 4 "
1114                    "+ ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs - = "
1115                    "$P $T0 8 + .cbParams + =\n");
1116 
1117   SetModuleSymbols(&chrome_child,
1118                    "FUNC 4f4851 20 0 base::ConditionVariable::TimedWait\n");
1119 
1120   stack_section.start() = 0x0026c048;
1121   stack_section
1122       .D32(0x7772655c)
1123       .D32(0x776e4a3f)
1124       .D32(0x00000000)
1125       .D32(0x0026c070)
1126       .D32(0x00000000)
1127       .D32(0x00000000)
1128       .D32(0x00000001)
1129       .D32(0x0026c168)
1130       .D32(0x00000000)
1131       .D32(0x00000000)
1132       .D32(0x00000000)
1133       .D32(0x0026c070)
1134       .D32(0x00000000)
1135       .D32(0x00000000)
1136       .D32(0x00000000)
1137       .D32(0x0026c164)
1138       .D32(0x00be0000)
1139       .D32(0x0026fc60)
1140       .D32(0x0026c164)
1141       .D32(0x00000000)
1142       .D32(0xfffffffe)
1143       .D32(0x00000000)
1144       .D32(0x0026c0d0)
1145       .D32(0x7728219e)
1146       .D32(0x000003e8)
1147       .D32(0x00000000)
1148       .D32(0x7728219e)
1149       .D32(0x0026c168)
1150       .D32(0x0026c164)
1151       .D32(0x00000000)
1152       .D32(0x00000000)
1153       .D32(0x0026c168)
1154       .D32(0x000003e8)
1155       .D32(0x000003e8)
1156       .D32(0x0026c0ec)
1157       .D32(0x5ac0486c)
1158       .D32(0x0026c168)
1159       .D32(0x0026c108)
1160       .D32(0x5ac0484c)
1161       .D32(0x0026c100)
1162       .D32(0x0026c160);
1163 
1164   RegionFromSection();
1165   raw_context.eip = 0x77726bf4; // in ntdll!KiFastSystemCallRet
1166   raw_context.esp = stack_section.start().Value();
1167   raw_context.ebp = 0x26c0a0;
1168   raw_context.ebx = 0x26c0ac;
1169 
1170   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
1171   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
1172                         &frame_symbolizer);
1173   vector<const CodeModule *> modules_without_symbols;
1174   vector<const CodeModule *> modules_with_corrupt_symbols;
1175   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
1176                           &modules_with_corrupt_symbols));
1177   ASSERT_EQ(0U, modules_without_symbols.size());
1178   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
1179   frames = call_stack.frames();
1180 
1181   ASSERT_EQ(5U, frames->size());
1182   {
1183     const StackFrameX86 &frame = *static_cast<StackFrameX86 *>(frames->at(0));
1184     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame.trust);
1185     EXPECT_EQ(0x77726bf4U, frame.context.eip);
1186     EXPECT_EQ("KiFastSystemCallRet", frame.function_name);
1187   }
1188   {
1189     const StackFrameX86 &frame = *static_cast<StackFrameX86 *>(frames->at(1));
1190     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame.trust);
1191     EXPECT_EQ(0x7772655cU, frame.context.eip);
1192     EXPECT_EQ("NtWaitForKeyedEvent", frame.function_name);
1193   }
1194   {
1195     const StackFrameX86 &frame = *static_cast<StackFrameX86 *>(frames->at(2));
1196     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame.trust);
1197     EXPECT_EQ(0x776e4a3fU, frame.context.eip);
1198     EXPECT_EQ("RtlSleepConditionVariableSRW", frame.function_name);
1199   }
1200   {
1201     const StackFrameX86 &frame = *static_cast<StackFrameX86 *>(frames->at(3));
1202     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame.trust);
1203     EXPECT_EQ(0x7728219eU, frame.context.eip);
1204     EXPECT_EQ("SleepConditionVariableSRW", frame.function_name);
1205   }
1206   {
1207     const StackFrameX86 &frame = *static_cast<StackFrameX86 *>(frames->at(4));
1208     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame.trust);
1209     EXPECT_EQ(0x5ac0486cU, frame.context.eip);
1210     EXPECT_EQ("base::ConditionVariable::TimedWait", frame.function_name);
1211   }
1212 }
1213 
1214 // This is a regression unit test which covers a bug which has to do with
1215 // FPO-optimized Windows system call stubs in the context frame.  There is
1216 // a more recent Windows system call dispatch mechanism which differs from
1217 // the one which is being tested here.  The newer system call dispatch
1218 // mechanism creates an extra context frame (KiFastSystemCallRet).
TEST_F(GetCallerFrame,WindowsFPOSystemCall)1219 TEST_F(GetCallerFrame, WindowsFPOSystemCall) {
1220   SetModuleSymbols(&module3,  // ntdll.dll
1221                    "PUBLIC 1f8ac c ZwWaitForSingleObject\n"
1222                    "STACK WIN 0 1f8ac 1b 0 0 c 0 0 0 0 0\n");
1223   SetModuleSymbols(&module4,  // kernelbase.dll
1224                    "PUBLIC 109f9 c WaitForSingleObjectEx\n"
1225                    "PUBLIC 36590 0 _except_handler4\n"
1226                    "STACK WIN 4 109f9 df c 0 c c 48 0 1 $T0 $ebp = $eip "
1227                    "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
1228                    "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n"
1229                    "STACK WIN 4 36590 154 17 0 10 0 14 0 1 $T0 $ebp = $eip "
1230                    "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 "
1231                    ".cbSavedRegs - = $P $T0 8 + .cbParams + =\n");
1232   SetModuleSymbols(&module5,  // kernel32.dll
1233                    "PUBLIC 11136 8 WaitForSingleObject\n"
1234                    "PUBLIC 11151 c WaitForSingleObjectExImplementation\n"
1235                    "STACK WIN 4 11136 16 5 0 8 0 0 0 1 $T0 $ebp = $eip "
1236                    "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
1237                    "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n"
1238                    "STACK WIN 4 11151 7a 5 0 c 0 0 0 1 $T0 $ebp = $eip "
1239                    "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
1240                    "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n");
1241   SetModuleSymbols(&module6,  // chrome.dll
1242                    "FILE 7038 some_file_name.h\n"
1243                    "FILE 839776 some_file_name.cc\n"
1244                    "FUNC 217fda 17 4 function_217fda\n"
1245                    "217fda 4 102 839776\n"
1246                    "FUNC 217ff1 a 4 function_217ff1\n"
1247                    "217ff1 0 594 7038\n"
1248                    "217ff1 a 596 7038\n"
1249                    "STACK WIN 0 217ff1 a 0 0 4 0 0 0 0 0\n");
1250 
1251   Label frame0_esp, frame1_esp;
1252   Label frame1_ebp, frame2_ebp, frame3_ebp;
1253   stack_section.start() = 0x002ff290;
1254   stack_section
1255     .Mark(&frame0_esp)
1256     .D32(0x771ef8c1)    // EIP in frame 0 (system call)
1257     .D32(0x75fa0a91)    // return address of frame 0
1258     .Mark(&frame1_esp)
1259     .D32(0x000017b0)    // args to child
1260     .D32(0x00000000)
1261     .D32(0x002ff2d8)
1262     .D32(0x88014a2e)
1263     .D32(0x002ff364)
1264     .D32(0x000017b0)
1265     .D32(0x00000000)
1266     .D32(0x00000024)
1267     .D32(0x00000001)
1268     .D32(0x00000000)
1269     .D32(0x00000000)
1270     .D32(0x00000000)
1271     .D32(0x00000000)
1272     .D32(0x00000000)
1273     .D32(0x00000000)
1274     .D32(0x00000000)
1275     .D32(0x9e3b9800)
1276     .D32(0xfffffff7)
1277     .D32(0x00000000)
1278     .D32(0x002ff2a4)
1279     .D32(0x64a07ff1)    // random value to be confused with a return address
1280     .D32(0x002ff8dc)
1281     .D32(0x75fc6590)    // random value to be confused with a return address
1282     .D32(0xfdd2c6ea)
1283     .D32(0x00000000)
1284     .Mark(&frame1_ebp)
1285     .D32(frame2_ebp)    // Child EBP
1286     .D32(0x75741194)    // return address of frame 1
1287     .D32(0x000017b0)    // args to child
1288     .D32(0x0036ee80)
1289     .D32(0x00000000)
1290     .D32(0x65bc7d14)
1291     .Mark(&frame2_ebp)
1292     .D32(frame3_ebp)    // Child EBP
1293     .D32(0x75741148)    // return address of frame 2
1294     .D32(0x000017b0)    // args to child
1295     .D32(0x0036ee80)
1296     .D32(0x00000000)
1297     .Mark(&frame3_ebp)
1298     .D32(0)             // saved %ebp (stack end)
1299     .D32(0);            // saved %eip (stack end)
1300 
1301   RegionFromSection();
1302   raw_context.eip = 0x771ef8c1;  // in ntdll::ZwWaitForSingleObject
1303   raw_context.esp = stack_section.start().Value();
1304   ASSERT_TRUE(raw_context.esp == frame0_esp.Value());
1305   raw_context.ebp = frame1_ebp.Value();
1306 
1307   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
1308   StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
1309                         &frame_symbolizer);
1310   vector<const CodeModule*> modules_without_symbols;
1311   vector<const CodeModule*> modules_with_corrupt_symbols;
1312   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
1313                           &modules_with_corrupt_symbols));
1314   ASSERT_EQ(0U, modules_without_symbols.size());
1315   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
1316   frames = call_stack.frames();
1317 
1318   ASSERT_EQ(4U, frames->size());
1319 
1320   {  // To avoid reusing locals by mistake
1321     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
1322     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
1323     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
1324     EXPECT_EQ(0x771ef8c1U, frame0->instruction);
1325     EXPECT_EQ(0x771ef8c1U, frame0->context.eip);
1326     EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
1327     EXPECT_EQ(frame1_ebp.Value(), frame0->context.ebp);
1328     EXPECT_EQ(&module3, frame0->module);
1329     EXPECT_EQ("ZwWaitForSingleObject", frame0->function_name);
1330     // The STACK WIN record for module3!ZwWaitForSingleObject should have
1331     // produced a fully populated WindowsFrameInfo structure.
1332     ASSERT_TRUE(frame0->windows_frame_info != NULL);
1333     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
1334     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
1335               frame0->windows_frame_info->type_);
1336     EXPECT_EQ("", frame0->windows_frame_info->program_string);
1337     EXPECT_FALSE(frame0->windows_frame_info->allocates_base_pointer);
1338   }
1339 
1340   {  // To avoid reusing locals by mistake
1341     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
1342     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
1343     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
1344                | StackFrameX86::CONTEXT_VALID_ESP
1345                | StackFrameX86::CONTEXT_VALID_EBP
1346                | StackFrameX86::CONTEXT_VALID_EBX),
1347               frame1->context_validity);
1348     EXPECT_EQ(0x75fa0a91U, frame1->instruction + 1);
1349     EXPECT_EQ(0x75fa0a91U, frame1->context.eip);
1350     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
1351     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
1352     EXPECT_EQ(&module4, frame1->module);
1353     EXPECT_EQ("WaitForSingleObjectEx", frame1->function_name);
1354     // The STACK WIN record for module4!WaitForSingleObjectEx should have
1355     // produced a fully populated WindowsFrameInfo structure.
1356     ASSERT_TRUE(frame1->windows_frame_info != NULL);
1357     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid);
1358     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
1359               frame1->windows_frame_info->type_);
1360     EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
1361               "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =",
1362               frame1->windows_frame_info->program_string);
1363     EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer);
1364   }
1365 }
1366 
1367 // Scan the stack for a better return address and potentially skip frames
1368 // when the calculated return address is not in a known module.  Note, that
1369 // the span of this scan is somewhat arbitrarily limited to 160 search words
1370 // for the context frame and 40 search words (pointers) for the other frames:
1371 //     const int kRASearchWords = 40;
1372 // This means that frames can be skipped only when their size is relatively
1373 // small: smaller than 4 * kRASearchWords * sizeof(InstructionType)
TEST_F(GetCallerFrame,ReturnAddressIsNotInKnownModule)1374 TEST_F(GetCallerFrame, ReturnAddressIsNotInKnownModule) {
1375   MockCodeModule msvcrt_dll(0x77be0000, 0x58000, "msvcrt.dll", "version1");
1376   SetModuleSymbols(&msvcrt_dll,  // msvcrt.dll
1377                    "PUBLIC 38180 0 wcsstr\n"
1378                    "STACK WIN 4 38180 61 10 0 8 0 0 0 1 $T0 $ebp = $eip $T0 "
1379                    "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs "
1380                    "- = $P $T0 4 + .cbParams + =\n");
1381 
1382   MockCodeModule kernel32_dll(0x7c800000, 0x103000, "kernel32.dll", "version1");
1383   SetModuleSymbols(&kernel32_dll,  // kernel32.dll
1384                    "PUBLIC efda 8 FindNextFileW\n"
1385                    "STACK WIN 4 efda 1bb c 0 8 8 3c 0 1 $T0 $ebp = $eip $T0 "
1386                    "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs "
1387                    "- = $P $T0 4 + .cbParams + =\n");
1388 
1389   MockCodeModule chrome_dll(0x1c30000, 0x28C8000, "chrome.dll", "version1");
1390   SetModuleSymbols(&chrome_dll,  // chrome.dll
1391                    "FUNC e3cff 4af 0 file_util::FileEnumerator::Next()\n"
1392                    "e3cff 1a 711 2505\n"
1393                    "STACK WIN 4 e3cff 4af 20 0 4 c 94 0 1 $T1 .raSearch = "
1394                    "$T0  $T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp "
1395                    "$T1 4 + = $20 $T0 152 - ^ =  $23 $T0 156 - ^ =  $24 "
1396                    "$T0 160 - ^ =\n");
1397 
1398   // Create some modules with some stock debugging information.
1399   MockCodeModules local_modules;
1400   local_modules.Add(&msvcrt_dll);
1401   local_modules.Add(&kernel32_dll);
1402   local_modules.Add(&chrome_dll);
1403 
1404   Label frame0_esp;
1405   Label frame0_ebp;
1406   Label frame1_ebp;
1407   Label frame2_ebp;
1408   Label frame3_ebp;
1409 
1410   stack_section.start() = 0x0932f2d0;
1411   stack_section
1412     .Mark(&frame0_esp)
1413     .D32(0x0764e000)
1414     .D32(0x0764e068)
1415     .Mark(&frame0_ebp)
1416     .D32(frame1_ebp)    // Child EBP
1417     .D32(0x001767a0)    // return address of frame 0
1418                         // Not in known module
1419     .D32(0x0764e0c6)
1420     .D32(0x001bb1b8)
1421     .D32(0x0764e068)
1422     .D32(0x00000003)
1423     .D32(0x0764e068)
1424     .D32(0x00000003)
1425     .D32(0x07578828)
1426     .D32(0x0764e000)
1427     .D32(0x00000000)
1428     .D32(0x001c0010)
1429     .D32(0x0764e0c6)
1430     .Mark(&frame1_ebp)
1431     .D32(frame2_ebp)    // Child EBP
1432     .D32(0x7c80f10f)    // return address of frame 1
1433                         // inside kernel32!FindNextFileW
1434     .D32(0x000008f8)
1435     .D32(0x00000000)
1436     .D32(0x00000000)
1437     .D32(0x00000000)
1438     .D32(0x0932f34c)
1439     .D32(0x0764e000)
1440     .D32(0x00001000)
1441     .D32(0x00000000)
1442     .D32(0x00000001)
1443     .D32(0x00000000)
1444     .D32(0x00000000)
1445     .D32(0x0932f6a8)
1446     .D32(0x00000000)
1447     .D32(0x0932f6d8)
1448     .D32(0x00000000)
1449     .D32(0x000000d6)
1450     .D32(0x0764e000)
1451     .D32(0x7ff9a000)
1452     .D32(0x0932f3fc)
1453     .D32(0x00000001)
1454     .D32(0x00000001)
1455     .D32(0x07578828)
1456     .D32(0x0000002e)
1457     .D32(0x0932f340)
1458     .D32(0x0932eef4)
1459     .D32(0x0932ffdc)
1460     .D32(0x7c839ad8)
1461     .D32(0x7c80f0d8)
1462     .D32(0x00000000)
1463     .Mark(&frame2_ebp)
1464     .D32(frame3_ebp)    // Child EBP
1465     .D32(0x01d13f91)    // return address of frame 2
1466                         // inside chrome_dll!file_util::FileEnumerator::Next
1467     .D32(0x07578828)
1468     .D32(0x0932f6ac)
1469     .D32(0x0932f9c4)
1470     .D32(0x0932f9b4)
1471     .D32(0x00000000)
1472     .D32(0x00000003)
1473     .D32(0x0932f978)
1474     .D32(0x01094330)
1475     .D32(0x00000000)
1476     .D32(0x00000001)
1477     .D32(0x01094330)
1478     .D32(0x00000000)
1479     .D32(0x00000000)
1480     .D32(0x07f30000)
1481     .D32(0x01c3ba17)
1482     .D32(0x08bab840)
1483     .D32(0x07f31580)
1484     .D32(0x00000000)
1485     .D32(0x00000007)
1486     .D32(0x0932f940)
1487     .D32(0x0000002e)
1488     .D32(0x0932f40c)
1489     .D32(0x01d13b53)
1490     .D32(0x0932f958)
1491     .D32(0x00000001)
1492     .D32(0x00000007)
1493     .D32(0x0932f940)
1494     .D32(0x0000002e)
1495     .D32(0x00000000)
1496     .D32(0x0932f6ac)
1497     .D32(0x01e13ef0)
1498     .D32(0x00000001)
1499     .D32(0x00000007)
1500     .D32(0x0932f958)
1501     .D32(0x08bab840)
1502     .D32(0x0932f9b4)
1503     .D32(0x00000000)
1504     .D32(0x0932f9b4)
1505     .D32(0x000000a7)
1506     .D32(0x000000a7)
1507     .D32(0x0932f998)
1508     .D32(0x579627a2)
1509     .Mark(&frame3_ebp)
1510     .D32(0)             // saved %ebp (stack end)
1511     .D32(0);            // saved %eip (stack end)
1512 
1513   RegionFromSection();
1514   raw_context.eip = 0x77c181cd;  // inside msvcrt!wcsstr
1515   raw_context.esp = frame0_esp.Value();
1516   raw_context.ebp = frame0_ebp.Value();
1517   // sanity
1518   ASSERT_TRUE(raw_context.esp == stack_section.start().Value());
1519   ASSERT_TRUE(raw_context.ebp == stack_section.start().Value() + 8);
1520 
1521   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
1522   StackwalkerX86 walker(&system_info, &raw_context, &stack_region,
1523                         &local_modules, &frame_symbolizer);
1524   vector<const CodeModule*> modules_without_symbols;
1525   vector<const CodeModule*> modules_with_corrupt_symbols;
1526   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
1527                           &modules_with_corrupt_symbols));
1528   ASSERT_EQ(0U, modules_without_symbols.size());
1529   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
1530   frames = call_stack.frames();
1531 
1532   ASSERT_EQ(3U, frames->size());
1533 
1534   {  // To avoid reusing locals by mistake
1535     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
1536     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
1537     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
1538     EXPECT_EQ(0x77c181cdU, frame0->instruction);
1539     EXPECT_EQ(0x77c181cdU, frame0->context.eip);
1540     EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
1541     EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
1542     EXPECT_EQ(&msvcrt_dll, frame0->module);
1543     EXPECT_EQ("wcsstr", frame0->function_name);
1544     ASSERT_TRUE(frame0->windows_frame_info != NULL);
1545     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
1546     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
1547               frame0->windows_frame_info->type_);
1548     EXPECT_EQ("$T0 $ebp = $eip $T0 "
1549               "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs "
1550               "- = $P $T0 4 + .cbParams + =",
1551               frame0->windows_frame_info->program_string);
1552     // It has program string, so allocates_base_pointer is not expected
1553     EXPECT_FALSE(frame0->windows_frame_info->allocates_base_pointer);
1554   }
1555 
1556   {  // To avoid reusing locals by mistake
1557     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
1558     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI_SCAN, frame1->trust);
1559     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
1560                StackFrameX86::CONTEXT_VALID_ESP |
1561                StackFrameX86::CONTEXT_VALID_EBP),
1562               frame1->context_validity);
1563     EXPECT_EQ(0x7c80f10fU, frame1->instruction + 1);
1564     EXPECT_EQ(0x7c80f10fU, frame1->context.eip);
1565     // frame 1 was skipped, so intead of frame1_ebp compare with frame2_ebp.
1566     EXPECT_EQ(frame2_ebp.Value(), frame1->context.ebp);
1567     EXPECT_EQ(&kernel32_dll, frame1->module);
1568     EXPECT_EQ("FindNextFileW", frame1->function_name);
1569     ASSERT_TRUE(frame1->windows_frame_info != NULL);
1570     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid);
1571     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
1572               frame1->windows_frame_info->type_);
1573     EXPECT_EQ("$T0 $ebp = $eip $T0 "
1574               "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs "
1575               "- = $P $T0 4 + .cbParams + =",
1576               frame1->windows_frame_info->program_string);
1577     EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer);
1578   }
1579 
1580   {  // To avoid reusing locals by mistake
1581     StackFrameX86 *frame2 = static_cast<StackFrameX86 *>(frames->at(2));
1582     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust);
1583     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
1584                StackFrameX86::CONTEXT_VALID_ESP |
1585                StackFrameX86::CONTEXT_VALID_EBP),
1586               frame2->context_validity);
1587     EXPECT_EQ(0x01d13f91U, frame2->instruction + 1);
1588     EXPECT_EQ(0x01d13f91U, frame2->context.eip);
1589     // frame 1 was skipped, so intead of frame2_ebp compare with frame3_ebp.
1590     EXPECT_EQ(frame3_ebp.Value(), frame2->context.ebp);
1591     EXPECT_EQ(&chrome_dll, frame2->module);
1592     EXPECT_EQ("file_util::FileEnumerator::Next()", frame2->function_name);
1593     ASSERT_TRUE(frame2->windows_frame_info != NULL);
1594     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame2->windows_frame_info->valid);
1595     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
1596               frame2->windows_frame_info->type_);
1597     EXPECT_EQ("$T1 .raSearch = "
1598               "$T0  $T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp "
1599               "$T1 4 + = $20 $T0 152 - ^ =  $23 $T0 156 - ^ =  $24 "
1600               "$T0 160 - ^ =",
1601               frame2->windows_frame_info->program_string);
1602     EXPECT_FALSE(frame2->windows_frame_info->allocates_base_pointer);
1603   }
1604 }
1605 
1606 // Test the .raSearchStart/.raSearch calculation when alignment operators are
1607 // used in the program string.  The current %ebp must be valid and it is the
1608 // only reliable data point that can be used for that calculation.
TEST_F(GetCallerFrame,HandleAlignmentInProgramString)1609 TEST_F(GetCallerFrame, HandleAlignmentInProgramString) {
1610   MockCodeModule chrome_dll(0x59630000, 0x19e3000, "chrome.dll", "version1");
1611   SetModuleSymbols(&chrome_dll,  // chrome.dll
1612                    "FUNC 56422 50c 8 base::MessageLoop::RunTask"
1613                    "(base::PendingTask const &)\n"
1614                    "56422 e 458 4589\n"
1615                    "STACK WIN 4 56422 50c 11 0 8 c ac 0 1 $T1 .raSearch = $T0 "
1616                    "$T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + = "
1617                    "$20 $T0 176 - ^ =  $23 $T0 180 - ^ =  $24 $T0 184 - ^ =\n"
1618                    "FUNC 55d34 34a 0 base::MessageLoop::DoWork()\n"
1619                    "55d34 11 596 4589\n"
1620                    "STACK WIN 4 55d34 34a 19 0 0 c 134 0 1 $T1 .raSearch = "
1621                    "$T0  $T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp "
1622                    "$T1 4 + = $20 $T0 312 - ^ =  $23 $T0 316 - ^ =  $24 $T0 "
1623                    "320 - ^ =\n"
1624                    "FUNC 55c39 fb 0 base::MessagePumpForIO::DoRunLoop()\n"
1625                    "55c39 d 518 19962\n"
1626                    "STACK WIN 4 55c39 fb d 0 0 c 34 0 1 $T1 .raSearch = $T0 "
1627                    "$T1 4 - 64 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + "
1628                    "= $20 $T0 56 - ^ =  $23 $T0 60 - ^ =  $24 $T0 64 - ^ =\n"
1629                    "FUNC 55bf0 49 4 base::MessagePumpWin::Run(base::"
1630                    "MessagePump::Delegate *)\n"
1631                    "55bf0 49 48 4724\n"
1632                    "STACK WIN 4 55bf0 49 c 0 4 0 10 0 1 $T0 $ebp = $eip $T0 4 "
1633                    "+ ^ = $ebp $T0 ^ = $esp $T0 8 + =\n"
1634                    "FUNC 165d de 4 malloc\n"
1635                    "165d 6 119 54\n"
1636                    "STACK WIN 4 165d de d 0 4 8 0 0 1 $T1 .raSearch = $T0 "
1637                    "$T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 "
1638                    "+ = $23 $T0 4 - ^ =  $24 $T0 8 - ^ =\n"
1639                    "FUNC 55ac9 79 0 base::MessageLoop::RunInternal()\n"
1640                    "55ac9 d 427 4589\n"
1641                    "STACK WIN 4 55ac9 79 d 0 0 8 10 0 1 $T1 .raSearch = $T0 "
1642                    "$T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + = "
1643                    "$23 $T0 20 - ^ =  $24 $T0 24 - ^ =\n");
1644 
1645   // Create some modules with some stock debugging information.
1646   MockCodeModules local_modules;
1647   local_modules.Add(&chrome_dll);
1648 
1649   Label frame0_esp;
1650   Label frame0_ebp;
1651   Label frame1_esp;
1652   Label frame1_ebp;
1653   Label frame2_esp;
1654   Label frame2_ebp;
1655   Label frame3_esp;
1656   Label frame3_ebp;
1657 
1658   stack_section.start() = 0x046bfc80;
1659   stack_section
1660     .D32(0)
1661     .Mark(&frame0_esp)
1662     .D32(0x01e235a0)
1663     .D32(0x00000000)
1664     .D32(0x01e9f580)
1665     .D32(0x01e9f580)
1666     .D32(0x00000020)
1667     .D32(0x00000000)
1668     .D32(0x00463674)
1669     .D32(0x00000020)
1670     .D32(0x00000000)
1671     .D32(0x046bfcd8)
1672     .D32(0x046bfcd8)
1673     .D32(0x0001204b)
1674     .D32(0x00000000)
1675     .D32(0xfdddb523)
1676     .D32(0x00000000)
1677     .D32(0x00000007)
1678     .D32(0x00000040)
1679     .D32(0x00000000)
1680     .D32(0x59631693)  // chrome_59630000!malloc+0x36
1681     .D32(0x01e9f580)
1682     .D32(0x01e9f580)
1683     .D32(0x046bfcf8)
1684     .D32(0x77da6704)  // ntdll!NtSetIoCompletion+0xc
1685     .D32(0x046bfd4c)
1686     .D32(0x59685bec)  // chrome_59630000!base::MessageLoop::StartHistogrammer..
1687     .D32(0x01e235a0)
1688 
1689     .Mark(&frame0_ebp)
1690     .D32(frame1_ebp)  // Child EBP    .D32(0x046bfd0c)
1691     .D32(0x59685c2e)  // Return address in
1692                       // chrome_59630000!base::MessagePumpWin::Run+0x3e
1693     .Mark(&frame1_esp)
1694     .D32(0x01e75a90)
1695     .D32(0x046bfd4c)
1696     .D32(0x01e75a90)
1697     .D32(0x00000000)
1698     .D32(0x00000300)
1699     .D32(0x00000001)
1700 
1701     .Mark(&frame1_ebp)
1702     .D32(frame2_ebp)  // Child EBP    .D32(0x046bfd30)
1703     .D32(0x59685b3c)  // Return address in
1704                       // chrome_59630000!base::MessageLoop::RunInternal+0x73
1705     .Mark(&frame2_esp)
1706     .D32(0x01e75a90)
1707     .D32(0x00000000)
1708     .D32(0x046bfd4c)
1709     .D32(0x59658123)  // chrome_59630000!std::deque..
1710     .D32(0x046bfda0)
1711     .D32(0x01e79d70)
1712     .D32(0x046bfda0)
1713 
1714     .Mark(&frame2_ebp)  // .D32(0x046bfd40)
1715     .D32(0)             // saved %ebp (stack end)
1716     .D32(0);            // saved %eip (stack end)
1717 
1718   RegionFromSection();
1719   raw_context.eip = 0x59685c46;  // Context frame in
1720                                  // base::MessagePumpForIO::DoRunLoop
1721   raw_context.esp = frame0_esp.Value();
1722   raw_context.ebp = frame0_ebp.Value();
1723 
1724   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
1725   StackwalkerX86 walker(&system_info, &raw_context, &stack_region,
1726                         &local_modules, &frame_symbolizer);
1727   vector<const CodeModule*> modules_without_symbols;
1728   vector<const CodeModule*> modules_with_corrupt_symbols;
1729   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
1730                           &modules_with_corrupt_symbols));
1731   ASSERT_EQ(0U, modules_without_symbols.size());
1732   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
1733   frames = call_stack.frames();
1734 
1735   ASSERT_EQ(3U, frames->size());
1736 
1737   {  // To avoid reusing locals by mistake
1738     StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
1739     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame->trust);
1740     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame->context_validity);
1741     EXPECT_EQ("base::MessagePumpForIO::DoRunLoop()", frame->function_name);
1742     EXPECT_EQ(0x59685c46U, frame->instruction);
1743     EXPECT_EQ(0x59685c46U, frame->context.eip);
1744     EXPECT_EQ(frame0_esp.Value(), frame->context.esp);
1745     EXPECT_EQ(frame0_ebp.Value(), frame->context.ebp);
1746     EXPECT_EQ(&chrome_dll, frame->module);
1747     ASSERT_TRUE(frame->windows_frame_info != NULL);
1748     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame->windows_frame_info->valid);
1749     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
1750               frame->windows_frame_info->type_);
1751     EXPECT_EQ("$T1 .raSearch = $T0 "
1752               "$T1 4 - 64 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + "
1753               "= $20 $T0 56 - ^ =  $23 $T0 60 - ^ =  $24 $T0 64 - ^ =",
1754               frame->windows_frame_info->program_string);
1755     EXPECT_FALSE(frame->windows_frame_info->allocates_base_pointer);
1756   }
1757 
1758   {  // To avoid reusing locals by mistake
1759     StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(1));
1760     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame->trust);
1761     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
1762                StackFrameX86::CONTEXT_VALID_ESP |
1763                StackFrameX86::CONTEXT_VALID_EBP),
1764               frame->context_validity);
1765     EXPECT_EQ("base::MessagePumpWin::Run(base::MessagePump::Delegate *)",
1766               frame->function_name);
1767     EXPECT_EQ(1500011566U, frame->instruction + 1);
1768     EXPECT_EQ(1500011566U, frame->context.eip);
1769     EXPECT_EQ(frame1_esp.Value(), frame->context.esp);
1770     EXPECT_EQ(frame1_ebp.Value(), frame->context.ebp);
1771     EXPECT_EQ(&chrome_dll, frame->module);
1772     ASSERT_TRUE(frame->windows_frame_info != NULL);
1773     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame->windows_frame_info->valid);
1774     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
1775               frame->windows_frame_info->type_);
1776     EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =",
1777               frame->windows_frame_info->program_string);
1778     EXPECT_FALSE(frame->windows_frame_info->allocates_base_pointer);
1779   }
1780 
1781   {  // To avoid reusing locals by mistake
1782     StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(2));
1783     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame->trust);
1784     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
1785                StackFrameX86::CONTEXT_VALID_ESP |
1786                StackFrameX86::CONTEXT_VALID_EBP),
1787               frame->context_validity);
1788     EXPECT_EQ("base::MessageLoop::RunInternal()", frame->function_name);
1789     EXPECT_EQ(1500011324U, frame->instruction + 1);
1790     EXPECT_EQ(1500011324U, frame->context.eip);
1791     EXPECT_EQ(frame2_esp.Value(), frame->context.esp);
1792     EXPECT_EQ(frame2_ebp.Value(), frame->context.ebp);
1793     EXPECT_EQ(&chrome_dll, frame->module);
1794     ASSERT_TRUE(frame->windows_frame_info != NULL);
1795     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame->windows_frame_info->valid);
1796     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
1797               frame->windows_frame_info->type_);
1798     EXPECT_EQ("$T1 .raSearch = $T0 "
1799               "$T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp $T1 4 + = "
1800               "$23 $T0 20 - ^ =  $24 $T0 24 - ^ =",
1801               frame->windows_frame_info->program_string);
1802     EXPECT_FALSE(frame->windows_frame_info->allocates_base_pointer);
1803   }
1804 }
1805 
1806 // Scan the stack for a return address and potentially skip frames when the
1807 // current IP address is not in a known module.  Note, that that the span of
1808 // this scan is limited to 120 search words for the context frame and 30
1809 // search words (pointers) for the other frames:
1810 //     const int kRASearchWords = 30;
IPAddressIsNotInKnownModuleTestImpl(bool has_corrupt_symbols)1811 void GetCallerFrame::IPAddressIsNotInKnownModuleTestImpl(
1812     bool has_corrupt_symbols) {
1813   MockCodeModule remoting_core_dll(0x54080000, 0x501000, "remoting_core.dll",
1814                                    "version1");
1815   string symbols_func_section =
1816       "FUNC 137214 17d 10 PK11_Verify\n"
1817       "FUNC 15c834 37 14 nsc_ECDSAVerifyStub\n"
1818       "FUNC 1611d3 91 14 NSC_Verify\n"
1819       "FUNC 162ff7 60 4 sftk_SessionFromHandle\n";
1820   string symbols_stack_section =
1821                    "STACK WIN 4 137214 17d 9 0 10 0 10 0 1 $T0 $ebp = "
1822                    "$eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =\n"
1823                    "STACK WIN 4 15c834 37 6 0 14 0 18 0 1 $T0 $ebp = "
1824                    "$eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =\n"
1825                    "STACK WIN 4 1611d3 91 7 0 14 0 8 0 1 $T0 $ebp = "
1826                    "$eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =\n"
1827                    "STACK WIN 4 162ff7 60 5 0 4 0 0 0 1 $T0 $ebp = "
1828                    "$eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =\n";
1829 
1830   string symbols = symbols_func_section;
1831   if (has_corrupt_symbols) {
1832     symbols.append(string(1, '\0'));           // null terminator in the middle
1833     symbols.append("\n");
1834     symbols.append("FUNC 1234\n"               // invalid FUNC records
1835                    "FUNNC 1234\n"
1836                    "STACK WIN 4 1234 234 23 "  // invalid STACK record
1837                    "23423423 234 23 234 234 "
1838                    "234 23 234 23 234 234 "
1839                    "234 234 234\n");
1840   }
1841   symbols.append(symbols_stack_section);
1842   SetModuleSymbols(&remoting_core_dll, symbols);
1843 
1844   // Create some modules with some stock debugging information.
1845   MockCodeModules local_modules;
1846   local_modules.Add(&remoting_core_dll);
1847 
1848   Label frame0_esp;
1849   Label frame0_ebp;
1850   Label frame1_ebp;
1851   Label frame1_esp;
1852   Label frame2_ebp;
1853   Label frame2_esp;
1854   Label frame3_ebp;
1855   Label frame3_esp;
1856   Label bogus_stack_location_1;
1857   Label bogus_stack_location_2;
1858   Label bogus_stack_location_3;
1859 
1860   stack_section.start() = 0x01a3ea28;
1861   stack_section
1862     .Mark(&frame0_esp)
1863     .D32(bogus_stack_location_2)
1864     .D32(bogus_stack_location_1)
1865     .D32(0x042478e4)
1866     .D32(bogus_stack_location_2)
1867     .D32(0x00000000)
1868     .D32(0x041f0420)
1869     .D32(0x00000000)
1870     .D32(0x00000000)
1871     .D32(0x00000040)
1872     .D32(0x00000001)
1873     .D32(0x00b7e0d0)
1874     .D32(0x00000000)
1875     .D32(0x00000040)
1876     .D32(0x00000001)
1877     .D32(0x00b7f570)
1878     .Mark(&bogus_stack_location_1)
1879     .D32(0x00000000)
1880     .D32(0x00000040)
1881     .D32(0x00000008)
1882     .D32(0x04289530)
1883     .D32(0x00000000)
1884     .D32(0x00000040)
1885     .D32(0x00000008)
1886     .D32(0x00b7e910)
1887     .D32(0x00000000)
1888     .D32(0x00000040)
1889     .D32(0x00000008)
1890     .D32(0x00b7d998)
1891     .D32(0x00000000)
1892     .D32(0x00000040)
1893     .D32(0x00000008)
1894     .D32(0x00b7dec0)
1895     .Mark(&bogus_stack_location_2)
1896     .D32(0x00000000)
1897     .D32(0x00000040)
1898     .D32(0x00000008)
1899     .D32(0x04289428)
1900     .D32(0x00000000)
1901     .D32(0x00000040)
1902     .D32(0x00000008)
1903     .D32(0x00b7f258)
1904     .Mark(&bogus_stack_location_3)
1905     .D32(0x00000000)
1906     .D32(0x041f3560)
1907     .D32(0x00000041)
1908     .D32(0x00000020)
1909     .D32(0xffffffff)
1910     .Mark(&frame0_ebp)
1911     .D32(frame1_ebp)  // Child %ebp
1912     .D32(0x541dc866)  // return address of frame 0
1913                       // inside remoting_core!nsc_ECDSAVerifyStub+0x32
1914     .Mark(&frame1_esp)
1915     .D32(0x04247860)
1916     .D32(0x01a3eaec)
1917     .D32(0x01a3eaf8)
1918     .D32(0x541e304f)  // remoting_core!sftk_SessionFromHandle+0x58
1919     .D32(0x0404c620)
1920     .D32(0x00000040)
1921     .D32(0x01a3eb2c)
1922     .D32(0x01a3ec08)
1923     .D32(0x00000014)
1924     .Mark(&frame1_ebp)
1925     .D32(frame2_ebp)  // Child %ebp
1926     .D32(0x541e1234)  // return address of frame 1
1927                       // inside remoting_core!NSC_Verify+0x61
1928     .Mark(&frame2_esp)
1929     .D32(0x04247858)
1930     .D32(0x0404c620)
1931     .D32(0x00000040)
1932     .D32(0x01a3ec08)
1933     .D32(0x00000014)
1934     .D32(0x01000005)
1935     .D32(0x00b2f7a0)
1936     .D32(0x041f0420)
1937     .D32(0x041f3650)
1938     .Mark(&frame2_ebp)
1939     .D32(frame3_ebp)  // Child %ebp
1940     .D32(0x541b734d)  // return address of frame 1
1941                       // inside remoting_core!PK11_Verify+0x139
1942     .Mark(&frame3_esp)
1943     .D32(0x01000005)
1944     .D32(0x01a3ec08)
1945     .D32(0x00000014)
1946     .D32(0x0404c620)
1947     .D32(0x00000040)
1948     .D32(0x04073e00)
1949     .D32(0x04073e00)
1950     .D32(0x04247050)
1951     .D32(0x00001041)
1952     .D32(0x00000000)
1953     .D32(0x00000000)
1954     .D32(0x00000000)
1955     .Mark(&frame3_ebp)
1956     .D32(0)           // saved %ebp (stack end)
1957     .D32(0);          // saved %eip (stack end)
1958 
1959   RegionFromSection();
1960   raw_context.eip = 0x4247860;   // IP address not in known module
1961   raw_context.ebp = 0x5420362d;  // bogus
1962   raw_context.esp = frame0_esp.Value();
1963 
1964   // sanity
1965   ASSERT_TRUE(raw_context.esp == stack_section.start().Value());
1966 
1967   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
1968   StackwalkerX86 walker(&system_info, &raw_context, &stack_region,
1969                         &local_modules, &frame_symbolizer);
1970   vector<const CodeModule*> modules_without_symbols;
1971   vector<const CodeModule*> modules_with_corrupt_symbols;
1972   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
1973                           &modules_with_corrupt_symbols));
1974   ASSERT_EQ(0U, modules_without_symbols.size());
1975   if (has_corrupt_symbols) {
1976     ASSERT_EQ(1U, modules_with_corrupt_symbols.size());
1977     ASSERT_EQ("remoting_core.dll",
1978               modules_with_corrupt_symbols[0]->debug_file());
1979   } else {
1980     ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
1981   }
1982   frames = call_stack.frames();
1983 
1984   ASSERT_EQ(4U, frames->size());
1985 
1986   {  // To avoid reusing locals by mistake
1987     StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
1988     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
1989     ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
1990     EXPECT_EQ(raw_context.eip, frame0->context.eip);
1991     EXPECT_EQ(raw_context.ebp, frame0->context.ebp);
1992     EXPECT_EQ(raw_context.esp, frame0->context.esp);
1993     EXPECT_EQ(NULL, frame0->module);  // IP not in known module
1994     EXPECT_EQ("", frame0->function_name);
1995     ASSERT_EQ(NULL, frame0->windows_frame_info);
1996   }
1997 
1998   {  // To avoid reusing locals by mistake
1999     StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
2000     EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
2001     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
2002                StackFrameX86::CONTEXT_VALID_ESP |
2003                StackFrameX86::CONTEXT_VALID_EBP),
2004               frame1->context_validity);
2005     EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
2006     EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
2007     EXPECT_EQ(&remoting_core_dll, frame1->module);
2008     EXPECT_EQ("nsc_ECDSAVerifyStub", frame1->function_name);
2009     ASSERT_TRUE(frame1->windows_frame_info != NULL);
2010     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid);
2011     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
2012               frame1->windows_frame_info->type_);
2013     EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =",
2014               frame1->windows_frame_info->program_string);
2015     EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer);
2016   }
2017 
2018   {  // To avoid reusing locals by mistake
2019     StackFrameX86 *frame2 = static_cast<StackFrameX86 *>(frames->at(2));
2020     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust);
2021     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
2022                StackFrameX86::CONTEXT_VALID_ESP |
2023                StackFrameX86::CONTEXT_VALID_EBP),
2024               frame2->context_validity);
2025     EXPECT_EQ(frame2_ebp.Value(), frame2->context.ebp);
2026     EXPECT_EQ(frame2_esp.Value(), frame2->context.esp);
2027     EXPECT_EQ(&remoting_core_dll, frame2->module);
2028     EXPECT_EQ("NSC_Verify", frame2->function_name);
2029     ASSERT_TRUE(frame2->windows_frame_info != NULL);
2030     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame2->windows_frame_info->valid);
2031     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
2032               frame2->windows_frame_info->type_);
2033     EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =",
2034               frame2->windows_frame_info->program_string);
2035     EXPECT_FALSE(frame2->windows_frame_info->allocates_base_pointer);
2036   }
2037 
2038   {  // To avoid reusing locals by mistake
2039     StackFrameX86 *frame3 = static_cast<StackFrameX86 *>(frames->at(3));
2040     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame3->trust);
2041     ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
2042                StackFrameX86::CONTEXT_VALID_ESP |
2043                StackFrameX86::CONTEXT_VALID_EBP),
2044               frame3->context_validity);
2045     EXPECT_EQ(frame3_ebp.Value(), frame3->context.ebp);
2046     EXPECT_EQ(frame3_esp.Value(), frame3->context.esp);
2047     EXPECT_EQ(&remoting_core_dll, frame3->module);
2048     EXPECT_EQ("PK11_Verify", frame3->function_name);
2049     ASSERT_TRUE(frame3->windows_frame_info != NULL);
2050     EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame3->windows_frame_info->valid);
2051     EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
2052               frame3->windows_frame_info->type_);
2053     EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =",
2054               frame3->windows_frame_info->program_string);
2055     EXPECT_FALSE(frame3->windows_frame_info->allocates_base_pointer);
2056   }
2057 }
2058 
2059 // Runs IPAddressIsNotInKnownModule test with good symbols
TEST_F(GetCallerFrame,IPAddressIsNotInKnownModule)2060 TEST_F(GetCallerFrame, IPAddressIsNotInKnownModule) {
2061   IPAddressIsNotInKnownModuleTestImpl(false /* has_corrupt_modules */);
2062 }
2063 
2064 // Runs IPAddressIsNotInKnownModule test with corrupt symbols
TEST_F(GetCallerFrame,IPAddressIsNotInKnownModule_CorruptSymbols)2065 TEST_F(GetCallerFrame, IPAddressIsNotInKnownModule_CorruptSymbols) {
2066   IPAddressIsNotInKnownModuleTestImpl(true /* has_corrupt_modules */);
2067 }
2068 
2069 struct CFIFixture: public StackwalkerX86Fixture {
CFIFixtureCFIFixture2070   CFIFixture() {
2071     // Provide a bunch of STACK CFI records; individual tests walk to the
2072     // caller from every point in this series, expecting to find the same
2073     // set of register values.
2074     SetModuleSymbols(&module1,
2075                      // The youngest frame's function.
2076                      "FUNC 4000 1000 10 enchiridion\n"
2077                      // Initially, just a return address.
2078                      "STACK CFI INIT 4000 100 .cfa: $esp 4 + .ra: .cfa 4 - ^\n"
2079                      // Push %ebx.
2080                      "STACK CFI 4001 .cfa: $esp 8 + $ebx: .cfa 8 - ^\n"
2081                      // Move %esi into %ebx.  Weird, but permitted.
2082                      "STACK CFI 4002 $esi: $ebx\n"
2083                      // Allocate frame space, and save %edi.
2084                      "STACK CFI 4003 .cfa: $esp 20 + $edi: .cfa 16 - ^\n"
2085                      // Put the return address in %edi.
2086                      "STACK CFI 4005 .ra: $edi\n"
2087                      // Save %ebp, and use it as a frame pointer.
2088                      "STACK CFI 4006 .cfa: $ebp 8 + $ebp: .cfa 12 - ^\n"
2089 
2090                      // The calling function.
2091                      "FUNC 5000 1000 10 epictetus\n"
2092                      // Mark it as end of stack.
2093                      "STACK CFI INIT 5000 1000 .cfa: $esp .ra 0\n");
2094 
2095     // Provide some distinctive values for the caller's registers.
2096     expected.esp = 0x80000000;
2097     expected.eip = 0x40005510;
2098     expected.ebp = 0xc0d4aab9;
2099     expected.ebx = 0x60f20ce6;
2100     expected.esi = 0x53d1379d;
2101     expected.edi = 0xafbae234;
2102 
2103     // By default, registers are unchanged.
2104     raw_context = expected;
2105   }
2106 
2107   // Walk the stack, using stack_section as the contents of the stack
2108   // and raw_context as the current register values. (Set
2109   // raw_context.esp to the stack's starting address.) Expect two
2110   // stack frames; in the older frame, expect the callee-saves
2111   // registers to have values matching those in 'expected'.
CheckWalkCFIFixture2112   void CheckWalk() {
2113     RegionFromSection();
2114     raw_context.esp = stack_section.start().Value();
2115 
2116     StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
2117     StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
2118                           &frame_symbolizer);
2119     vector<const CodeModule*> modules_without_symbols;
2120     vector<const CodeModule*> modules_with_corrupt_symbols;
2121     ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
2122                             &modules_with_corrupt_symbols));
2123     ASSERT_EQ(0U, modules_without_symbols.size());
2124     ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
2125     frames = call_stack.frames();
2126     ASSERT_EQ(2U, frames->size());
2127 
2128     {  // To avoid reusing locals by mistake
2129       StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
2130       EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
2131       ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
2132       EXPECT_EQ("enchiridion", frame0->function_name);
2133       EXPECT_EQ(0x40004000U, frame0->function_base);
2134       ASSERT_TRUE(frame0->windows_frame_info != NULL);
2135       ASSERT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE,
2136                 frame0->windows_frame_info->valid);
2137       ASSERT_TRUE(frame0->cfi_frame_info != NULL);
2138     }
2139 
2140     {  // To avoid reusing locals by mistake
2141       StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
2142       EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
2143       ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
2144                  StackFrameX86::CONTEXT_VALID_ESP |
2145                  StackFrameX86::CONTEXT_VALID_EBP |
2146                  StackFrameX86::CONTEXT_VALID_EBX |
2147                  StackFrameX86::CONTEXT_VALID_ESI |
2148                  StackFrameX86::CONTEXT_VALID_EDI),
2149                  frame1->context_validity);
2150       EXPECT_EQ(expected.eip, frame1->context.eip);
2151       EXPECT_EQ(expected.esp, frame1->context.esp);
2152       EXPECT_EQ(expected.ebp, frame1->context.ebp);
2153       EXPECT_EQ(expected.ebx, frame1->context.ebx);
2154       EXPECT_EQ(expected.esi, frame1->context.esi);
2155       EXPECT_EQ(expected.edi, frame1->context.edi);
2156       EXPECT_EQ("epictetus", frame1->function_name);
2157     }
2158   }
2159 
2160   // The values the stack walker should find for the caller's registers.
2161   MDRawContextX86 expected;
2162 };
2163 
2164 class CFI: public CFIFixture, public Test { };
2165 
TEST_F(CFI,At4000)2166 TEST_F(CFI, At4000) {
2167   Label frame1_esp = expected.esp;
2168   stack_section
2169     .D32(0x40005510)             // return address
2170     .Mark(&frame1_esp);          // This effectively sets stack_section.start().
2171   raw_context.eip = 0x40004000;
2172   CheckWalk();
2173 }
2174 
TEST_F(CFI,At4001)2175 TEST_F(CFI, At4001) {
2176   Label frame1_esp = expected.esp;
2177   stack_section
2178     .D32(0x60f20ce6)             // saved %ebx
2179     .D32(0x40005510)             // return address
2180     .Mark(&frame1_esp);          // This effectively sets stack_section.start().
2181   raw_context.eip = 0x40004001;
2182   raw_context.ebx = 0x91aa9a8b;  // callee's %ebx value
2183   CheckWalk();
2184 }
2185 
TEST_F(CFI,At4002)2186 TEST_F(CFI, At4002) {
2187   Label frame1_esp = expected.esp;
2188   stack_section
2189     .D32(0x60f20ce6)             // saved %ebx
2190     .D32(0x40005510)             // return address
2191     .Mark(&frame1_esp);          // This effectively sets stack_section.start().
2192   raw_context.eip = 0x40004002;
2193   raw_context.ebx = 0x53d1379d;  // saved %esi
2194   raw_context.esi = 0xa5c790ed;  // callee's %esi value
2195   CheckWalk();
2196 }
2197 
TEST_F(CFI,At4003)2198 TEST_F(CFI, At4003) {
2199   Label frame1_esp = expected.esp;
2200   stack_section
2201     .D32(0x56ec3db7)             // garbage
2202     .D32(0xafbae234)             // saved %edi
2203     .D32(0x53d67131)             // garbage
2204     .D32(0x60f20ce6)             // saved %ebx
2205     .D32(0x40005510)             // return address
2206     .Mark(&frame1_esp);          // This effectively sets stack_section.start().
2207   raw_context.eip = 0x40004003;
2208   raw_context.ebx = 0x53d1379d;  // saved %esi
2209   raw_context.esi = 0xa97f229d;  // callee's %esi
2210   raw_context.edi = 0xb05cc997;  // callee's %edi
2211   CheckWalk();
2212 }
2213 
2214 // The results here should be the same as those at module offset
2215 // 0x4003.
TEST_F(CFI,At4004)2216 TEST_F(CFI, At4004) {
2217   Label frame1_esp = expected.esp;
2218   stack_section
2219     .D32(0xe29782c2)             // garbage
2220     .D32(0xafbae234)             // saved %edi
2221     .D32(0x5ba29ce9)             // garbage
2222     .D32(0x60f20ce6)             // saved %ebx
2223     .D32(0x40005510)             // return address
2224     .Mark(&frame1_esp);          // This effectively sets stack_section.start().
2225   raw_context.eip = 0x40004004;
2226   raw_context.ebx = 0x53d1379d;  // saved %esi
2227   raw_context.esi = 0x0fb7dc4e;  // callee's %esi
2228   raw_context.edi = 0x993b4280;  // callee's %edi
2229   CheckWalk();
2230 }
2231 
TEST_F(CFI,At4005)2232 TEST_F(CFI, At4005) {
2233   Label frame1_esp = expected.esp;
2234   stack_section
2235     .D32(0xe29782c2)             // garbage
2236     .D32(0xafbae234)             // saved %edi
2237     .D32(0x5ba29ce9)             // garbage
2238     .D32(0x60f20ce6)             // saved %ebx
2239     .D32(0x8036cc02)             // garbage
2240     .Mark(&frame1_esp);          // This effectively sets stack_section.start().
2241   raw_context.eip = 0x40004005;
2242   raw_context.ebx = 0x53d1379d;  // saved %esi
2243   raw_context.esi = 0x0fb7dc4e;  // callee's %esi
2244   raw_context.edi = 0x40005510;  // return address
2245   CheckWalk();
2246 }
2247 
TEST_F(CFI,At4006)2248 TEST_F(CFI, At4006) {
2249   Label frame0_ebp;
2250   Label frame1_esp = expected.esp;
2251   stack_section
2252     .D32(0xdcdd25cd)             // garbage
2253     .D32(0xafbae234)             // saved %edi
2254     .D32(0xc0d4aab9)             // saved %ebp
2255     .Mark(&frame0_ebp)           // frame pointer points here
2256     .D32(0x60f20ce6)             // saved %ebx
2257     .D32(0x8036cc02)             // garbage
2258     .Mark(&frame1_esp);          // This effectively sets stack_section.start().
2259   raw_context.eip = 0x40004006;
2260   raw_context.ebp = frame0_ebp.Value();
2261   raw_context.ebx = 0x53d1379d;  // saved %esi
2262   raw_context.esi = 0x743833c9;  // callee's %esi
2263   raw_context.edi = 0x40005510;  // return address
2264   CheckWalk();
2265 }
2266 
2267