Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(857)

Side by Side Diff: src/processor/stackwalker_amd64_unittest.cc

Issue 1408973002: Issue in StackwalkerAMD64::GetCallerByFramePointerRecovery. (Closed) Base URL: https://chromium.googlesource.com/breakpad/breakpad.git@master
Patch Set: Combining IsEndOfStack and rbp checks Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/processor/stackwalker_amd64.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010, Google Inc. 1 // Copyright (c) 2010, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 StackFrameAMD64::CONTEXT_VALID_RSP | 363 StackFrameAMD64::CONTEXT_VALID_RSP |
364 StackFrameAMD64::CONTEXT_VALID_RBP), 364 StackFrameAMD64::CONTEXT_VALID_RBP),
365 frame1->context_validity); 365 frame1->context_validity);
366 EXPECT_EQ(return_address, frame1->context.rip); 366 EXPECT_EQ(return_address, frame1->context.rip);
367 EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp); 367 EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp);
368 EXPECT_EQ(frame1_rbp.Value(), frame1->context.rbp); 368 EXPECT_EQ(frame1_rbp.Value(), frame1->context.rbp);
369 EXPECT_EQ("echidna", frame1->function_name); 369 EXPECT_EQ("echidna", frame1->function_name);
370 EXPECT_EQ(0x50000000b0000100ULL, frame1->function_base); 370 EXPECT_EQ(0x50000000b0000100ULL, frame1->function_base);
371 } 371 }
372 372
373 // StackwalkerAMD64::GetCallerByFramePointerRecovery should never return an
374 // instruction pointer of 0 because IP of 0 is an end of stack marker and the
375 // stack walk may be terminated prematurely. Instead it should return NULL
376 // so that the stack walking code can proceed to stack scanning.
377 TEST_F(GetCallerFrame, GetCallerByFramePointerRecovery) {
378 MockCodeModule user32_dll(0x00007ff9cb8a0000ULL, 0x14E000, "user32.dll",
379 "version1");
380 SetModuleSymbols(&user32_dll, // user32.dll
381 "PUBLIC fa60 0 DispatchMessageWorker\n"
382 "PUBLIC fee0 0 UserCallWinProcCheckWow\n"
383 "PUBLIC 1cdb0 0 _fnHkINLPMSG\n"
384 "STACK CFI INIT fa60 340 .cfa: $rsp .ra: .cfa 8 - ^\n"
385 "STACK CFI fa60 .cfa: $rsp 128 +\n"
386 "STACK CFI INIT fee0 49f .cfa: $rsp .ra: .cfa 8 - ^\n"
387 "STACK CFI fee0 .cfa: $rsp 240 +\n"
388 "STACK CFI INIT 1cdb0 9f .cfa: $rsp .ra: .cfa 8 - ^\n"
389 "STACK CFI 1cdb0 .cfa: $rsp 80 +\n");
390
391 // Create some modules with some stock debugging information.
392 MockCodeModules local_modules;
393 local_modules.Add(&user32_dll);
394
395 Label frame0_rsp;
396 Label frame0_rbp;
397 Label frame1_rsp;
398 Label frame2_rsp;
399
400 stack_section.start() = 0x00000099abf0f238ULL;
401 stack_section
402 .Mark(&frame0_rsp)
403 .D64(0x00007ff9cb8b00dcULL)
404 .Mark(&frame1_rsp)
405 .D64(0x0000000000000000ULL)
406 .D64(0x0000000000000001ULL)
407 .D64(0x00000099abf0f308ULL)
408 .D64(0x00007ff9cb8bce3aULL) // Stack residue from execution of
409 // user32!_fnHkINLPMSG+0x8a
410 .D64(0x000000000000c2e0ULL)
411 .D64(0x00000099abf0f328ULL)
412 .D64(0x0000000100000001ULL)
413 .D64(0x0000000000000000ULL)
414 .D64(0x0000000000000000ULL)
415 .D64(0x0000000000000000ULL)
416 .D64(0x0000000000000000ULL)
417 .D64(0x0000000000000000ULL)
418 .D64(0x0000000000000000ULL)
419 .D64(0x00007ff9ccad53e4ULL)
420 .D64(0x0000000000000048ULL)
421 .D64(0x0000000000000001ULL)
422 .D64(0x00000099abf0f5e0ULL)
423 .D64(0x00000099b61f7388ULL)
424 .D64(0x0000000000000030ULL)
425 .D64(0xffffff66540f0a1fULL)
426 .D64(0xffffff6649e08c77ULL)
427 .D64(0x00007ff9cb8affb4ULL) // Return address in
428 // user32!UserCallWinProcCheckWow+0xd4
429 .D64(0x0000000000000000ULL)
430 .D64(0x00000099abf0f368ULL)
431 .D64(0x0000000000000000ULL)
432 .D64(0x0000000000000000ULL)
433 .D64(0x0000000000000000ULL)
434 .D64(0x00000099a8150fd8ULL)
435 .D64(0x00000099abf0f3e8ULL)
436 .D64(0x00007ff9cb8afc07ULL) // Return address in
437 // user32!DispatchMessageWorker+0x1a7
438 .Mark(&frame2_rsp)
439 .Append(256, 0)
440 .Mark(&frame0_rbp) // The following are expected by
441 // GetCallerByFramePointerRecovery.
442 .D64(0xfffffffffffffffeULL) // %caller_rbp = *(%callee_rbp)
443 .D64(0x0000000000000000ULL) // %caller_rip = *(%callee_rbp + 8)
444 .D64(0x00000099a3e31040ULL) // %caller_rsp = *(%callee_rbp + 16)
445 .Append(256, 0);
446
447 RegionFromSection();
448 raw_context.rip = 0x00000099a8150fd8ULL; // IP in context frame is guarbage
449 raw_context.rsp = frame0_rsp.Value();
450 raw_context.rbp = frame0_rbp.Value();
451
452 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
453 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region,
454 &local_modules, &frame_symbolizer);
455 vector<const CodeModule*> modules_without_symbols;
456 vector<const CodeModule*> modules_with_corrupt_symbols;
457 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
458 &modules_with_corrupt_symbols));
459 ASSERT_EQ(0U, modules_without_symbols.size());
460 ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
461 frames = call_stack.frames();
462
463 ASSERT_EQ(3U, frames->size());
464
465 { // To avoid reusing locals by mistake
466 StackFrameAMD64 *frame = static_cast<StackFrameAMD64 *>(frames->at(0));
467 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame->trust);
468 ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame->context_validity);
469 EXPECT_EQ("", frame->function_name);
470 EXPECT_EQ(0x00000099a8150fd8ULL, frame->instruction);
471 EXPECT_EQ(0x00000099a8150fd8ULL, frame->context.rip);
472 EXPECT_EQ(frame0_rsp.Value(), frame->context.rsp);
473 EXPECT_EQ(frame0_rbp.Value(), frame->context.rbp);
474 }
475
476 { // To avoid reusing locals by mistake
477 StackFrameAMD64 *frame = static_cast<StackFrameAMD64 *>(frames->at(1));
478 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame->trust);
479 ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
480 StackFrameAMD64::CONTEXT_VALID_RSP |
481 StackFrameAMD64::CONTEXT_VALID_RBP),
482 frame->context_validity);
483 EXPECT_EQ("UserCallWinProcCheckWow", frame->function_name);
484 EXPECT_EQ(140710838468828ULL, frame->instruction + 1);
485 EXPECT_EQ(140710838468828ULL, frame->context.rip);
486 EXPECT_EQ(frame1_rsp.Value(), frame->context.rsp);
487 EXPECT_EQ(&user32_dll, frame->module);
488 }
489
490 { // To avoid reusing locals by mistake
491 StackFrameAMD64 *frame = static_cast<StackFrameAMD64 *>(frames->at(2));
492 EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame->trust);
493 ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
494 StackFrameAMD64::CONTEXT_VALID_RSP |
495 StackFrameAMD64::CONTEXT_VALID_RBP),
496 frame->context_validity);
497 EXPECT_EQ("DispatchMessageWorker", frame->function_name);
498 EXPECT_EQ(140710838467591ULL, frame->instruction + 1);
499 EXPECT_EQ(140710838467591ULL, frame->context.rip);
500 EXPECT_EQ(frame2_rsp.Value(), frame->context.rsp);
501 EXPECT_EQ(&user32_dll, frame->module);
502 }
503 }
504
373 // Test that set_max_frames_scanned prevents using stack scanning 505 // Test that set_max_frames_scanned prevents using stack scanning
374 // to find caller frames. 506 // to find caller frames.
375 TEST_F(GetCallerFrame, ScanningNotAllowed) { 507 TEST_F(GetCallerFrame, ScanningNotAllowed) {
376 // When the stack walker resorts to scanning the stack, 508 // When the stack walker resorts to scanning the stack,
377 // only addresses located within loaded modules are 509 // only addresses located within loaded modules are
378 // considered valid return addresses. 510 // considered valid return addresses.
379 stack_section.start() = 0x8000000080000000ULL; 511 stack_section.start() = 0x8000000080000000ULL;
380 uint64_t return_address1 = 0x50000000b0000100ULL; 512 uint64_t return_address1 = 0x50000000b0000100ULL;
381 uint64_t return_address2 = 0x50000000b0000900ULL; 513 uint64_t return_address2 = 0x50000000b0000900ULL;
382 Label frame1_sp, frame2_sp, frame1_rbp; 514 Label frame1_sp, frame2_sp, frame1_rbp;
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 .D64(0x5a5beeb38de23be8ULL) // saved %rbx 822 .D64(0x5a5beeb38de23be8ULL) // saved %rbx
691 .D64(0xf015ee516ad89eabULL) // garbage 823 .D64(0xf015ee516ad89eabULL) // garbage
692 .Mark(&frame1_rsp); // This effectively sets stack_section.start(). 824 .Mark(&frame1_rsp); // This effectively sets stack_section.start().
693 raw_context.rip = 0x40000000c0004006ULL; 825 raw_context.rip = 0x40000000c0004006ULL;
694 raw_context.rbp = frame0_rbp.Value(); 826 raw_context.rbp = frame0_rbp.Value();
695 raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12 827 raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
696 raw_context.r12 = 0x26e007b341acfebdULL; // callee's %r12 828 raw_context.r12 = 0x26e007b341acfebdULL; // callee's %r12
697 raw_context.r13 = 0x40000000c0005510ULL; // return address 829 raw_context.r13 = 0x40000000c0005510ULL; // return address
698 CheckWalk(); 830 CheckWalk();
699 } 831 }
OLDNEW
« no previous file with comments | « src/processor/stackwalker_amd64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698