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