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