stackwalker_arm_unittest.cc
1 // Copyright 2010 Google LLC 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are 5 // met: 6 // 7 // * Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above 10 // copyright notice, this list of conditions and the following disclaimer 11 // in the documentation and/or other materials provided with the 12 // distribution. 13 // * Neither the name of Google LLC nor the names of its 14 // contributors may be used to endorse or promote products derived from 15 // this software without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> 30 31 // stackwalker_arm_unittest.cc: Unit tests for StackwalkerARM class. 32 33 #ifdef HAVE_CONFIG_H 34 #include <config.h> // Must come first 35 #endif 36 37 #include <string.h> 38 #include <string> 39 #include <vector> 40 41 #include "breakpad_googletest_includes.h" 42 #include "common/test_assembler.h" 43 #include "common/using_std_string.h" 44 #include "google_breakpad/common/minidump_format.h" 45 #include "google_breakpad/processor/basic_source_line_resolver.h" 46 #include "google_breakpad/processor/call_stack.h" 47 #include "google_breakpad/processor/code_module.h" 48 #include "google_breakpad/processor/source_line_resolver_interface.h" 49 #include "google_breakpad/processor/stack_frame_cpu.h" 50 #include "processor/stackwalker_unittest_utils.h" 51 #include "processor/stackwalker_arm.h" 52 #include "processor/windows_frame_info.h" 53 54 using google_breakpad::BasicSourceLineResolver; 55 using google_breakpad::CallStack; 56 using google_breakpad::CodeModule; 57 using google_breakpad::StackFrameSymbolizer; 58 using google_breakpad::StackFrame; 59 using google_breakpad::StackFrameARM; 60 using google_breakpad::Stackwalker; 61 using google_breakpad::StackwalkerARM; 62 using google_breakpad::SystemInfo; 63 using google_breakpad::WindowsFrameInfo; 64 using google_breakpad::test_assembler::kLittleEndian; 65 using google_breakpad::test_assembler::Label; 66 using google_breakpad::test_assembler::Section; 67 using std::vector; 68 using testing::_; 69 using testing::AnyNumber; 70 using testing::DoAll; 71 using testing::Return; 72 using testing::SetArgumentPointee; 73 using testing::Test; 74 75 class StackwalkerARMFixture { 76 public: 77 StackwalkerARMFixture() 78 : stack_section(kLittleEndian), 79 // Give the two modules reasonable standard locations and names 80 // for tests to play with. 81 module1(0x40000000, 0x10000, "module1", "version1"), 82 module2(0x50000000, 0x10000, "module2", "version2") { 83 // Identify the system as a Linux system. 84 system_info.os = "Linux"; 85 system_info.os_short = "linux"; 86 system_info.os_version = "Lugubrious Labrador"; 87 system_info.cpu = "arm"; 88 system_info.cpu_info = ""; 89 90 // Put distinctive values in the raw CPU context. 91 BrandContext(&raw_context); 92 93 // Create some modules with some stock debugging information. 94 modules.Add(&module1); 95 modules.Add(&module2); 96 97 // By default, none of the modules have symbol info; call 98 // SetModuleSymbols to override this. 99 EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _)) 100 .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND)); 101 102 // Avoid GMOCK WARNING "Uninteresting mock function call - returning 103 // directly" for FreeSymbolData(). 104 EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); 105 106 // Reset max_frames_scanned since it's static. 107 Stackwalker::set_max_frames_scanned(1024); 108 } 109 110 // Set the Breakpad symbol information that supplier should return for 111 // MODULE to INFO. 112 void SetModuleSymbols(MockCodeModule* module, const string& info) { 113 size_t buffer_size; 114 char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size); 115 EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _)) 116 .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer), 117 SetArgumentPointee<4>(buffer_size), 118 Return(MockSymbolSupplier::FOUND))); 119 } 120 121 // Populate stack_region with the contents of stack_section. Use 122 // stack_section.start() as the region's starting address. 123 void RegionFromSection() { 124 string contents; 125 ASSERT_TRUE(stack_section.GetContents(&contents)); 126 stack_region.Init(stack_section.start().Value(), contents); 127 } 128 129 // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking. 130 void BrandContext(MDRawContextARM *raw_context) { 131 uint8_t x = 173; 132 for (size_t i = 0; i < sizeof(*raw_context); i++) 133 reinterpret_cast<uint8_t*>(raw_context)[i] = (x += 17); 134 } 135 136 SystemInfo system_info; 137 MDRawContextARM raw_context; 138 Section stack_section; 139 MockMemoryRegion stack_region; 140 MockCodeModule module1; 141 MockCodeModule module2; 142 MockCodeModules modules; 143 MockSymbolSupplier supplier; 144 BasicSourceLineResolver resolver; 145 CallStack call_stack; 146 const vector<StackFrame*>* frames; 147 }; 148 149 class SanityCheck: public StackwalkerARMFixture, public Test { }; 150 151 TEST_F(SanityCheck, NoResolver) { 152 // Since we have no call frame information, and all unwinding 153 // requires call frame information, the stack walk will end after 154 // the first frame. 155 StackFrameSymbolizer frame_symbolizer(NULL, NULL); 156 StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, 157 &frame_symbolizer); 158 // This should succeed even without a resolver or supplier. 159 vector<const CodeModule*> modules_without_symbols; 160 vector<const CodeModule*> modules_with_corrupt_symbols; 161 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 162 &modules_with_corrupt_symbols)); 163 ASSERT_EQ(0U, modules_without_symbols.size()); 164 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 165 frames = call_stack.frames(); 166 ASSERT_EQ(1U, frames->size()); 167 StackFrameARM *frame = static_cast<StackFrameARM*>(frames->at(0)); 168 // Check that the values from the original raw context made it 169 // through to the context in the stack frame. 170 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); 171 } 172 173 class GetContextFrame: public StackwalkerARMFixture, public Test { }; 174 175 TEST_F(GetContextFrame, Simple) { 176 // Since we have no call frame information, and all unwinding 177 // requires call frame information, the stack walk will end after 178 // the first frame. 179 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 180 StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, 181 &frame_symbolizer); 182 vector<const CodeModule*> modules_without_symbols; 183 vector<const CodeModule*> modules_with_corrupt_symbols; 184 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 185 &modules_with_corrupt_symbols)); 186 ASSERT_EQ(0U, modules_without_symbols.size()); 187 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 188 frames = call_stack.frames(); 189 ASSERT_EQ(1U, frames->size()); 190 StackFrameARM *frame = static_cast<StackFrameARM*>(frames->at(0)); 191 // Check that the values from the original raw context made it 192 // through to the context in the stack frame. 193 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); 194 } 195 196 // The stackwalker should be able to produce the context frame even 197 // without stack memory present. 198 TEST_F(GetContextFrame, NoStackMemory) { 199 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 200 StackwalkerARM walker(&system_info, &raw_context, -1, NULL, &modules, 201 &frame_symbolizer); 202 vector<const CodeModule*> modules_without_symbols; 203 vector<const CodeModule*> modules_with_corrupt_symbols; 204 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 205 &modules_with_corrupt_symbols)); 206 ASSERT_EQ(0U, modules_without_symbols.size()); 207 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 208 frames = call_stack.frames(); 209 ASSERT_EQ(1U, frames->size()); 210 StackFrameARM *frame = static_cast<StackFrameARM*>(frames->at(0)); 211 // Check that the values from the original raw context made it 212 // through to the context in the stack frame. 213 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); 214 } 215 216 class GetCallerFrame: public StackwalkerARMFixture, public Test { }; 217 218 TEST_F(GetCallerFrame, ScanWithoutSymbols) { 219 // When the stack walker resorts to scanning the stack, 220 // only addresses located within loaded modules are 221 // considered valid return addresses. 222 // Force scanning through three frames to ensure that the 223 // stack pointer is set properly in scan-recovered frames. 224 stack_section.start() = 0x80000000; 225 uint32_t return_address1 = 0x50000100; 226 uint32_t return_address2 = 0x50000900; 227 Label frame1_sp, frame2_sp; 228 stack_section 229 // frame 0 230 .Append(16, 0) // space 231 232 .D32(0x40090000) // junk that's not 233 .D32(0x60000000) // a return address 234 235 .D32(return_address1) // actual return address 236 // frame 1 237 .Mark(&frame1_sp) 238 .Append(16, 0) // space 239 240 .D32(0xF0000000) // more junk 241 .D32(0x0000000D) 242 243 .D32(return_address2) // actual return address 244 // frame 2 245 .Mark(&frame2_sp) 246 .Append(32, 0); // end of stack 247 RegionFromSection(); 248 249 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510; 250 raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); 251 252 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 253 StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, 254 &frame_symbolizer); 255 vector<const CodeModule*> modules_without_symbols; 256 vector<const CodeModule*> modules_with_corrupt_symbols; 257 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 258 &modules_with_corrupt_symbols)); 259 ASSERT_EQ(2U, modules_without_symbols.size()); 260 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 261 ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); 262 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 263 frames = call_stack.frames(); 264 ASSERT_EQ(3U, frames->size()); 265 266 StackFrameARM *frame0 = static_cast<StackFrameARM*>(frames->at(0)); 267 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 268 ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity); 269 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 270 271 StackFrameARM *frame1 = static_cast<StackFrameARM*>(frames->at(1)); 272 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); 273 ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | 274 StackFrameARM::CONTEXT_VALID_SP), 275 frame1->context_validity); 276 EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]); 277 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]); 278 279 StackFrameARM *frame2 = static_cast<StackFrameARM*>(frames->at(2)); 280 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame2->trust); 281 ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | 282 StackFrameARM::CONTEXT_VALID_SP), 283 frame2->context_validity); 284 EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]); 285 EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]); 286 } 287 288 TEST_F(GetCallerFrame, ScanWithFunctionSymbols) { 289 // During stack scanning, if a potential return address 290 // is located within a loaded module that has symbols, 291 // it is only considered a valid return address if it 292 // lies within a function's bounds. 293 stack_section.start() = 0x80000000; 294 uint32_t return_address = 0x50000200; 295 Label frame1_sp; 296 297 stack_section 298 // frame 0 299 .Append(16, 0) // space 300 301 .D32(0x40090000) // junk that's not 302 .D32(0x60000000) // a return address 303 304 .D32(0x40001000) // a couple of plausible addresses 305 .D32(0x5000F000) // that are not within functions 306 307 .D32(return_address) // actual return address 308 // frame 1 309 .Mark(&frame1_sp) 310 .Append(32, 0); // end of stack 311 RegionFromSection(); 312 313 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40000200; 314 raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); 315 316 SetModuleSymbols(&module1, 317 // The youngest frame's function. 318 "FUNC 100 400 10 monotreme\n"); 319 SetModuleSymbols(&module2, 320 // The calling frame's function. 321 "FUNC 100 400 10 marsupial\n"); 322 323 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 324 StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, 325 &frame_symbolizer); 326 vector<const CodeModule*> modules_without_symbols; 327 vector<const CodeModule*> modules_with_corrupt_symbols; 328 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 329 &modules_with_corrupt_symbols)); 330 ASSERT_EQ(0U, modules_without_symbols.size()); 331 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 332 frames = call_stack.frames(); 333 ASSERT_EQ(2U, frames->size()); 334 335 StackFrameARM *frame0 = static_cast<StackFrameARM*>(frames->at(0)); 336 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 337 ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity); 338 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 339 EXPECT_EQ("monotreme", frame0->function_name); 340 EXPECT_EQ(0x40000100U, frame0->function_base); 341 342 StackFrameARM *frame1 = static_cast<StackFrameARM*>(frames->at(1)); 343 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); 344 ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | 345 StackFrameARM::CONTEXT_VALID_SP), 346 frame1->context_validity); 347 EXPECT_EQ(return_address, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]); 348 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]); 349 EXPECT_EQ("marsupial", frame1->function_name); 350 EXPECT_EQ(0x50000100U, frame1->function_base); 351 } 352 353 TEST_F(GetCallerFrame, ScanFirstFrame) { 354 // If the stackwalker resorts to stack scanning, it will scan much 355 // farther to find the caller of the context frame. 356 stack_section.start() = 0x80000000; 357 uint32_t return_address1 = 0x50000100; 358 uint32_t return_address2 = 0x50000900; 359 Label frame1_sp, frame2_sp; 360 stack_section 361 // frame 0 362 .Append(32, 0) // space 363 364 .D32(0x40090000) // junk that's not 365 .D32(0x60000000) // a return address 366 367 .Append(96, 0) // more space 368 369 .D32(return_address1) // actual return address 370 // frame 1 371 .Mark(&frame1_sp) 372 .Append(32, 0) // space 373 374 .D32(0xF0000000) // more junk 375 .D32(0x0000000D) 376 377 .Append(136, 0) // more space 378 379 .D32(return_address2) // actual return address 380 // (won't be found) 381 // frame 2 382 .Mark(&frame2_sp) 383 .Append(32, 0); // end of stack 384 RegionFromSection(); 385 386 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510; 387 raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); 388 389 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 390 StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, 391 &frame_symbolizer); 392 vector<const CodeModule*> modules_without_symbols; 393 vector<const CodeModule*> modules_with_corrupt_symbols; 394 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 395 &modules_with_corrupt_symbols)); 396 ASSERT_EQ(2U, modules_without_symbols.size()); 397 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 398 ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); 399 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 400 frames = call_stack.frames(); 401 ASSERT_EQ(2U, frames->size()); 402 403 StackFrameARM *frame0 = static_cast<StackFrameARM*>(frames->at(0)); 404 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 405 ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity); 406 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 407 408 StackFrameARM *frame1 = static_cast<StackFrameARM*>(frames->at(1)); 409 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); 410 ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | 411 StackFrameARM::CONTEXT_VALID_SP), 412 frame1->context_validity); 413 EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]); 414 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]); 415 } 416 417 // Test that set_max_frames_scanned prevents using stack scanning 418 // to find caller frames. 419 TEST_F(GetCallerFrame, ScanningNotAllowed) { 420 // When the stack walker resorts to scanning the stack, 421 // only addresses located within loaded modules are 422 // considered valid return addresses. 423 stack_section.start() = 0x80000000; 424 uint32_t return_address1 = 0x50000100; 425 uint32_t return_address2 = 0x50000900; 426 Label frame1_sp, frame2_sp; 427 stack_section 428 // frame 0 429 .Append(16, 0) // space 430 431 .D32(0x40090000) // junk that's not 432 .D32(0x60000000) // a return address 433 434 .D32(return_address1) // actual return address 435 // frame 1 436 .Mark(&frame1_sp) 437 .Append(16, 0) // space 438 439 .D32(0xF0000000) // more junk 440 .D32(0x0000000D) 441 442 .D32(return_address2) // actual return address 443 // frame 2 444 .Mark(&frame2_sp) 445 .Append(32, 0); // end of stack 446 RegionFromSection(); 447 448 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510; 449 raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); 450 451 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 452 StackwalkerARM walker(&system_info, &raw_context, -1, &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 StackFrameARM *frame0 = static_cast<StackFrameARM*>(frames->at(0)); 467 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 468 ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity); 469 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 470 } 471 472 struct CFIFixture: public StackwalkerARMFixture { 473 CFIFixture() { 474 // Provide a bunch of STACK CFI records; we'll walk to the caller 475 // from every point in this series, expecting to find the same set 476 // of register values. 477 SetModuleSymbols(&module1, 478 // The youngest frame's function. 479 "FUNC 4000 1000 10 enchiridion\n" 480 // Initially, nothing has been pushed on the stack, 481 // and the return address is still in the link register. 482 "STACK CFI INIT 4000 100 .cfa: sp .ra: lr\n" 483 // Push r4, the frame pointer, and the link register. 484 "STACK CFI 4001 .cfa: sp 12 + r4: .cfa 12 - ^" 485 " r11: .cfa 8 - ^ .ra: .cfa 4 - ^\n" 486 // Save r4..r7 in r0..r3: verify that we populate 487 // the youngest frame with all the values we have. 488 "STACK CFI 4002 r4: r0 r5: r1 r6: r2 r7: r3\n" 489 // Restore r4..r7. Save the non-callee-saves register r1. 490 "STACK CFI 4003 .cfa: sp 16 + r1: .cfa 16 - ^" 491 " r4: r4 r5: r5 r6: r6 r7: r7\n" 492 // Move the .cfa back four bytes, to point at the return 493 // address, and restore the sp explicitly. 494 "STACK CFI 4005 .cfa: sp 12 + r1: .cfa 12 - ^" 495 " r11: .cfa 4 - ^ .ra: .cfa ^ sp: .cfa 4 +\n" 496 // Recover the PC explicitly from a new stack slot; 497 // provide garbage for the .ra. 498 "STACK CFI 4006 .cfa: sp 16 + pc: .cfa 16 - ^\n" 499 500 // The calling function. 501 "FUNC 5000 1000 10 epictetus\n" 502 // Mark it as end of stack. 503 "STACK CFI INIT 5000 1000 .cfa: 0 .ra: 0\n" 504 505 // A function whose CFI makes the stack pointer 506 // go backwards. 507 "FUNC 6000 1000 20 palinal\n" 508 "STACK CFI INIT 6000 1000 .cfa: sp 4 - .ra: lr\n" 509 510 // A function with CFI expressions that can't be 511 // evaluated. 512 "FUNC 7000 1000 20 rhetorical\n" 513 "STACK CFI INIT 7000 1000 .cfa: moot .ra: ambiguous\n"); 514 515 // Provide some distinctive values for the caller's registers. 516 expected.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510; 517 expected.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000; 518 expected.iregs[4] = 0xb5d55e68; 519 expected.iregs[5] = 0xebd134f3; 520 expected.iregs[6] = 0xa31e74bc; 521 expected.iregs[7] = 0x2dcb16b3; 522 expected.iregs[8] = 0x2ada2137; 523 expected.iregs[9] = 0xbbbb557d; 524 expected.iregs[10] = 0x48bf8ca7; 525 expected.iregs[MD_CONTEXT_ARM_REG_FP] = 0x8112e110; 526 527 // Expect CFI to recover all callee-saves registers. Since CFI is the 528 // only stack frame construction technique we have, aside from the 529 // context frame itself, there's no way for us to have a set of valid 530 // registers smaller than this. 531 expected_validity = (StackFrameARM::CONTEXT_VALID_PC | 532 StackFrameARM::CONTEXT_VALID_SP | 533 StackFrameARM::CONTEXT_VALID_R4 | 534 StackFrameARM::CONTEXT_VALID_R5 | 535 StackFrameARM::CONTEXT_VALID_R6 | 536 StackFrameARM::CONTEXT_VALID_R7 | 537 StackFrameARM::CONTEXT_VALID_R8 | 538 StackFrameARM::CONTEXT_VALID_R9 | 539 StackFrameARM::CONTEXT_VALID_R10 | 540 StackFrameARM::CONTEXT_VALID_FP); 541 542 // By default, context frames provide all registers, as normal. 543 context_frame_validity = StackFrameARM::CONTEXT_VALID_ALL; 544 545 // By default, registers are unchanged. 546 raw_context = expected; 547 } 548 549 // Walk the stack, using stack_section as the contents of the stack 550 // and raw_context as the current register values. (Set the stack 551 // pointer to the stack's starting address.) Expect two stack 552 // frames; in the older frame, expect the callee-saves registers to 553 // have values matching those in 'expected'. 554 void CheckWalk() { 555 RegionFromSection(); 556 raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); 557 558 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 559 StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, 560 &modules, &frame_symbolizer); 561 walker.SetContextFrameValidity(context_frame_validity); 562 vector<const CodeModule*> modules_without_symbols; 563 vector<const CodeModule*> modules_with_corrupt_symbols; 564 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 565 &modules_with_corrupt_symbols)); 566 ASSERT_EQ(0U, modules_without_symbols.size()); 567 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 568 frames = call_stack.frames(); 569 ASSERT_EQ(2U, frames->size()); 570 571 StackFrameARM *frame0 = static_cast<StackFrameARM*>(frames->at(0)); 572 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 573 ASSERT_EQ(context_frame_validity, frame0->context_validity); 574 EXPECT_EQ("enchiridion", frame0->function_name); 575 EXPECT_EQ(0x40004000U, frame0->function_base); 576 577 StackFrameARM *frame1 = static_cast<StackFrameARM*>(frames->at(1)); 578 EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); 579 ASSERT_EQ(expected_validity, frame1->context_validity); 580 if (expected_validity & StackFrameARM::CONTEXT_VALID_R1) 581 EXPECT_EQ(expected.iregs[1], frame1->context.iregs[1]); 582 if (expected_validity & StackFrameARM::CONTEXT_VALID_R4) 583 EXPECT_EQ(expected.iregs[4], frame1->context.iregs[4]); 584 if (expected_validity & StackFrameARM::CONTEXT_VALID_R5) 585 EXPECT_EQ(expected.iregs[5], frame1->context.iregs[5]); 586 if (expected_validity & StackFrameARM::CONTEXT_VALID_R6) 587 EXPECT_EQ(expected.iregs[6], frame1->context.iregs[6]); 588 if (expected_validity & StackFrameARM::CONTEXT_VALID_R7) 589 EXPECT_EQ(expected.iregs[7], frame1->context.iregs[7]); 590 if (expected_validity & StackFrameARM::CONTEXT_VALID_R8) 591 EXPECT_EQ(expected.iregs[8], frame1->context.iregs[8]); 592 if (expected_validity & StackFrameARM::CONTEXT_VALID_R9) 593 EXPECT_EQ(expected.iregs[9], frame1->context.iregs[9]); 594 if (expected_validity & StackFrameARM::CONTEXT_VALID_R10) 595 EXPECT_EQ(expected.iregs[10], frame1->context.iregs[10]); 596 if (expected_validity & StackFrameARM::CONTEXT_VALID_FP) 597 EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_FP], 598 frame1->context.iregs[MD_CONTEXT_ARM_REG_FP]); 599 600 // We would never have gotten a frame in the first place if the SP 601 // and PC weren't valid or ->instruction weren't set. 602 EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_SP], 603 frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]); 604 EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_PC], 605 frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]); 606 EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_PC], 607 frame1->instruction + 2); 608 EXPECT_EQ("epictetus", frame1->function_name); 609 } 610 611 // The values we expect to find for the caller's registers. 612 MDRawContextARM expected; 613 614 // The validity mask for expected. 615 int expected_validity; 616 617 // The validity mask to impose on the context frame. 618 int context_frame_validity; 619 }; 620 621 class CFI: public CFIFixture, public Test { }; 622 623 TEST_F(CFI, At4000) { 624 stack_section.start() = expected.iregs[MD_CONTEXT_ARM_REG_SP]; 625 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004000; 626 raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = 0x40005510; 627 CheckWalk(); 628 } 629 630 TEST_F(CFI, At4001) { 631 Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP]; 632 stack_section 633 .D32(0xb5d55e68) // saved r4 634 .D32(0x8112e110) // saved fp 635 .D32(0x40005510) // return address 636 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 637 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004001; 638 raw_context.iregs[4] = 0x635adc9f; // distinct callee r4 639 raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp 640 CheckWalk(); 641 } 642 643 // As above, but unwind from a context that has only the PC and SP. 644 TEST_F(CFI, At4001LimitedValidity) { 645 context_frame_validity = 646 StackFrameARM::CONTEXT_VALID_PC | StackFrameARM::CONTEXT_VALID_SP; 647 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004001; 648 raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp 649 Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP]; 650 stack_section 651 .D32(0xb5d55e68) // saved r4 652 .D32(0x8112e110) // saved fp 653 .D32(0x40005510) // return address 654 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 655 expected_validity = (StackFrameARM::CONTEXT_VALID_PC 656 | StackFrameARM::CONTEXT_VALID_SP 657 | StackFrameARM::CONTEXT_VALID_FP 658 | StackFrameARM::CONTEXT_VALID_R4); 659 CheckWalk(); 660 } 661 662 TEST_F(CFI, At4002) { 663 Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP]; 664 stack_section 665 .D32(0xfb81ff3d) // no longer saved r4 666 .D32(0x8112e110) // saved fp 667 .D32(0x40005510) // return address 668 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 669 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004002; 670 raw_context.iregs[0] = 0xb5d55e68; // saved r4 671 raw_context.iregs[1] = 0xebd134f3; // saved r5 672 raw_context.iregs[2] = 0xa31e74bc; // saved r6 673 raw_context.iregs[3] = 0x2dcb16b3; // saved r7 674 raw_context.iregs[4] = 0xfdd35466; // distinct callee r4 675 raw_context.iregs[5] = 0xf18c946c; // distinct callee r5 676 raw_context.iregs[6] = 0xac2079e8; // distinct callee r6 677 raw_context.iregs[7] = 0xa449829f; // distinct callee r7 678 raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp 679 CheckWalk(); 680 } 681 682 TEST_F(CFI, At4003) { 683 Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP]; 684 stack_section 685 .D32(0x48c8dd5a) // saved r1 (even though it's not callee-saves) 686 .D32(0xcb78040e) // no longer saved r4 687 .D32(0x8112e110) // saved fp 688 .D32(0x40005510) // return address 689 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 690 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004003; 691 raw_context.iregs[1] = 0xfb756319; // distinct callee r1 692 raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0x0a2857ea; // distinct callee fp 693 expected.iregs[1] = 0x48c8dd5a; // caller's r1 694 expected_validity |= StackFrameARM::CONTEXT_VALID_R1; 695 CheckWalk(); 696 } 697 698 // We have no new rule at module offset 0x4004, so the results here should 699 // be the same as those at module offset 0x4003. 700 TEST_F(CFI, At4004) { 701 Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP]; 702 stack_section 703 .D32(0x48c8dd5a) // saved r1 (even though it's not callee-saves) 704 .D32(0xcb78040e) // no longer saved r4 705 .D32(0x8112e110) // saved fp 706 .D32(0x40005510) // return address 707 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 708 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004004; 709 raw_context.iregs[1] = 0xfb756319; // distinct callee r1 710 expected.iregs[1] = 0x48c8dd5a; // caller's r1 711 expected_validity |= StackFrameARM::CONTEXT_VALID_R1; 712 CheckWalk(); 713 } 714 715 // Here we move the .cfa, but provide an explicit rule to recover the SP, 716 // so again there should be no change in the registers recovered. 717 TEST_F(CFI, At4005) { 718 Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP]; 719 stack_section 720 .D32(0x48c8dd5a) // saved r1 (even though it's not callee-saves) 721 .D32(0xf013f841) // no longer saved r4 722 .D32(0x8112e110) // saved fp 723 .D32(0x40005510) // return address 724 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 725 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004005; 726 raw_context.iregs[1] = 0xfb756319; // distinct callee r1 727 expected.iregs[1] = 0x48c8dd5a; // caller's r1 728 expected_validity |= StackFrameARM::CONTEXT_VALID_R1; 729 CheckWalk(); 730 } 731 732 // Here we provide an explicit rule for the PC, and have the saved .ra be 733 // bogus. 734 TEST_F(CFI, At4006) { 735 Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP]; 736 stack_section 737 .D32(0x40005510) // saved pc 738 .D32(0x48c8dd5a) // saved r1 (even though it's not callee-saves) 739 .D32(0xf013f841) // no longer saved r4 740 .D32(0x8112e110) // saved fp 741 .D32(0xf8d15783) // .ra rule recovers this, which is garbage 742 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 743 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004006; 744 raw_context.iregs[1] = 0xfb756319; // callee's r1, different from caller's 745 expected.iregs[1] = 0x48c8dd5a; // caller's r1 746 expected_validity |= StackFrameARM::CONTEXT_VALID_R1; 747 CheckWalk(); 748 } 749 750 // Check that we reject rules that would cause the stack pointer to 751 // move in the wrong direction. 752 TEST_F(CFI, RejectBackwards) { 753 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40006000; 754 raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000; 755 raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = 0x40005510; 756 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 757 StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, 758 &frame_symbolizer); 759 vector<const CodeModule*> modules_without_symbols; 760 vector<const CodeModule*> modules_with_corrupt_symbols; 761 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 762 &modules_with_corrupt_symbols)); 763 ASSERT_EQ(0U, modules_without_symbols.size()); 764 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 765 frames = call_stack.frames(); 766 ASSERT_EQ(1U, frames->size()); 767 } 768 769 // Check that we reject rules whose expressions' evaluation fails. 770 TEST_F(CFI, RejectBadExpressions) { 771 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40007000; 772 raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000; 773 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 774 StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, 775 &frame_symbolizer); 776 vector<const CodeModule*> modules_without_symbols; 777 vector<const CodeModule*> modules_with_corrupt_symbols; 778 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 779 &modules_with_corrupt_symbols)); 780 ASSERT_EQ(0U, modules_without_symbols.size()); 781 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 782 frames = call_stack.frames(); 783 ASSERT_EQ(1U, frames->size()); 784 } 785 786 class StackwalkerARMFixtureIOS : public StackwalkerARMFixture { 787 public: 788 StackwalkerARMFixtureIOS() { 789 // iOS_test is used instead of iOS because the stackwalker has a check to 790 // avoid using CFI for iOS dumps. This is a workaround for bad CFI being 791 // produced by dump_syms for iOS. 792 // https://bugs.chromium.org/p/google-breakpad/issues/detail?id=764 793 system_info.os = "iOS_test"; 794 system_info.os_short = "ios_test"; 795 } 796 }; 797 798 class GetFramesByFramePointer: public StackwalkerARMFixtureIOS, public Test { }; 799 800 TEST_F(GetFramesByFramePointer, OnlyFramePointer) { 801 stack_section.start() = 0x80000000; 802 uint32_t return_address1 = 0x50000100; 803 uint32_t return_address2 = 0x50000900; 804 Label frame1_sp, frame2_sp; 805 Label frame1_fp, frame2_fp; 806 stack_section 807 // frame 0 808 .Append(32, 0) // Whatever values on the stack. 809 .D32(0x0000000D) // junk that's not 810 .D32(0xF0000000) // a return address. 811 812 .Mark(&frame1_fp) // Next fp will point to the next value. 813 .D32(frame2_fp) // Save current frame pointer. 814 .D32(return_address2) // Save current link register. 815 .Mark(&frame1_sp) 816 817 // frame 1 818 .Append(32, 0) // Whatever values on the stack. 819 .D32(0x0000000D) // junk that's not 820 .D32(0xF0000000) // a return address. 821 822 .Mark(&frame2_fp) 823 .D32(0) 824 .D32(0) 825 .Mark(&frame2_sp) 826 827 // frame 2 828 .Append(32, 0) // Whatever values on the stack. 829 .D32(0x0000000D) // junk that's not 830 .D32(0xF0000000); // a return address. 831 RegionFromSection(); 832 833 834 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510; 835 raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = return_address1; 836 raw_context.iregs[MD_CONTEXT_ARM_REG_IOS_FP] = frame1_fp.Value(); 837 raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); 838 839 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 840 StackwalkerARM walker(&system_info, &raw_context, MD_CONTEXT_ARM_REG_IOS_FP, 841 &stack_region, &modules, &frame_symbolizer); 842 843 vector<const CodeModule*> modules_without_symbols; 844 vector<const CodeModule*> modules_with_corrupt_symbols; 845 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 846 &modules_with_corrupt_symbols)); 847 ASSERT_EQ(2U, modules_without_symbols.size()); 848 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 849 ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); 850 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 851 frames = call_stack.frames(); 852 ASSERT_EQ(3U, frames->size()); 853 854 StackFrameARM *frame0 = static_cast<StackFrameARM*>(frames->at(0)); 855 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 856 ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity); 857 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 858 859 StackFrameARM *frame1 = static_cast<StackFrameARM*>(frames->at(1)); 860 EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust); 861 ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | 862 StackFrameARM::CONTEXT_VALID_LR | 863 StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) | 864 StackFrameARM::CONTEXT_VALID_SP), 865 frame1->context_validity); 866 EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]); 867 EXPECT_EQ(return_address2, frame1->context.iregs[MD_CONTEXT_ARM_REG_LR]); 868 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]); 869 EXPECT_EQ(frame2_fp.Value(), 870 frame1->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]); 871 872 StackFrameARM *frame2 = static_cast<StackFrameARM*>(frames->at(2)); 873 EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame2->trust); 874 ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | 875 StackFrameARM::CONTEXT_VALID_LR | 876 StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) | 877 StackFrameARM::CONTEXT_VALID_SP), 878 frame2->context_validity); 879 EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]); 880 EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_LR]); 881 EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]); 882 EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]); 883 } 884 885 TEST_F(GetFramesByFramePointer, FramePointerAndCFI) { 886 // Provide the standatd STACK CFI records that is obtained when exmining an 887 // executable produced by XCode. 888 SetModuleSymbols(&module1, 889 // Adding a function in CFI. 890 "FUNC 4000 1000 10 enchiridion\n" 891 892 "STACK CFI INIT 4000 100 .cfa: sp 0 + .ra: lr\n" 893 "STACK CFI 4001 .cfa: sp 8 + .ra: .cfa -4 + ^" 894 " r7: .cfa -8 + ^\n" 895 "STACK CFI 4002 .cfa: r7 8 +\n" 896 ); 897 898 stack_section.start() = 0x80000000; 899 uint32_t return_address1 = 0x40004010; 900 uint32_t return_address2 = 0x50000900; 901 Label frame1_sp, frame2_sp; 902 Label frame1_fp, frame2_fp; 903 stack_section 904 // frame 0 905 .Append(32, 0) // Whatever values on the stack. 906 .D32(0x0000000D) // junk that's not 907 .D32(0xF0000000) // a return address. 908 909 .Mark(&frame1_fp) // Next fp will point to the next value. 910 .D32(frame2_fp) // Save current frame pointer. 911 .D32(return_address2) // Save current link register. 912 .Mark(&frame1_sp) 913 914 // frame 1 915 .Append(32, 0) // Whatever values on the stack. 916 .D32(0x0000000D) // junk that's not 917 .D32(0xF0000000) // a return address. 918 919 .Mark(&frame2_fp) 920 .D32(0) 921 .D32(0) 922 .Mark(&frame2_sp) 923 924 // frame 2 925 .Append(32, 0) // Whatever values on the stack. 926 .D32(0x0000000D) // junk that's not 927 .D32(0xF0000000); // a return address. 928 RegionFromSection(); 929 930 931 raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x50000400; 932 raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = return_address1; 933 raw_context.iregs[MD_CONTEXT_ARM_REG_IOS_FP] = frame1_fp.Value(); 934 raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value(); 935 936 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 937 StackwalkerARM walker(&system_info, &raw_context, MD_CONTEXT_ARM_REG_IOS_FP, 938 &stack_region, &modules, &frame_symbolizer); 939 940 vector<const CodeModule*> modules_without_symbols; 941 vector<const CodeModule*> modules_with_corrupt_symbols; 942 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 943 &modules_with_corrupt_symbols)); 944 ASSERT_EQ(1U, modules_without_symbols.size()); 945 ASSERT_EQ("module2", modules_without_symbols[0]->debug_file()); 946 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 947 frames = call_stack.frames(); 948 ASSERT_EQ(3U, frames->size()); 949 950 StackFrameARM *frame0 = static_cast<StackFrameARM*>(frames->at(0)); 951 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 952 ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity); 953 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 954 955 StackFrameARM *frame1 = static_cast<StackFrameARM*>(frames->at(1)); 956 EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust); 957 ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | 958 StackFrameARM::CONTEXT_VALID_LR | 959 StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) | 960 StackFrameARM::CONTEXT_VALID_SP), 961 frame1->context_validity); 962 EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]); 963 EXPECT_EQ(return_address2, frame1->context.iregs[MD_CONTEXT_ARM_REG_LR]); 964 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]); 965 EXPECT_EQ(frame2_fp.Value(), 966 frame1->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]); 967 EXPECT_EQ("enchiridion", frame1->function_name); 968 EXPECT_EQ(0x40004000U, frame1->function_base); 969 970 971 StackFrameARM *frame2 = static_cast<StackFrameARM*>(frames->at(2)); 972 EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust); 973 ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC | 974 StackFrameARM::CONTEXT_VALID_LR | 975 StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) | 976 StackFrameARM::CONTEXT_VALID_SP), 977 frame2->context_validity); 978 EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]); 979 EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_LR]); 980 EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]); 981 EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]); 982 }