// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <cstdlib>
#include <memory>
#include <utility>
#include <vector>

#include "starboard/types.h"

#include "base/bind.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/files/file_util.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/native_library.h"
#include "base/path_service.h"
#include "base/profiler/native_stack_sampler.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "base/run_loop.h"
#include "base/scoped_native_library.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/bind_test_util.h"
#include "base/threading/platform_thread.h"
#include "base/threading/simple_thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_WIN)
#include <intrin.h>
#include <malloc.h>
#include <windows.h>
#else
#include <alloca.h>
#endif

// STACK_SAMPLING_PROFILER_SUPPORTED is used to conditionally enable the tests
// below for supported platforms (currently Win x64 and Mac x64).
#if defined(_WIN64) || (defined(OS_MACOSX) && !defined(OS_IOS))
#define STACK_SAMPLING_PROFILER_SUPPORTED 1
#endif

#if defined(OS_WIN)
#pragma intrinsic(_ReturnAddress)
#endif

namespace base {

#if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
#define PROFILER_TEST_F(TestClass, TestName) TEST_F(TestClass, TestName)
#else
#define PROFILER_TEST_F(TestClass, TestName) \
  TEST_F(TestClass, DISABLED_##TestName)
#endif

using SamplingParams = StackSamplingProfiler::SamplingParams;
using Frame = StackSamplingProfiler::Frame;
using Frames = std::vector<Frame>;
using FrameSets = std::vector<std::vector<Frame>>;

namespace {

// Configuration for the frames that appear on the stack.
struct StackConfiguration {
  enum Config { NORMAL, WITH_ALLOCA, WITH_OTHER_LIBRARY };

  explicit StackConfiguration(Config config)
      : StackConfiguration(config, nullptr) {
    EXPECT_NE(config, WITH_OTHER_LIBRARY);
  }

  StackConfiguration(Config config, NativeLibrary library)
      : config(config), library(library) {
    EXPECT_TRUE(config != WITH_OTHER_LIBRARY || library);
  }

  Config config;

  // Only used if config == WITH_OTHER_LIBRARY.
  NativeLibrary library;
};

// Signature for a target function that is expected to appear in the stack. See
// SignalAndWaitUntilSignaled() below. The return value should be a program
// counter pointer near the end of the function.
using TargetFunction = const void* (*)(WaitableEvent*,
                                       WaitableEvent*,
                                       const StackConfiguration*);

// A thread to target for profiling, whose stack is guaranteed to contain
// SignalAndWaitUntilSignaled() when coordinated with the main thread.
class TargetThread : public PlatformThread::Delegate {
 public:
  explicit TargetThread(const StackConfiguration& stack_config);

  // PlatformThread::Delegate:
  void ThreadMain() override;

  // Waits for the thread to have started and be executing in
  // SignalAndWaitUntilSignaled().
  void WaitForThreadStart();

  // Allows the thread to return from SignalAndWaitUntilSignaled() and finish
  // execution.
  void SignalThreadToFinish();

  // This function is guaranteed to be executing between calls to
  // WaitForThreadStart() and SignalThreadToFinish() when invoked with
  // |thread_started_event_| and |finish_event_|. Returns a program counter
  // value near the end of the function. May be invoked with null WaitableEvents
  // to just return the program counter.
  //
  // This function is static so that we can get a straightforward address
  // for it in one of the tests below, rather than dealing with the complexity
  // of a member function pointer representation.
  static const void* SignalAndWaitUntilSignaled(
      WaitableEvent* thread_started_event,
      WaitableEvent* finish_event,
      const StackConfiguration* stack_config);

  // Calls into SignalAndWaitUntilSignaled() after allocating memory on the
  // stack with alloca.
  static const void* CallWithAlloca(WaitableEvent* thread_started_event,
                                    WaitableEvent* finish_event,
                                    const StackConfiguration* stack_config);

  // Calls into SignalAndWaitUntilSignaled() via a function in
  // base_profiler_test_support_library.
  static const void* CallThroughOtherLibrary(
      WaitableEvent* thread_started_event,
      WaitableEvent* finish_event,
      const StackConfiguration* stack_config);

  PlatformThreadId id() const { return id_; }

 private:
  struct TargetFunctionArgs {
    WaitableEvent* thread_started_event;
    WaitableEvent* finish_event;
    const StackConfiguration* stack_config;
  };

  // Callback function to be provided when calling through the other library.
  static void OtherLibraryCallback(void* arg);

  // Returns the current program counter, or a value very close to it.
  static const void* GetProgramCounter();

  WaitableEvent thread_started_event_;
  WaitableEvent finish_event_;
  PlatformThreadId id_;
  const StackConfiguration stack_config_;

  DISALLOW_COPY_AND_ASSIGN(TargetThread);
};

TargetThread::TargetThread(const StackConfiguration& stack_config)
    : thread_started_event_(WaitableEvent::ResetPolicy::AUTOMATIC,
                            WaitableEvent::InitialState::NOT_SIGNALED),
      finish_event_(WaitableEvent::ResetPolicy::AUTOMATIC,
                    WaitableEvent::InitialState::NOT_SIGNALED),
      id_(0),
      stack_config_(stack_config) {}

void TargetThread::ThreadMain() {
  id_ = PlatformThread::CurrentId();
  switch (stack_config_.config) {
    case StackConfiguration::NORMAL:
      SignalAndWaitUntilSignaled(&thread_started_event_, &finish_event_,
                                 &stack_config_);
      break;

    case StackConfiguration::WITH_ALLOCA:
      CallWithAlloca(&thread_started_event_, &finish_event_, &stack_config_);
      break;

    case StackConfiguration::WITH_OTHER_LIBRARY:
      CallThroughOtherLibrary(&thread_started_event_, &finish_event_,
                              &stack_config_);
      break;
  }
}

void TargetThread::WaitForThreadStart() {
  thread_started_event_.Wait();
}

void TargetThread::SignalThreadToFinish() {
  finish_event_.Signal();
}

// static
// Disable inlining for this function so that it gets its own stack frame.
NOINLINE const void* TargetThread::SignalAndWaitUntilSignaled(
    WaitableEvent* thread_started_event,
    WaitableEvent* finish_event,
    const StackConfiguration* stack_config) {
  if (thread_started_event && finish_event) {
    thread_started_event->Signal();
    finish_event->Wait();
  }

  // Volatile to prevent a tail call to GetProgramCounter().
  const void* volatile program_counter = GetProgramCounter();
  return program_counter;
}

// static
// Disable inlining for this function so that it gets its own stack frame.
NOINLINE const void* TargetThread::CallWithAlloca(
    WaitableEvent* thread_started_event,
    WaitableEvent* finish_event,
    const StackConfiguration* stack_config) {
  const size_t alloca_size = 100;
  // Memset to 0 to generate a clean failure.
  std::memset(alloca(alloca_size), 0, alloca_size);

  SignalAndWaitUntilSignaled(thread_started_event, finish_event, stack_config);

  // Volatile to prevent a tail call to GetProgramCounter().
  const void* volatile program_counter = GetProgramCounter();
  return program_counter;
}

// static
NOINLINE const void* TargetThread::CallThroughOtherLibrary(
    WaitableEvent* thread_started_event,
    WaitableEvent* finish_event,
    const StackConfiguration* stack_config) {
  if (stack_config) {
    // A function whose arguments are a function accepting void*, and a void*.
    using InvokeCallbackFunction = void (*)(void (*)(void*), void*);
    EXPECT_TRUE(stack_config->library);
    InvokeCallbackFunction function = reinterpret_cast<InvokeCallbackFunction>(
        GetFunctionPointerFromNativeLibrary(stack_config->library,
                                            "InvokeCallbackFunction"));
    EXPECT_TRUE(function);

    TargetFunctionArgs args = {thread_started_event, finish_event,
                               stack_config};
    (*function)(&OtherLibraryCallback, &args);
  }

  // Volatile to prevent a tail call to GetProgramCounter().
  const void* volatile program_counter = GetProgramCounter();
  return program_counter;
}

// static
void TargetThread::OtherLibraryCallback(void* arg) {
  const TargetFunctionArgs* args = static_cast<TargetFunctionArgs*>(arg);
  SignalAndWaitUntilSignaled(args->thread_started_event, args->finish_event,
                             args->stack_config);
  // Prevent tail call.
  volatile int i = 0;
  ALLOW_UNUSED_LOCAL(i);
}

// static
// Disable inlining for this function so that it gets its own stack frame.
NOINLINE const void* TargetThread::GetProgramCounter() {
#if defined(OS_WIN)
  return _ReturnAddress();
#else
  return __builtin_return_address(0);
#endif
}

// Profile consists of a set of frame sets and other sampling information.
struct Profile {
  Profile() = default;
  Profile(Profile&& other) = default;
  Profile(const FrameSets& frame_sets,
          int annotation_count,
          TimeDelta profile_duration,
          TimeDelta sampling_period);

  ~Profile() = default;

  Profile& operator=(Profile&& other) = default;

  // The collected frame sets.
  FrameSets frame_sets;

  // The number of invocations of RecordAnnotations().
  int annotation_count;

  // Duration of this profile.
  TimeDelta profile_duration;

  // Time between samples.
  TimeDelta sampling_period;
};

Profile::Profile(const FrameSets& frame_sets,
                 int annotation_count,
                 TimeDelta profile_duration,
                 TimeDelta sampling_period)
    : frame_sets(frame_sets),
      annotation_count(annotation_count),
      profile_duration(profile_duration),
      sampling_period(sampling_period) {}

// The callback type used to collect a profile. The passed Profile is move-only.
// Other threads, including the UI thread, may block on callback completion so
// this should run as quickly as possible.
using ProfileCompletedCallback = Callback<void(Profile)>;

// TestProfileBuilder collects frames produced by the profiler.
class TestProfileBuilder : public StackSamplingProfiler::ProfileBuilder {
 public:
  TestProfileBuilder(const ProfileCompletedCallback& callback);

  ~TestProfileBuilder() override;

  // StackSamplingProfiler::ProfileBuilder:
  void RecordAnnotations() override;
  void OnSampleCompleted(Frames frames) override;
  void OnProfileCompleted(TimeDelta profile_duration,
                          TimeDelta sampling_period) override;

 private:
  // The sets of frames recorded.
  std::vector<Frames> frame_sets_;

  // The number of invocations of RecordAnnotations().
  int annotation_count_ = 0;

  // Callback made when sampling a profile completes.
  const ProfileCompletedCallback callback_;

  DISALLOW_COPY_AND_ASSIGN(TestProfileBuilder);
};

TestProfileBuilder::TestProfileBuilder(const ProfileCompletedCallback& callback)
    : callback_(callback) {}

TestProfileBuilder::~TestProfileBuilder() = default;

void TestProfileBuilder::RecordAnnotations() {
  ++annotation_count_;
}

void TestProfileBuilder::OnSampleCompleted(Frames frames) {
  frame_sets_.push_back(std::move(frames));
}

void TestProfileBuilder::OnProfileCompleted(TimeDelta profile_duration,
                                            TimeDelta sampling_period) {
  callback_.Run(Profile(frame_sets_, annotation_count_, profile_duration,
                        sampling_period));
}

// Loads the other library, which defines a function to be called in the
// WITH_OTHER_LIBRARY configuration.
NativeLibrary LoadOtherLibrary() {
  // The lambda gymnastics works around the fact that we can't use ASSERT_*
  // macros in a function returning non-null.
  const auto load = [](NativeLibrary* library) {
    FilePath other_library_path;
    ASSERT_TRUE(PathService::Get(DIR_EXE, &other_library_path));
    other_library_path = other_library_path.AppendASCII(
        GetNativeLibraryName("base_profiler_test_support_library"));
    NativeLibraryLoadError load_error;
    *library = LoadNativeLibrary(other_library_path, &load_error);
    ASSERT_TRUE(*library) << "error loading " << other_library_path.value()
                          << ": " << load_error.ToString();
  };

  NativeLibrary library = nullptr;
  load(&library);
  return library;
}

// Unloads |library| and returns when it has completed unloading. Unloading a
// library is asynchronous on Windows, so simply calling UnloadNativeLibrary()
// is insufficient to ensure it's been unloaded.
void SynchronousUnloadNativeLibrary(NativeLibrary library) {
  UnloadNativeLibrary(library);
#if defined(OS_WIN)
  // NativeLibrary is a typedef for HMODULE, which is actually the base address
  // of the module.
  uintptr_t module_base_address = reinterpret_cast<uintptr_t>(library);
  HMODULE module_handle;
  // Keep trying to get the module handle until the call fails.
  while (::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
                                 GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
                             reinterpret_cast<LPCTSTR>(module_base_address),
                             &module_handle) ||
         ::GetLastError() != ERROR_MOD_NOT_FOUND) {
    PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
  }
#elif defined(OS_MACOSX)
// Unloading a library on the Mac is synchronous.
#else
  NOTIMPLEMENTED();
#endif
}

// Executes the function with the target thread running and executing within
// SignalAndWaitUntilSignaled(). Performs all necessary target thread startup
// and shutdown work before and afterward.
template <class Function>
void WithTargetThread(Function function,
                      const StackConfiguration& stack_config) {
  TargetThread target_thread(stack_config);
  PlatformThreadHandle target_thread_handle;
  EXPECT_TRUE(PlatformThread::Create(0, &target_thread, &target_thread_handle));

  target_thread.WaitForThreadStart();

  function(target_thread.id());

  target_thread.SignalThreadToFinish();

  PlatformThread::Join(target_thread_handle);
}

template <class Function>
void WithTargetThread(Function function) {
  WithTargetThread(function, StackConfiguration(StackConfiguration::NORMAL));
}

struct TestProfilerInfo {
  TestProfilerInfo(PlatformThreadId thread_id,
                   const SamplingParams& params,
                   NativeStackSamplerTestDelegate* delegate = nullptr)
      : completed(WaitableEvent::ResetPolicy::MANUAL,
                  WaitableEvent::InitialState::NOT_SIGNALED),
        profiler(thread_id,
                 params,
                 std::make_unique<TestProfileBuilder>(
                     BindLambdaForTesting([this](Profile result_profile) {
                       profile = std::move(result_profile);
                       completed.Signal();
                     })),
                 delegate) {}

  // The order here is important to ensure objects being referenced don't get
  // destructed until after the objects referencing them.
  Profile profile;
  WaitableEvent completed;
  StackSamplingProfiler profiler;

 private:
  DISALLOW_COPY_AND_ASSIGN(TestProfilerInfo);
};

// Creates multiple profilers based on a vector of parameters.
std::vector<std::unique_ptr<TestProfilerInfo>> CreateProfilers(
    PlatformThreadId target_thread_id,
    const std::vector<SamplingParams>& params) {
  DCHECK(!params.empty());

  std::vector<std::unique_ptr<TestProfilerInfo>> profilers;
  for (size_t i = 0; i < params.size(); ++i) {
    profilers.push_back(
        std::make_unique<TestProfilerInfo>(target_thread_id, params[i]));
  }

  return profilers;
}

// Captures frames as specified by |params| on the TargetThread, and returns
// them. Waits up to |profiler_wait_time| for the profiler to complete.
FrameSets CaptureFrameSets(const SamplingParams& params,
                           TimeDelta profiler_wait_time) {
  FrameSets frame_sets;
  WithTargetThread([&params, &frame_sets,
                    profiler_wait_time](PlatformThreadId target_thread_id) {
    TestProfilerInfo info(target_thread_id, params);
    info.profiler.Start();
    info.completed.TimedWait(profiler_wait_time);
    info.profiler.Stop();
    info.completed.Wait();
    frame_sets = std::move(info.profile.frame_sets);
  });

  return frame_sets;
}

// Waits for one of multiple samplings to complete.
size_t WaitForSamplingComplete(
    const std::vector<std::unique_ptr<TestProfilerInfo>>& infos) {
  // Map unique_ptrs to something that WaitMany can accept.
  std::vector<WaitableEvent*> sampling_completed_rawptrs(infos.size());
  std::transform(infos.begin(), infos.end(), sampling_completed_rawptrs.begin(),
                 [](const std::unique_ptr<TestProfilerInfo>& info) {
                   return &info.get()->completed;
                 });
  // Wait for one profiler to finish.
  return WaitableEvent::WaitMany(sampling_completed_rawptrs.data(),
                                 sampling_completed_rawptrs.size());
}

// If this executable was linked with /INCREMENTAL (the default for non-official
// debug and release builds on Windows), function addresses do not correspond to
// function code itself, but instead to instructions in the Incremental Link
// Table that jump to the functions. Checks for a jump instruction and if
// present does a little decompilation to find the function's actual starting
// address.
const void* MaybeFixupFunctionAddressForILT(const void* function_address) {
#if defined(_WIN64)
  const unsigned char* opcode =
      reinterpret_cast<const unsigned char*>(function_address);
  if (*opcode == 0xe9) {
    // This is a relative jump instruction. Assume we're in the ILT and compute
    // the function start address from the instruction offset.
    const int32_t* offset = reinterpret_cast<const int32_t*>(opcode + 1);
    const unsigned char* next_instruction =
        reinterpret_cast<const unsigned char*>(offset + 1);
    return next_instruction + *offset;
  }
#endif
  return function_address;
}

// Searches through the frames in |sample|, returning an iterator to the first
// frame that has an instruction pointer within |target_function|. Returns
// sample.end() if no such frames are found.
Frames::const_iterator FindFirstFrameWithinFunction(
    const Frames& frames,
    TargetFunction target_function) {
  uintptr_t function_start =
      reinterpret_cast<uintptr_t>(MaybeFixupFunctionAddressForILT(
          reinterpret_cast<const void*>(target_function)));
  uintptr_t function_end =
      reinterpret_cast<uintptr_t>(target_function(nullptr, nullptr, nullptr));
  for (auto it = frames.begin(); it != frames.end(); ++it) {
    if (it->instruction_pointer >= function_start &&
        it->instruction_pointer <= function_end) {
      return it;
    }
  }
  return frames.end();
}

// Formats a sample into a string that can be output for test diagnostics.
std::string FormatSampleForDiagnosticOutput(const Frames& frames) {
  std::string output;
  for (const auto& frame : frames) {
    output += StringPrintf(
        "0x%p %s\n", reinterpret_cast<const void*>(frame.instruction_pointer),
        frame.module.filename.AsUTF8Unsafe().c_str());
  }
  return output;
}

// Returns a duration that is longer than the test timeout. We would use
// TimeDelta::Max() but https://crbug.com/465948.
TimeDelta AVeryLongTimeDelta() {
  return TimeDelta::FromDays(1);
}

// Tests the scenario where the library is unloaded after copying the stack, but
// before walking it. If |wait_until_unloaded| is true, ensures that the
// asynchronous library loading has completed before walking the stack. If
// false, the unloading may still be occurring during the stack walk.
void TestLibraryUnload(bool wait_until_unloaded) {
  // Test delegate that supports intervening between the copying of the stack
  // and the walking of the stack.
  class StackCopiedSignaler : public NativeStackSamplerTestDelegate {
   public:
    StackCopiedSignaler(WaitableEvent* stack_copied,
                        WaitableEvent* start_stack_walk,
                        bool wait_to_walk_stack)
        : stack_copied_(stack_copied),
          start_stack_walk_(start_stack_walk),
          wait_to_walk_stack_(wait_to_walk_stack) {}

    void OnPreStackWalk() override {
      stack_copied_->Signal();
      if (wait_to_walk_stack_)
        start_stack_walk_->Wait();
    }

   private:
    WaitableEvent* const stack_copied_;
    WaitableEvent* const start_stack_walk_;
    const bool wait_to_walk_stack_;
  };

  SamplingParams params;
  params.sampling_interval = TimeDelta::FromMilliseconds(0);
  params.samples_per_profile = 1;

  NativeLibrary other_library = LoadOtherLibrary();
  TargetThread target_thread(StackConfiguration(
      StackConfiguration::WITH_OTHER_LIBRARY, other_library));

  PlatformThreadHandle target_thread_handle;
  EXPECT_TRUE(PlatformThread::Create(0, &target_thread, &target_thread_handle));

  target_thread.WaitForThreadStart();

  WaitableEvent sampling_thread_completed(
      WaitableEvent::ResetPolicy::MANUAL,
      WaitableEvent::InitialState::NOT_SIGNALED);
  Profile profile;

  WaitableEvent stack_copied(WaitableEvent::ResetPolicy::MANUAL,
                             WaitableEvent::InitialState::NOT_SIGNALED);
  WaitableEvent start_stack_walk(WaitableEvent::ResetPolicy::MANUAL,
                                 WaitableEvent::InitialState::NOT_SIGNALED);
  StackCopiedSignaler test_delegate(&stack_copied, &start_stack_walk,
                                    wait_until_unloaded);
  StackSamplingProfiler profiler(
      target_thread.id(), params,
      std::make_unique<TestProfileBuilder>(BindLambdaForTesting(
          [&profile, &sampling_thread_completed](Profile result_profile) {
            profile = std::move(result_profile);
            sampling_thread_completed.Signal();
          })),
      &test_delegate);

  profiler.Start();

  // Wait for the stack to be copied and the target thread to be resumed.
  stack_copied.Wait();

  // Cause the target thread to finish, so that it's no longer executing code in
  // the library we're about to unload.
  target_thread.SignalThreadToFinish();
  PlatformThread::Join(target_thread_handle);

  // Unload the library now that it's not being used.
  if (wait_until_unloaded)
    SynchronousUnloadNativeLibrary(other_library);
  else
    UnloadNativeLibrary(other_library);

  // Let the stack walk commence after unloading the library, if we're waiting
  // on that event.
  start_stack_walk.Signal();

  // Wait for the sampling thread to complete and fill out |profile|.
  sampling_thread_completed.Wait();

  // Look up the frames.
  ASSERT_EQ(1u, profile.frame_sets.size());
  const Frames& frames = profile.frame_sets[0];

  // Check that the stack contains a frame for
  // TargetThread::SignalAndWaitUntilSignaled().
  auto end_frame = FindFirstFrameWithinFunction(
      frames, &TargetThread::SignalAndWaitUntilSignaled);
  ASSERT_TRUE(end_frame != frames.end())
      << "Function at "
      << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>(
             &TargetThread::SignalAndWaitUntilSignaled))
      << " was not found in stack:\n"
      << FormatSampleForDiagnosticOutput(frames);

  if (wait_until_unloaded) {
    // The stack should look like this, resulting one frame after
    // SignalAndWaitUntilSignaled. The frame in the now-unloaded library is
    // not recorded since we can't get module information.
    //
    // ... WaitableEvent and system frames ...
    // TargetThread::SignalAndWaitUntilSignaled
    // TargetThread::OtherLibraryCallback
    EXPECT_EQ(2, frames.end() - end_frame)
        << "Stack:\n"
        << FormatSampleForDiagnosticOutput(frames);
  } else {
    // We didn't wait for the asynchronous unloading to complete, so the results
    // are non-deterministic: if the library finished unloading we should have
    // the same stack as |wait_until_unloaded|, if not we should have the full
    // stack. The important thing is that we should not crash.

    if (frames.end() - end_frame == 2) {
      // This is the same case as |wait_until_unloaded|.
      return;
    }

    // Check that the stack contains a frame for
    // TargetThread::CallThroughOtherLibrary().
    auto other_library_frame = FindFirstFrameWithinFunction(
        frames, &TargetThread::CallThroughOtherLibrary);
    ASSERT_TRUE(other_library_frame != frames.end())
        << "Function at "
        << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>(
               &TargetThread::CallThroughOtherLibrary))
        << " was not found in stack:\n"
        << FormatSampleForDiagnosticOutput(frames);

    // The stack should look like this, resulting in three frames between
    // SignalAndWaitUntilSignaled and CallThroughOtherLibrary:
    //
    // ... WaitableEvent and system frames ...
    // TargetThread::SignalAndWaitUntilSignaled
    // TargetThread::OtherLibraryCallback
    // InvokeCallbackFunction (in other library)
    // TargetThread::CallThroughOtherLibrary
    EXPECT_EQ(3, other_library_frame - end_frame)
        << "Stack:\n"
        << FormatSampleForDiagnosticOutput(frames);
  }
}

// Provide a suitable (and clean) environment for the tests below. All tests
// must use this class to ensure that proper clean-up is done and thus be
// usable in a later test.
class StackSamplingProfilerTest : public testing::Test {
 public:
  void SetUp() override {
    // The idle-shutdown time is too long for convenient (and accurate) testing.
    // That behavior is checked instead by artificially triggering it through
    // the TestPeer.
    StackSamplingProfiler::TestPeer::DisableIdleShutdown();
  }

  void TearDown() override {
    // Be a good citizen and clean up after ourselves. This also re-enables the
    // idle-shutdown behavior.
    StackSamplingProfiler::TestPeer::Reset();
  }
};

}  // namespace

// Checks that the basic expected information is present in sampled frames.
//
// macOS ASAN is not yet supported - crbug.com/718628.
#if !(defined(ADDRESS_SANITIZER) && defined(OS_MACOSX))
#define MAYBE_Basic Basic
#else
#define MAYBE_Basic DISABLED_Basic
#endif
PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_Basic) {
  SamplingParams params;
  params.sampling_interval = TimeDelta::FromMilliseconds(0);
  params.samples_per_profile = 1;

  FrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());

  // Check that the size of the frame sets are correct.
  ASSERT_EQ(1u, frame_sets.size());
  const Frames& frames = frame_sets[0];

  // Check that all the modules are valid.
  for (const auto& frame : frames)
    EXPECT_TRUE(frame.module.is_valid);

  // Check that the stack contains a frame for
  // TargetThread::SignalAndWaitUntilSignaled().
  auto loc = FindFirstFrameWithinFunction(
      frames, &TargetThread::SignalAndWaitUntilSignaled);
  ASSERT_TRUE(loc != frames.end())
      << "Function at "
      << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>(
             &TargetThread::SignalAndWaitUntilSignaled))
      << " was not found in stack:\n"
      << FormatSampleForDiagnosticOutput(frames);
}

// Checks that the profiler handles stacks containing dynamically-allocated
// stack memory.
// macOS ASAN is not yet supported - crbug.com/718628.
#if !(defined(ADDRESS_SANITIZER) && defined(OS_MACOSX))
#define MAYBE_Alloca Alloca
#else
#define MAYBE_Alloca DISABLED_Alloca
#endif
PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_Alloca) {
  SamplingParams params;
  params.sampling_interval = TimeDelta::FromMilliseconds(0);
  params.samples_per_profile = 1;

  Profile profile;
  WithTargetThread(
      [&params, &profile](PlatformThreadId target_thread_id) {
        WaitableEvent sampling_thread_completed(
            WaitableEvent::ResetPolicy::MANUAL,
            WaitableEvent::InitialState::NOT_SIGNALED);
        StackSamplingProfiler profiler(
            target_thread_id, params,
            std::make_unique<TestProfileBuilder>(BindLambdaForTesting(
                [&profile, &sampling_thread_completed](Profile result_profile) {
                  profile = std::move(result_profile);
                  sampling_thread_completed.Signal();
                })));
        profiler.Start();
        sampling_thread_completed.Wait();
      },
      StackConfiguration(StackConfiguration::WITH_ALLOCA));

  // Look up the frames.
  ASSERT_EQ(1u, profile.frame_sets.size());
  const Frames& frames = profile.frame_sets[0];

  // Check that the stack contains a frame for
  // TargetThread::SignalAndWaitUntilSignaled().
  auto end_frame = FindFirstFrameWithinFunction(
      frames, &TargetThread::SignalAndWaitUntilSignaled);
  ASSERT_TRUE(end_frame != frames.end())
      << "Function at "
      << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>(
             &TargetThread::SignalAndWaitUntilSignaled))
      << " was not found in stack:\n"
      << FormatSampleForDiagnosticOutput(frames);

  // Check that the stack contains a frame for TargetThread::CallWithAlloca().
  auto alloca_frame =
      FindFirstFrameWithinFunction(frames, &TargetThread::CallWithAlloca);
  ASSERT_TRUE(alloca_frame != frames.end())
      << "Function at "
      << MaybeFixupFunctionAddressForILT(
             reinterpret_cast<const void*>(&TargetThread::CallWithAlloca))
      << " was not found in stack:\n"
      << FormatSampleForDiagnosticOutput(frames);

  // These frames should be adjacent on the stack.
  EXPECT_EQ(1, alloca_frame - end_frame)
      << "Stack:\n"
      << FormatSampleForDiagnosticOutput(frames);
}

// Checks that a profiler can stop/destruct without ever having started.
PROFILER_TEST_F(StackSamplingProfilerTest, StopWithoutStarting) {
  WithTargetThread([](PlatformThreadId target_thread_id) {
    SamplingParams params;
    params.sampling_interval = TimeDelta::FromMilliseconds(0);
    params.samples_per_profile = 1;

    Profile profile;
    WaitableEvent sampling_completed(WaitableEvent::ResetPolicy::MANUAL,
                                     WaitableEvent::InitialState::NOT_SIGNALED);

    StackSamplingProfiler profiler(
        target_thread_id, params,
        std::make_unique<TestProfileBuilder>(BindLambdaForTesting(
            [&profile, &sampling_completed](Profile result_profile) {
              profile = std::move(result_profile);
              sampling_completed.Signal();
            })));

    profiler.Stop();  // Constructed but never started.
    EXPECT_FALSE(sampling_completed.IsSignaled());
  });
}

// Checks that its okay to stop a profiler before it finishes even when the
// sampling thread continues to run.
PROFILER_TEST_F(StackSamplingProfilerTest, StopSafely) {
  // Test delegate that counts samples.
  class SampleRecordedCounter : public NativeStackSamplerTestDelegate {
   public:
    SampleRecordedCounter() = default;

    void OnPreStackWalk() override {
      AutoLock lock(lock_);
      ++count_;
    }

    size_t Get() {
      AutoLock lock(lock_);
      return count_;
    }

   private:
    Lock lock_;
    size_t count_ = 0;
  };

  WithTargetThread([](PlatformThreadId target_thread_id) {
    SamplingParams params[2];

    // Providing an initial delay makes it more likely that both will be
    // scheduled before either starts to run. Once started, samples will
    // run ordered by their scheduled, interleaved times regardless of
    // whatever interval the thread wakes up.
    params[0].initial_delay = TimeDelta::FromMilliseconds(10);
    params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
    params[0].samples_per_profile = 100000;

    params[1].initial_delay = TimeDelta::FromMilliseconds(10);
    params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
    params[1].samples_per_profile = 100000;

    SampleRecordedCounter samples_recorded[size(params)];

    TestProfilerInfo profiler_info0(target_thread_id, params[0],
                                    &samples_recorded[0]);
    TestProfilerInfo profiler_info1(target_thread_id, params[1],
                                    &samples_recorded[1]);

    profiler_info0.profiler.Start();
    profiler_info1.profiler.Start();

    // Wait for both to start accumulating samples. Using a WaitableEvent is
    // possible but gets complicated later on because there's no way of knowing
    // if 0 or 1 additional sample will be taken after Stop() and thus no way
    // of knowing how many Wait() calls to make on it.
    while (samples_recorded[0].Get() == 0 || samples_recorded[1].Get() == 0)
      PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));

    // Ensure that the first sampler can be safely stopped while the second
    // continues to run. The stopped first profiler will still have a
    // RecordSampleTask pending that will do nothing when executed because the
    // collection will have been removed by Stop().
    profiler_info0.profiler.Stop();
    profiler_info0.completed.Wait();
    size_t count0 = samples_recorded[0].Get();
    size_t count1 = samples_recorded[1].Get();

    // Waiting for the second sampler to collect a couple samples ensures that
    // the pending RecordSampleTask for the first has executed because tasks are
    // always ordered by their next scheduled time.
    while (samples_recorded[1].Get() < count1 + 2)
      PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));

    // Ensure that the first profiler didn't do anything since it was stopped.
    EXPECT_EQ(count0, samples_recorded[0].Get());
  });
}

// Checks that no frames are captured if the profiling is stopped during the
// initial delay.
PROFILER_TEST_F(StackSamplingProfilerTest, StopDuringInitialDelay) {
  SamplingParams params;
  params.initial_delay = TimeDelta::FromSeconds(60);

  FrameSets frame_sets =
      CaptureFrameSets(params, TimeDelta::FromMilliseconds(0));

  EXPECT_TRUE(frame_sets.empty());
}

// Checks that tasks can be stopped before completion and incomplete frames are
// captured.
PROFILER_TEST_F(StackSamplingProfilerTest, StopDuringInterSampleInterval) {
  // Test delegate that counts samples.
  class SampleRecordedEvent : public NativeStackSamplerTestDelegate {
   public:
    SampleRecordedEvent()
        : sample_recorded_(WaitableEvent::ResetPolicy::MANUAL,
                           WaitableEvent::InitialState::NOT_SIGNALED) {}

    void OnPreStackWalk() override { sample_recorded_.Signal(); }

    void WaitForSample() { sample_recorded_.Wait(); }

   private:
    WaitableEvent sample_recorded_;
  };

  WithTargetThread([](PlatformThreadId target_thread_id) {
    SamplingParams params;

    params.sampling_interval = AVeryLongTimeDelta();
    params.samples_per_profile = 2;

    SampleRecordedEvent samples_recorded;
    TestProfilerInfo profiler_info(target_thread_id, params, &samples_recorded);

    profiler_info.profiler.Start();

    // Wait for profiler to start accumulating samples.
    samples_recorded.WaitForSample();

    // Ensure that it can stop safely.
    profiler_info.profiler.Stop();
    profiler_info.completed.Wait();

    EXPECT_EQ(1u, profiler_info.profile.frame_sets.size());
  });
}

// Checks that we can destroy the profiler while profiling.
PROFILER_TEST_F(StackSamplingProfilerTest, DestroyProfilerWhileProfiling) {
  SamplingParams params;
  params.sampling_interval = TimeDelta::FromMilliseconds(10);

  Profile profile;
  WithTargetThread([&params, &profile](PlatformThreadId target_thread_id) {
    std::unique_ptr<StackSamplingProfiler> profiler;
    auto profile_builder = std::make_unique<TestProfileBuilder>(
        BindLambdaForTesting([&profile](Profile result_profile) {
          profile = std::move(result_profile);
        }));
    profiler.reset(new StackSamplingProfiler(target_thread_id, params,
                                             std::move(profile_builder)));
    profiler->Start();
    profiler.reset();

    // Wait longer than a sample interval to catch any use-after-free actions by
    // the profiler thread.
    PlatformThread::Sleep(TimeDelta::FromMilliseconds(50));
  });
}

// Checks that the different profilers may be run.
PROFILER_TEST_F(StackSamplingProfilerTest, CanRunMultipleProfilers) {
  SamplingParams params;
  params.sampling_interval = TimeDelta::FromMilliseconds(0);
  params.samples_per_profile = 1;

  FrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
  ASSERT_EQ(1u, frame_sets.size());

  frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
  ASSERT_EQ(1u, frame_sets.size());
}

// Checks that a sampler can be started while another is running.
PROFILER_TEST_F(StackSamplingProfilerTest, MultipleStart) {
  WithTargetThread([](PlatformThreadId target_thread_id) {
    std::vector<SamplingParams> params(2);

    params[0].initial_delay = AVeryLongTimeDelta();
    params[0].samples_per_profile = 1;

    params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
    params[1].samples_per_profile = 1;

    std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos =
        CreateProfilers(target_thread_id, params);

    profiler_infos[0]->profiler.Start();
    profiler_infos[1]->profiler.Start();
    profiler_infos[1]->completed.Wait();
    EXPECT_EQ(1u, profiler_infos[1]->profile.frame_sets.size());
  });
}

// Checks that the profile duration and the sampling interval are calculated
// correctly. Also checks that RecordAnnotations() is invoked each time a sample
// is recorded.
PROFILER_TEST_F(StackSamplingProfilerTest, ProfileGeneralInfo) {
  WithTargetThread([](PlatformThreadId target_thread_id) {
    SamplingParams params;
    params.sampling_interval = TimeDelta::FromMilliseconds(1);
    params.samples_per_profile = 3;

    TestProfilerInfo profiler_info(target_thread_id, params);

    profiler_info.profiler.Start();
    profiler_info.completed.Wait();
    EXPECT_EQ(3u, profiler_info.profile.frame_sets.size());

    // The profile duration should be greater than the total sampling intervals.
    EXPECT_GT(profiler_info.profile.profile_duration,
              profiler_info.profile.sampling_period * 3);

    EXPECT_EQ(TimeDelta::FromMilliseconds(1),
              profiler_info.profile.sampling_period);

    // The number of invocations of RecordAnnotations() should be equal to the
    // number of samples recorded.
    EXPECT_EQ(3, profiler_info.profile.annotation_count);
  });
}

// Checks that the sampling thread can shut down.
PROFILER_TEST_F(StackSamplingProfilerTest, SamplerIdleShutdown) {
  SamplingParams params;
  params.sampling_interval = TimeDelta::FromMilliseconds(0);
  params.samples_per_profile = 1;

  FrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
  ASSERT_EQ(1u, frame_sets.size());

  // Capture thread should still be running at this point.
  ASSERT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());

  // Initiate an "idle" shutdown and ensure it happens. Idle-shutdown was
  // disabled by the test fixture so the test will fail due to a timeout if
  // it does not exit.
  StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(false);

  // While the shutdown has been initiated, the actual exit of the thread still
  // happens asynchronously. Watch until the thread actually exits. This test
  // will time-out in the case of failure.
  while (StackSamplingProfiler::TestPeer::IsSamplingThreadRunning())
    PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
}

// Checks that additional requests will restart a stopped profiler.
PROFILER_TEST_F(StackSamplingProfilerTest,
                WillRestartSamplerAfterIdleShutdown) {
  SamplingParams params;
  params.sampling_interval = TimeDelta::FromMilliseconds(0);
  params.samples_per_profile = 1;

  FrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
  ASSERT_EQ(1u, frame_sets.size());

  // Capture thread should still be running at this point.
  ASSERT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());

  // Post a ShutdownTask on the sampling thread which, when executed, will
  // mark the thread as EXITING and begin shut down of the thread.
  StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(false);

  // Ensure another capture will start the sampling thread and run.
  frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
  ASSERT_EQ(1u, frame_sets.size());
  EXPECT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
}

// Checks that it's safe to stop a task after it's completed and the sampling
// thread has shut-down for being idle.
PROFILER_TEST_F(StackSamplingProfilerTest, StopAfterIdleShutdown) {
  WithTargetThread([](PlatformThreadId target_thread_id) {
    SamplingParams params;

    params.sampling_interval = TimeDelta::FromMilliseconds(1);
    params.samples_per_profile = 1;

    TestProfilerInfo profiler_info(target_thread_id, params);

    profiler_info.profiler.Start();
    profiler_info.completed.Wait();

    // Capture thread should still be running at this point.
    ASSERT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());

    // Perform an idle shutdown.
    StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(false);

    // Stop should be safe though its impossible to know at this moment if the
    // sampling thread has completely exited or will just "stop soon".
    profiler_info.profiler.Stop();
  });
}

// Checks that profilers can run both before and after the sampling thread has
// started.
PROFILER_TEST_F(StackSamplingProfilerTest,
                ProfileBeforeAndAfterSamplingThreadRunning) {
  WithTargetThread([](PlatformThreadId target_thread_id) {
    std::vector<SamplingParams> params(2);

    params[0].initial_delay = AVeryLongTimeDelta();
    params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
    params[0].samples_per_profile = 1;

    params[1].initial_delay = TimeDelta::FromMilliseconds(0);
    params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
    params[1].samples_per_profile = 1;

    std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos =
        CreateProfilers(target_thread_id, params);

    // First profiler is started when there has never been a sampling thread.
    EXPECT_FALSE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
    profiler_infos[0]->profiler.Start();
    // Second profiler is started when sampling thread is already running.
    EXPECT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
    profiler_infos[1]->profiler.Start();

    // Only the second profiler should finish before test times out.
    size_t completed_profiler = WaitForSamplingComplete(profiler_infos);
    EXPECT_EQ(1U, completed_profiler);
  });
}

// Checks that an idle-shutdown task will abort if a new profiler starts
// between when it was posted and when it runs.
PROFILER_TEST_F(StackSamplingProfilerTest, IdleShutdownAbort) {
  WithTargetThread([](PlatformThreadId target_thread_id) {
    SamplingParams params;

    params.sampling_interval = TimeDelta::FromMilliseconds(1);
    params.samples_per_profile = 1;

    TestProfilerInfo profiler_info(target_thread_id, params);

    profiler_info.profiler.Start();
    profiler_info.completed.Wait();
    EXPECT_EQ(1u, profiler_info.profile.frame_sets.size());

    // Perform an idle shutdown but simulate that a new capture is started
    // before it can actually run.
    StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(true);

    // Though the shutdown-task has been executed, any actual exit of the
    // thread is asynchronous so there is no way to detect that *didn't* exit
    // except to wait a reasonable amount of time and then check. Since the
    // thread was just running ("perform" blocked until it was), it should
    // finish almost immediately and without any waiting for tasks or events.
    PlatformThread::Sleep(TimeDelta::FromMilliseconds(200));
    EXPECT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());

    // Ensure that it's still possible to run another sampler.
    TestProfilerInfo another_info(target_thread_id, params);
    another_info.profiler.Start();
    another_info.completed.Wait();
    EXPECT_EQ(1u, another_info.profile.frame_sets.size());
  });
}

// Checks that synchronized multiple sampling requests execute in parallel.
PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_InSync) {
  WithTargetThread([](PlatformThreadId target_thread_id) {
    std::vector<SamplingParams> params(2);

    // Providing an initial delay makes it more likely that both will be
    // scheduled before either starts to run. Once started, samples will
    // run ordered by their scheduled, interleaved times regardless of
    // whatever interval the thread wakes up. Thus, total execution time
    // will be 10ms (delay) + 10x1ms (sampling) + 1/2 timer minimum interval.
    params[0].initial_delay = TimeDelta::FromMilliseconds(10);
    params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
    params[0].samples_per_profile = 9;

    params[1].initial_delay = TimeDelta::FromMilliseconds(11);
    params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
    params[1].samples_per_profile = 8;

    std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos =
        CreateProfilers(target_thread_id, params);

    profiler_infos[0]->profiler.Start();
    profiler_infos[1]->profiler.Start();

    // Wait for one profiler to finish.
    size_t completed_profiler = WaitForSamplingComplete(profiler_infos);

    size_t other_profiler = 1 - completed_profiler;
    // Wait for the other profiler to finish.
    profiler_infos[other_profiler]->completed.Wait();

    // Ensure each got the correct number of frame sets.
    EXPECT_EQ(9u, profiler_infos[0]->profile.frame_sets.size());
    EXPECT_EQ(8u, profiler_infos[1]->profile.frame_sets.size());
  });
}

// Checks that several mixed sampling requests execute in parallel.
PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_Mixed) {
  WithTargetThread([](PlatformThreadId target_thread_id) {
    std::vector<SamplingParams> params(3);

    params[0].initial_delay = TimeDelta::FromMilliseconds(8);
    params[0].sampling_interval = TimeDelta::FromMilliseconds(4);
    params[0].samples_per_profile = 10;

    params[1].initial_delay = TimeDelta::FromMilliseconds(9);
    params[1].sampling_interval = TimeDelta::FromMilliseconds(3);
    params[1].samples_per_profile = 10;

    params[2].initial_delay = TimeDelta::FromMilliseconds(10);
    params[2].sampling_interval = TimeDelta::FromMilliseconds(2);
    params[2].samples_per_profile = 10;

    std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos =
        CreateProfilers(target_thread_id, params);

    for (size_t i = 0; i < profiler_infos.size(); ++i)
      profiler_infos[i]->profiler.Start();

    // Wait for one profiler to finish.
    size_t completed_profiler = WaitForSamplingComplete(profiler_infos);
    EXPECT_EQ(10u,
              profiler_infos[completed_profiler]->profile.frame_sets.size());
    // Stop and destroy all profilers, always in the same order. Don't crash.
    for (size_t i = 0; i < profiler_infos.size(); ++i)
      profiler_infos[i]->profiler.Stop();
    for (size_t i = 0; i < profiler_infos.size(); ++i)
      profiler_infos[i].reset();
  });
}

// Checks that a stack that runs through another library produces a stack with
// the expected functions.
// macOS ASAN is not yet supported - crbug.com/718628.
#if !(defined(ADDRESS_SANITIZER) && defined(OS_MACOSX))
#define MAYBE_OtherLibrary OtherLibrary
#else
#define MAYBE_OtherLibrary DISABLED_OtherLibrary
#endif
PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_OtherLibrary) {
  SamplingParams params;
  params.sampling_interval = TimeDelta::FromMilliseconds(0);
  params.samples_per_profile = 1;

  Profile profile;
  {
    ScopedNativeLibrary other_library(LoadOtherLibrary());
    WithTargetThread(
        [&params, &profile](PlatformThreadId target_thread_id) {
          WaitableEvent sampling_thread_completed(
              WaitableEvent::ResetPolicy::MANUAL,
              WaitableEvent::InitialState::NOT_SIGNALED);
          StackSamplingProfiler profiler(
              target_thread_id, params,
              std::make_unique<TestProfileBuilder>(
                  BindLambdaForTesting([&profile, &sampling_thread_completed](
                                           Profile result_profile) {
                    profile = std::move(result_profile);
                    sampling_thread_completed.Signal();
                  })));
          profiler.Start();
          sampling_thread_completed.Wait();
        },
        StackConfiguration(StackConfiguration::WITH_OTHER_LIBRARY,
                           other_library.get()));
  }

  // Look up the frames.
  ASSERT_EQ(1u, profile.frame_sets.size());
  const Frames& frames = profile.frame_sets[0];

  // Check that the stack contains a frame for
  // TargetThread::CallThroughOtherLibrary().
  auto other_library_frame = FindFirstFrameWithinFunction(
      frames, &TargetThread::CallThroughOtherLibrary);
  ASSERT_TRUE(other_library_frame != frames.end())
      << "Function at "
      << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>(
             &TargetThread::CallThroughOtherLibrary))
      << " was not found in stack:\n"
      << FormatSampleForDiagnosticOutput(frames);

  // Check that the stack contains a frame for
  // TargetThread::SignalAndWaitUntilSignaled().
  auto end_frame = FindFirstFrameWithinFunction(
      frames, &TargetThread::SignalAndWaitUntilSignaled);
  ASSERT_TRUE(end_frame != frames.end())
      << "Function at "
      << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>(
             &TargetThread::SignalAndWaitUntilSignaled))
      << " was not found in stack:\n"
      << FormatSampleForDiagnosticOutput(frames);

  // The stack should look like this, resulting in three frames between
  // SignalAndWaitUntilSignaled and CallThroughOtherLibrary:
  //
  // ... WaitableEvent and system frames ...
  // TargetThread::SignalAndWaitUntilSignaled
  // TargetThread::OtherLibraryCallback
  // InvokeCallbackFunction (in other library)
  // TargetThread::CallThroughOtherLibrary
  EXPECT_EQ(3, other_library_frame - end_frame)
      << "Stack:\n"
      << FormatSampleForDiagnosticOutput(frames);
}

// Checks that a stack that runs through a library that is unloading produces a
// stack, and doesn't crash.
// Unloading is synchronous on the Mac, so this test is inapplicable.
#if !defined(OS_MACOSX)
#define MAYBE_UnloadingLibrary UnloadingLibrary
#else
#define MAYBE_UnloadingLibrary DISABLED_UnloadingLibrary
#endif
PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_UnloadingLibrary) {
  TestLibraryUnload(false);
}

// Checks that a stack that runs through a library that has been unloaded
// produces a stack, and doesn't crash.
// macOS ASAN is not yet supported - crbug.com/718628.
#if !(defined(ADDRESS_SANITIZER) && defined(OS_MACOSX))
#define MAYBE_UnloadedLibrary UnloadedLibrary
#else
#define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary
#endif
PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) {
  TestLibraryUnload(true);
}

// Checks that different threads can be sampled in parallel.
PROFILER_TEST_F(StackSamplingProfilerTest, MultipleSampledThreads) {
  // Create target threads. The extra parethesis around the StackConfiguration
  // call are to avoid the most-vexing-parse problem.
  TargetThread target_thread1((StackConfiguration(StackConfiguration::NORMAL)));
  TargetThread target_thread2((StackConfiguration(StackConfiguration::NORMAL)));
  PlatformThreadHandle target_thread_handle1, target_thread_handle2;
  EXPECT_TRUE(
      PlatformThread::Create(0, &target_thread1, &target_thread_handle1));
  EXPECT_TRUE(
      PlatformThread::Create(0, &target_thread2, &target_thread_handle2));
  target_thread1.WaitForThreadStart();
  target_thread2.WaitForThreadStart();

  // Providing an initial delay makes it more likely that both will be
  // scheduled before either starts to run. Once started, samples will
  // run ordered by their scheduled, interleaved times regardless of
  // whatever interval the thread wakes up.
  SamplingParams params1, params2;
  params1.initial_delay = TimeDelta::FromMilliseconds(10);
  params1.sampling_interval = TimeDelta::FromMilliseconds(1);
  params1.samples_per_profile = 9;
  params2.initial_delay = TimeDelta::FromMilliseconds(10);
  params2.sampling_interval = TimeDelta::FromMilliseconds(1);
  params2.samples_per_profile = 8;

  Profile profile1, profile2;

  WaitableEvent sampling_thread_completed1(
      WaitableEvent::ResetPolicy::MANUAL,
      WaitableEvent::InitialState::NOT_SIGNALED);
  StackSamplingProfiler profiler1(
      target_thread1.id(), params1,
      std::make_unique<TestProfileBuilder>(BindLambdaForTesting(
          [&profile1, &sampling_thread_completed1](Profile result_profile) {
            profile1 = std::move(result_profile);
            sampling_thread_completed1.Signal();
          })));

  WaitableEvent sampling_thread_completed2(
      WaitableEvent::ResetPolicy::MANUAL,
      WaitableEvent::InitialState::NOT_SIGNALED);
  StackSamplingProfiler profiler2(
      target_thread2.id(), params2,
      std::make_unique<TestProfileBuilder>(BindLambdaForTesting(
          [&profile2, &sampling_thread_completed2](Profile result_profile) {
            profile2 = std::move(result_profile);
            sampling_thread_completed2.Signal();
          })));

  // Finally the real work.
  profiler1.Start();
  profiler2.Start();
  sampling_thread_completed1.Wait();
  sampling_thread_completed2.Wait();
  EXPECT_EQ(9u, profile1.frame_sets.size());
  EXPECT_EQ(8u, profile2.frame_sets.size());

  target_thread1.SignalThreadToFinish();
  target_thread2.SignalThreadToFinish();
  PlatformThread::Join(target_thread_handle1);
  PlatformThread::Join(target_thread_handle2);
}

// A simple thread that runs a profiler on another thread.
class ProfilerThread : public SimpleThread {
 public:
  ProfilerThread(const std::string& name,
                 PlatformThreadId thread_id,
                 const SamplingParams& params)
      : SimpleThread(name, Options()),
        run_(WaitableEvent::ResetPolicy::MANUAL,
             WaitableEvent::InitialState::NOT_SIGNALED),
        completed_(WaitableEvent::ResetPolicy::MANUAL,
                   WaitableEvent::InitialState::NOT_SIGNALED),
        profiler_(thread_id,
                  params,
                  std::make_unique<TestProfileBuilder>(
                      BindLambdaForTesting([this](Profile result_profile) {
                        profile_ = std::move(result_profile);
                        completed_.Signal();
                      }))) {}

  void Run() override {
    run_.Wait();
    profiler_.Start();
  }

  void Go() { run_.Signal(); }

  void Wait() { completed_.Wait(); }

  Profile& profile() { return profile_; }

 private:
  WaitableEvent run_;

  Profile profile_;
  WaitableEvent completed_;
  StackSamplingProfiler profiler_;
};

// Checks that different threads can run samplers in parallel.
PROFILER_TEST_F(StackSamplingProfilerTest, MultipleProfilerThreads) {
  WithTargetThread([](PlatformThreadId target_thread_id) {
    // Providing an initial delay makes it more likely that both will be
    // scheduled before either starts to run. Once started, samples will
    // run ordered by their scheduled, interleaved times regardless of
    // whatever interval the thread wakes up.
    SamplingParams params1, params2;
    params1.initial_delay = TimeDelta::FromMilliseconds(10);
    params1.sampling_interval = TimeDelta::FromMilliseconds(1);
    params1.samples_per_profile = 9;
    params2.initial_delay = TimeDelta::FromMilliseconds(10);
    params2.sampling_interval = TimeDelta::FromMilliseconds(1);
    params2.samples_per_profile = 8;

    // Start the profiler threads and give them a moment to get going.
    ProfilerThread profiler_thread1("profiler1", target_thread_id, params1);
    ProfilerThread profiler_thread2("profiler2", target_thread_id, params2);
    profiler_thread1.Start();
    profiler_thread2.Start();
    PlatformThread::Sleep(TimeDelta::FromMilliseconds(10));

    // This will (approximately) synchronize the two threads.
    profiler_thread1.Go();
    profiler_thread2.Go();

    // Wait for them both to finish and validate collection.
    profiler_thread1.Wait();
    profiler_thread2.Wait();
    EXPECT_EQ(9u, profiler_thread1.profile().frame_sets.size());
    EXPECT_EQ(8u, profiler_thread2.profile().frame_sets.size());

    profiler_thread1.Join();
    profiler_thread2.Join();
  });
}

}  // namespace base
