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 (at) mozilla.com> <jimb (at) 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: 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. 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. 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. 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 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 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. 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. 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. 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 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. 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. 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 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. 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. 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. 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. 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. 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). 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) 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. 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; 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 1922 TEST_F(GetCallerFrame, IPAddressIsNotInKnownModule) { 1923 IPAddressIsNotInKnownModuleTestImpl(false /* has_corrupt_modules */); 1924 } 1925 1926 // Runs IPAddressIsNotInKnownModule test with corrupt symbols 1927 TEST_F(GetCallerFrame, IPAddressIsNotInKnownModule_CorruptSymbols) { 1928 IPAddressIsNotInKnownModuleTestImpl(true /* has_corrupt_modules */); 1929 } 1930 1931 struct CFIFixture: public StackwalkerX86Fixture { 1932 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'. 1974 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 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 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 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 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. 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 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 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