Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <cstdlib> | 8 #include <cstdlib> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 #endif | 42 #endif |
| 43 | 43 |
| 44 #if defined(OS_WIN) | 44 #if defined(OS_WIN) |
| 45 #pragma intrinsic(_ReturnAddress) | 45 #pragma intrinsic(_ReturnAddress) |
| 46 #endif | 46 #endif |
| 47 | 47 |
| 48 namespace base { | 48 namespace base { |
| 49 | 49 |
| 50 using SamplingParams = StackSamplingProfiler::SamplingParams; | 50 using SamplingParams = StackSamplingProfiler::SamplingParams; |
| 51 using Frame = StackSamplingProfiler::Frame; | 51 using Frame = StackSamplingProfiler::Frame; |
| 52 using Frames = std::vector<StackSamplingProfiler::Frame>; | |
| 52 using Module = StackSamplingProfiler::Module; | 53 using Module = StackSamplingProfiler::Module; |
| 53 using Sample = StackSamplingProfiler::Sample; | 54 using Sample = StackSamplingProfiler::Sample; |
| 54 using CallStackProfile = StackSamplingProfiler::CallStackProfile; | 55 using CallStackProfile = StackSamplingProfiler::CallStackProfile; |
| 55 using CallStackProfiles = StackSamplingProfiler::CallStackProfiles; | 56 using CallStackProfiles = StackSamplingProfiler::CallStackProfiles; |
| 56 | 57 |
| 57 namespace { | 58 namespace { |
| 58 | 59 |
| 59 // Configuration for the frames that appear on the stack. | 60 // Configuration for the frames that appear on the stack. |
| 60 struct StackConfiguration { | 61 struct StackConfiguration { |
| 61 enum Config { NORMAL, WITH_ALLOCA, WITH_OTHER_LIBRARY }; | 62 enum Config { NORMAL, WITH_ALLOCA, WITH_OTHER_LIBRARY }; |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 389 reinterpret_cast<const unsigned char*>(offset + 1); | 390 reinterpret_cast<const unsigned char*>(offset + 1); |
| 390 return next_instruction + *offset; | 391 return next_instruction + *offset; |
| 391 } | 392 } |
| 392 #endif | 393 #endif |
| 393 return function_address; | 394 return function_address; |
| 394 } | 395 } |
| 395 | 396 |
| 396 // Searches through the frames in |sample|, returning an iterator to the first | 397 // Searches through the frames in |sample|, returning an iterator to the first |
| 397 // frame that has an instruction pointer within |target_function|. Returns | 398 // frame that has an instruction pointer within |target_function|. Returns |
| 398 // sample.end() if no such frames are found. | 399 // sample.end() if no such frames are found. |
| 399 Sample::const_iterator FindFirstFrameWithinFunction( | 400 Frames::const_iterator FindFirstFrameWithinFunction( |
| 400 const Sample& sample, | 401 const Sample& sample, |
| 401 TargetFunction target_function) { | 402 TargetFunction target_function) { |
| 402 uintptr_t function_start = reinterpret_cast<uintptr_t>( | 403 uintptr_t function_start = reinterpret_cast<uintptr_t>( |
| 403 MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( | 404 MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( |
| 404 target_function))); | 405 target_function))); |
| 405 uintptr_t function_end = | 406 uintptr_t function_end = |
| 406 reinterpret_cast<uintptr_t>(target_function(nullptr, nullptr, nullptr)); | 407 reinterpret_cast<uintptr_t>(target_function(nullptr, nullptr, nullptr)); |
| 407 for (auto it = sample.begin(); it != sample.end(); ++it) { | 408 for (auto it = sample.frames.begin(); it != sample.frames.end(); ++it) { |
| 408 if ((it->instruction_pointer >= function_start) && | 409 if ((it->instruction_pointer >= function_start) && |
| 409 (it->instruction_pointer <= function_end)) | 410 (it->instruction_pointer <= function_end)) |
| 410 return it; | 411 return it; |
| 411 } | 412 } |
| 412 return sample.end(); | 413 return sample.frames.end(); |
| 413 } | 414 } |
| 414 | 415 |
| 415 // Formats a sample into a string that can be output for test diagnostics. | 416 // Formats a sample into a string that can be output for test diagnostics. |
| 416 std::string FormatSampleForDiagnosticOutput( | 417 std::string FormatSampleForDiagnosticOutput( |
| 417 const Sample& sample, | 418 const Sample& sample, |
| 418 const std::vector<Module>& modules) { | 419 const std::vector<Module>& modules) { |
| 419 std::string output; | 420 std::string output; |
| 420 for (const Frame& frame : sample) { | 421 for (const Frame& frame : sample.frames) { |
| 421 output += StringPrintf( | 422 output += StringPrintf( |
| 422 "0x%p %s\n", reinterpret_cast<const void*>(frame.instruction_pointer), | 423 "0x%p %s\n", reinterpret_cast<const void*>(frame.instruction_pointer), |
| 423 modules[frame.module_index].filename.AsUTF8Unsafe().c_str()); | 424 modules[frame.module_index].filename.AsUTF8Unsafe().c_str()); |
| 424 } | 425 } |
| 425 return output; | 426 return output; |
| 426 } | 427 } |
| 427 | 428 |
| 428 // Returns a duration that is longer than the test timeout. We would use | 429 // Returns a duration that is longer than the test timeout. We would use |
| 429 // TimeDelta::Max() but https://crbug.com/465948. | 430 // TimeDelta::Max() but https://crbug.com/465948. |
| 430 TimeDelta AVeryLongTimeDelta() { return TimeDelta::FromDays(1); } | 431 TimeDelta AVeryLongTimeDelta() { return TimeDelta::FromDays(1); } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 511 sampling_thread_completed.Wait(); | 512 sampling_thread_completed.Wait(); |
| 512 | 513 |
| 513 // Look up the sample. | 514 // Look up the sample. |
| 514 ASSERT_EQ(1u, profiles.size()); | 515 ASSERT_EQ(1u, profiles.size()); |
| 515 const CallStackProfile& profile = profiles[0]; | 516 const CallStackProfile& profile = profiles[0]; |
| 516 ASSERT_EQ(1u, profile.samples.size()); | 517 ASSERT_EQ(1u, profile.samples.size()); |
| 517 const Sample& sample = profile.samples[0]; | 518 const Sample& sample = profile.samples[0]; |
| 518 | 519 |
| 519 // Check that the stack contains a frame for | 520 // Check that the stack contains a frame for |
| 520 // TargetThread::SignalAndWaitUntilSignaled(). | 521 // TargetThread::SignalAndWaitUntilSignaled(). |
| 521 Sample::const_iterator end_frame = FindFirstFrameWithinFunction( | 522 Frames::const_iterator end_frame = FindFirstFrameWithinFunction( |
| 522 sample, | 523 sample, |
| 523 &TargetThread::SignalAndWaitUntilSignaled); | 524 &TargetThread::SignalAndWaitUntilSignaled); |
| 524 ASSERT_TRUE(end_frame != sample.end()) | 525 ASSERT_TRUE(end_frame != sample.frames.end()) |
| 525 << "Function at " | 526 << "Function at " |
| 526 << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( | 527 << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( |
| 527 &TargetThread::SignalAndWaitUntilSignaled)) | 528 &TargetThread::SignalAndWaitUntilSignaled)) |
| 528 << " was not found in stack:\n" | 529 << " was not found in stack:\n" |
| 529 << FormatSampleForDiagnosticOutput(sample, profile.modules); | 530 << FormatSampleForDiagnosticOutput(sample, profile.modules); |
| 530 | 531 |
| 531 if (wait_until_unloaded) { | 532 if (wait_until_unloaded) { |
| 532 // The stack should look like this, resulting one frame after | 533 // The stack should look like this, resulting one frame after |
| 533 // SignalAndWaitUntilSignaled. The frame in the now-unloaded library is not | 534 // SignalAndWaitUntilSignaled. The frame in the now-unloaded library is not |
| 534 // recorded since we can't get module information. | 535 // recorded since we can't get module information. |
| 535 // | 536 // |
| 536 // ... WaitableEvent and system frames ... | 537 // ... WaitableEvent and system frames ... |
| 537 // TargetThread::SignalAndWaitUntilSignaled | 538 // TargetThread::SignalAndWaitUntilSignaled |
| 538 // TargetThread::OtherLibraryCallback | 539 // TargetThread::OtherLibraryCallback |
| 539 EXPECT_EQ(2, sample.end() - end_frame) | 540 EXPECT_EQ(2, sample.frames.end() - end_frame) |
| 540 << "Stack:\n" | 541 << "Stack:\n" |
| 541 << FormatSampleForDiagnosticOutput(sample, profile.modules); | 542 << FormatSampleForDiagnosticOutput(sample, profile.modules); |
| 542 } else { | 543 } else { |
| 543 // We didn't wait for the asynchonous unloading to complete, so the results | 544 // We didn't wait for the asynchonous unloading to complete, so the results |
| 544 // are non-deterministic: if the library finished unloading we should have | 545 // are non-deterministic: if the library finished unloading we should have |
| 545 // the same stack as |wait_until_unloaded|, if not we should have the full | 546 // the same stack as |wait_until_unloaded|, if not we should have the full |
| 546 // stack. The important thing is that we should not crash. | 547 // stack. The important thing is that we should not crash. |
| 547 | 548 |
| 548 if ((sample.end() - 1) - end_frame == 2) { | 549 if ((sample.frames.end() - 1) - end_frame == 2) { |
| 549 // This is the same case as |wait_until_unloaded|. | 550 // This is the same case as |wait_until_unloaded|. |
| 550 return; | 551 return; |
| 551 } | 552 } |
| 552 | 553 |
| 553 // Check that the stack contains a frame for | 554 // Check that the stack contains a frame for |
| 554 // TargetThread::CallThroughOtherLibrary(). | 555 // TargetThread::CallThroughOtherLibrary(). |
| 555 Sample::const_iterator other_library_frame = FindFirstFrameWithinFunction( | 556 Frames::const_iterator other_library_frame = FindFirstFrameWithinFunction( |
| 556 sample, | 557 sample, |
| 557 &TargetThread::CallThroughOtherLibrary); | 558 &TargetThread::CallThroughOtherLibrary); |
| 558 ASSERT_TRUE(other_library_frame != sample.end()) | 559 ASSERT_TRUE(other_library_frame != sample.frames.end()) |
| 559 << "Function at " | 560 << "Function at " |
| 560 << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( | 561 << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( |
| 561 &TargetThread::CallThroughOtherLibrary)) | 562 &TargetThread::CallThroughOtherLibrary)) |
| 562 << " was not found in stack:\n" | 563 << " was not found in stack:\n" |
| 563 << FormatSampleForDiagnosticOutput(sample, profile.modules); | 564 << FormatSampleForDiagnosticOutput(sample, profile.modules); |
| 564 | 565 |
| 565 // The stack should look like this, resulting in three frames between | 566 // The stack should look like this, resulting in three frames between |
| 566 // SignalAndWaitUntilSignaled and CallThroughOtherLibrary: | 567 // SignalAndWaitUntilSignaled and CallThroughOtherLibrary: |
| 567 // | 568 // |
| 568 // ... WaitableEvent and system frames ... | 569 // ... WaitableEvent and system frames ... |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 579 } // namespace | 580 } // namespace |
| 580 | 581 |
| 581 // Checks that the basic expected information is present in a sampled call stack | 582 // Checks that the basic expected information is present in a sampled call stack |
| 582 // profile. | 583 // profile. |
| 583 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) | 584 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) |
| 584 #define MAYBE_Basic Basic | 585 #define MAYBE_Basic Basic |
| 585 #else | 586 #else |
| 586 #define MAYBE_Basic DISABLED_Basic | 587 #define MAYBE_Basic DISABLED_Basic |
| 587 #endif | 588 #endif |
| 588 TEST(StackSamplingProfilerTest, MAYBE_Basic) { | 589 TEST(StackSamplingProfilerTest, MAYBE_Basic) { |
| 590 StackSamplingProfiler::ResetPhaseAndActivityForTesting(); | |
| 591 | |
| 589 SamplingParams params; | 592 SamplingParams params; |
| 590 params.sampling_interval = TimeDelta::FromMilliseconds(0); | 593 params.sampling_interval = TimeDelta::FromMilliseconds(0); |
| 591 params.samples_per_burst = 1; | 594 params.samples_per_burst = 1; |
| 592 | 595 |
| 593 std::vector<CallStackProfile> profiles; | 596 std::vector<CallStackProfile> profiles; |
| 594 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); | 597 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); |
| 595 | 598 |
| 596 // Check that the profile and samples sizes are correct, and the module | 599 // Check that the profile and samples sizes are correct, and the module |
| 597 // indices are in range. | 600 // indices are in range. |
| 598 ASSERT_EQ(1u, profiles.size()); | 601 ASSERT_EQ(1u, profiles.size()); |
| 599 const CallStackProfile& profile = profiles[0]; | 602 const CallStackProfile& profile = profiles[0]; |
| 600 ASSERT_EQ(1u, profile.samples.size()); | 603 ASSERT_EQ(1u, profile.samples.size()); |
| 601 EXPECT_EQ(params.sampling_interval, profile.sampling_period); | 604 EXPECT_EQ(params.sampling_interval, profile.sampling_period); |
| 602 const Sample& sample = profile.samples[0]; | 605 const Sample& sample = profile.samples[0]; |
| 603 for (const auto& frame : sample) { | 606 EXPECT_EQ(0u, sample.process_phases); |
| 607 EXPECT_EQ(0u, sample.current_activities); | |
| 608 for (const auto& frame : sample.frames) { | |
| 604 ASSERT_GE(frame.module_index, 0u); | 609 ASSERT_GE(frame.module_index, 0u); |
| 605 ASSERT_LT(frame.module_index, profile.modules.size()); | 610 ASSERT_LT(frame.module_index, profile.modules.size()); |
| 606 } | 611 } |
| 607 | 612 |
| 608 // Check that the stack contains a frame for | 613 // Check that the stack contains a frame for |
| 609 // TargetThread::SignalAndWaitUntilSignaled() and that the frame has this | 614 // TargetThread::SignalAndWaitUntilSignaled() and that the frame has this |
| 610 // executable's module. | 615 // executable's module. |
| 611 Sample::const_iterator loc = FindFirstFrameWithinFunction( | 616 Frames::const_iterator loc = FindFirstFrameWithinFunction( |
| 612 sample, | 617 sample, |
| 613 &TargetThread::SignalAndWaitUntilSignaled); | 618 &TargetThread::SignalAndWaitUntilSignaled); |
| 614 ASSERT_TRUE(loc != sample.end()) | 619 ASSERT_TRUE(loc != sample.frames.end()) |
| 615 << "Function at " | 620 << "Function at " |
| 616 << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( | 621 << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( |
| 617 &TargetThread::SignalAndWaitUntilSignaled)) | 622 &TargetThread::SignalAndWaitUntilSignaled)) |
| 618 << " was not found in stack:\n" | 623 << " was not found in stack:\n" |
| 619 << FormatSampleForDiagnosticOutput(sample, profile.modules); | 624 << FormatSampleForDiagnosticOutput(sample, profile.modules); |
| 620 FilePath executable_path; | 625 FilePath executable_path; |
| 621 EXPECT_TRUE(PathService::Get(FILE_EXE, &executable_path)); | 626 EXPECT_TRUE(PathService::Get(FILE_EXE, &executable_path)); |
| 622 EXPECT_EQ(executable_path, profile.modules[loc->module_index].filename); | 627 EXPECT_EQ(executable_path, profile.modules[loc->module_index].filename); |
| 623 } | 628 } |
| 624 | 629 |
| 630 // Checks that annotations are recorded in samples. | |
| 631 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) | |
| 632 #define MAYBE_Annotations Annotations | |
| 633 #else | |
| 634 #define MAYBE_Annotations DISABLED_Annotations | |
|
Alexei Svitkine (slow)
2016/11/07 23:22:07
How about just having the full TEST() {} block ins
bcwhite
2016/11/08 01:02:36
I've wondered about that but this seems to be the
Mike Wittman
2016/11/16 22:36:09
This structure keeps the tests compiling on non-Wi
| |
| 635 #endif | |
| 636 TEST(StackSamplingProfilerTest, MAYBE_Annotations) { | |
| 637 StackSamplingProfiler::ResetPhaseAndActivityForTesting(); | |
| 638 | |
| 639 SamplingParams params; | |
| 640 params.sampling_interval = TimeDelta::FromMilliseconds(0); | |
| 641 params.samples_per_burst = 1; | |
| 642 | |
| 643 // Check that a run picks up annotations. | |
| 644 StackSamplingProfiler::SetProcessPhase(1); | |
| 645 StackSamplingProfiler::RecordActivityBegin(11); | |
| 646 std::vector<CallStackProfile> profiles1; | |
| 647 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles1); | |
| 648 ASSERT_EQ(1u, profiles1.size()); | |
| 649 const CallStackProfile& profile1 = profiles1[0]; | |
| 650 ASSERT_EQ(1u, profile1.samples.size()); | |
| 651 EXPECT_EQ(params.sampling_interval, profile1.sampling_period); | |
| 652 const Sample& sample1 = profile1.samples[0]; | |
| 653 EXPECT_EQ(1u << 1, sample1.process_phases); | |
| 654 EXPECT_EQ(1u << 11, sample1.current_activities); | |
| 655 | |
| 656 // Run it a second time but with changed annotations. These annotations | |
| 657 // should appear in the first acquired sample. | |
| 658 StackSamplingProfiler::SetProcessPhase(2); | |
| 659 StackSamplingProfiler::RecordActivityBegin(12); | |
| 660 StackSamplingProfiler::RecordActivityEnd(11); | |
| 661 std::vector<CallStackProfile> profiles2; | |
| 662 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles2); | |
| 663 ASSERT_EQ(1u, profiles2.size()); | |
| 664 const CallStackProfile& profile2 = profiles2[0]; | |
| 665 ASSERT_EQ(1u, profile2.samples.size()); | |
| 666 const Sample& sample2 = profile2.samples[0]; | |
| 667 EXPECT_EQ(sample1.process_phases | (1u << 2), sample2.process_phases); | |
| 668 EXPECT_EQ(1u << 12, sample2.current_activities); | |
| 669 } | |
| 670 | |
| 625 // Checks that the profiler handles stacks containing dynamically-allocated | 671 // Checks that the profiler handles stacks containing dynamically-allocated |
| 626 // stack memory. | 672 // stack memory. |
| 627 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) | 673 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) |
| 628 #define MAYBE_Alloca Alloca | 674 #define MAYBE_Alloca Alloca |
| 629 #else | 675 #else |
| 630 #define MAYBE_Alloca DISABLED_Alloca | 676 #define MAYBE_Alloca DISABLED_Alloca |
| 631 #endif | 677 #endif |
| 632 TEST(StackSamplingProfilerTest, MAYBE_Alloca) { | 678 TEST(StackSamplingProfilerTest, MAYBE_Alloca) { |
| 633 SamplingParams params; | 679 SamplingParams params; |
| 634 params.sampling_interval = TimeDelta::FromMilliseconds(0); | 680 params.sampling_interval = TimeDelta::FromMilliseconds(0); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 650 StackConfiguration(StackConfiguration::WITH_ALLOCA)); | 696 StackConfiguration(StackConfiguration::WITH_ALLOCA)); |
| 651 | 697 |
| 652 // Look up the sample. | 698 // Look up the sample. |
| 653 ASSERT_EQ(1u, profiles.size()); | 699 ASSERT_EQ(1u, profiles.size()); |
| 654 const CallStackProfile& profile = profiles[0]; | 700 const CallStackProfile& profile = profiles[0]; |
| 655 ASSERT_EQ(1u, profile.samples.size()); | 701 ASSERT_EQ(1u, profile.samples.size()); |
| 656 const Sample& sample = profile.samples[0]; | 702 const Sample& sample = profile.samples[0]; |
| 657 | 703 |
| 658 // Check that the stack contains a frame for | 704 // Check that the stack contains a frame for |
| 659 // TargetThread::SignalAndWaitUntilSignaled(). | 705 // TargetThread::SignalAndWaitUntilSignaled(). |
| 660 Sample::const_iterator end_frame = FindFirstFrameWithinFunction( | 706 Frames::const_iterator end_frame = FindFirstFrameWithinFunction( |
| 661 sample, | 707 sample, |
| 662 &TargetThread::SignalAndWaitUntilSignaled); | 708 &TargetThread::SignalAndWaitUntilSignaled); |
| 663 ASSERT_TRUE(end_frame != sample.end()) | 709 ASSERT_TRUE(end_frame != sample.frames.end()) |
| 664 << "Function at " | 710 << "Function at " |
| 665 << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( | 711 << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( |
| 666 &TargetThread::SignalAndWaitUntilSignaled)) | 712 &TargetThread::SignalAndWaitUntilSignaled)) |
| 667 << " was not found in stack:\n" | 713 << " was not found in stack:\n" |
| 668 << FormatSampleForDiagnosticOutput(sample, profile.modules); | 714 << FormatSampleForDiagnosticOutput(sample, profile.modules); |
| 669 | 715 |
| 670 // Check that the stack contains a frame for TargetThread::CallWithAlloca(). | 716 // Check that the stack contains a frame for TargetThread::CallWithAlloca(). |
| 671 Sample::const_iterator alloca_frame = FindFirstFrameWithinFunction( | 717 Frames::const_iterator alloca_frame = FindFirstFrameWithinFunction( |
| 672 sample, | 718 sample, |
| 673 &TargetThread::CallWithAlloca); | 719 &TargetThread::CallWithAlloca); |
| 674 ASSERT_TRUE(alloca_frame != sample.end()) | 720 ASSERT_TRUE(alloca_frame != sample.frames.end()) |
| 675 << "Function at " | 721 << "Function at " |
| 676 << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( | 722 << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( |
| 677 &TargetThread::CallWithAlloca)) | 723 &TargetThread::CallWithAlloca)) |
| 678 << " was not found in stack:\n" | 724 << " was not found in stack:\n" |
| 679 << FormatSampleForDiagnosticOutput(sample, profile.modules); | 725 << FormatSampleForDiagnosticOutput(sample, profile.modules); |
| 680 | 726 |
| 681 // These frames should be adjacent on the stack. | 727 // These frames should be adjacent on the stack. |
| 682 EXPECT_EQ(1, alloca_frame - end_frame) | 728 EXPECT_EQ(1, alloca_frame - end_frame) |
| 683 << "Stack:\n" | 729 << "Stack:\n" |
| 684 << FormatSampleForDiagnosticOutput(sample, profile.modules); | 730 << FormatSampleForDiagnosticOutput(sample, profile.modules); |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 920 } | 966 } |
| 921 | 967 |
| 922 // Look up the sample. | 968 // Look up the sample. |
| 923 ASSERT_EQ(1u, profiles.size()); | 969 ASSERT_EQ(1u, profiles.size()); |
| 924 const CallStackProfile& profile = profiles[0]; | 970 const CallStackProfile& profile = profiles[0]; |
| 925 ASSERT_EQ(1u, profile.samples.size()); | 971 ASSERT_EQ(1u, profile.samples.size()); |
| 926 const Sample& sample = profile.samples[0]; | 972 const Sample& sample = profile.samples[0]; |
| 927 | 973 |
| 928 // Check that the stack contains a frame for | 974 // Check that the stack contains a frame for |
| 929 // TargetThread::CallThroughOtherLibrary(). | 975 // TargetThread::CallThroughOtherLibrary(). |
| 930 Sample::const_iterator other_library_frame = FindFirstFrameWithinFunction( | 976 Frames::const_iterator other_library_frame = FindFirstFrameWithinFunction( |
| 931 sample, | 977 sample, |
| 932 &TargetThread::CallThroughOtherLibrary); | 978 &TargetThread::CallThroughOtherLibrary); |
| 933 ASSERT_TRUE(other_library_frame != sample.end()) | 979 ASSERT_TRUE(other_library_frame != sample.frames.end()) |
| 934 << "Function at " | 980 << "Function at " |
| 935 << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( | 981 << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( |
| 936 &TargetThread::CallThroughOtherLibrary)) | 982 &TargetThread::CallThroughOtherLibrary)) |
| 937 << " was not found in stack:\n" | 983 << " was not found in stack:\n" |
| 938 << FormatSampleForDiagnosticOutput(sample, profile.modules); | 984 << FormatSampleForDiagnosticOutput(sample, profile.modules); |
| 939 | 985 |
| 940 // Check that the stack contains a frame for | 986 // Check that the stack contains a frame for |
| 941 // TargetThread::SignalAndWaitUntilSignaled(). | 987 // TargetThread::SignalAndWaitUntilSignaled(). |
| 942 Sample::const_iterator end_frame = FindFirstFrameWithinFunction( | 988 Frames::const_iterator end_frame = FindFirstFrameWithinFunction( |
| 943 sample, | 989 sample, |
| 944 &TargetThread::SignalAndWaitUntilSignaled); | 990 &TargetThread::SignalAndWaitUntilSignaled); |
| 945 ASSERT_TRUE(end_frame != sample.end()) | 991 ASSERT_TRUE(end_frame != sample.frames.end()) |
| 946 << "Function at " | 992 << "Function at " |
| 947 << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( | 993 << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( |
| 948 &TargetThread::SignalAndWaitUntilSignaled)) | 994 &TargetThread::SignalAndWaitUntilSignaled)) |
| 949 << " was not found in stack:\n" | 995 << " was not found in stack:\n" |
| 950 << FormatSampleForDiagnosticOutput(sample, profile.modules); | 996 << FormatSampleForDiagnosticOutput(sample, profile.modules); |
| 951 | 997 |
| 952 // The stack should look like this, resulting in three frames between | 998 // The stack should look like this, resulting in three frames between |
| 953 // SignalAndWaitUntilSignaled and CallThroughOtherLibrary: | 999 // SignalAndWaitUntilSignaled and CallThroughOtherLibrary: |
| 954 // | 1000 // |
| 955 // ... WaitableEvent and system frames ... | 1001 // ... WaitableEvent and system frames ... |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 977 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) | 1023 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) |
| 978 #define MAYBE_UnloadedLibrary UnloadedLibrary | 1024 #define MAYBE_UnloadedLibrary UnloadedLibrary |
| 979 #else | 1025 #else |
| 980 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary | 1026 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary |
| 981 #endif | 1027 #endif |
| 982 TEST(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) { | 1028 TEST(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) { |
| 983 TestLibraryUnload(true); | 1029 TestLibraryUnload(true); |
| 984 } | 1030 } |
| 985 | 1031 |
| 986 } // namespace base | 1032 } // namespace base |
| OLD | NEW |