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