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