/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <atomic>
#include <string>
#include <vector>

#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/pipe.h"
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/subprocess.h"
#include "perfetto/ext/tracing/ipc/default_socket.h"
#include "perfetto/heap_profile.h"
#include "perfetto/trace_processor/trace_processor.h"
#include "protos/perfetto/trace/trace.gen.h"
#include "protos/perfetto/trace/trace.pbzero.h"
#include "src/base/test/test_task_runner.h"
#include "src/profiling/memory/heapprofd_producer.h"
#include "test/gtest_and_gmock.h"
#include "test/test_helper.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#include <sys/system_properties.h>
#endif

#include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
#include "protos/perfetto/trace/interned_data/interned_data.gen.h"
#include "protos/perfetto/trace/profiling/profile_common.gen.h"
#include "protos/perfetto/trace/profiling/profile_packet.gen.h"

namespace perfetto {
namespace profiling {
namespace {

constexpr useconds_t kMsToUs = 1000;

constexpr auto kTracingDisabledTimeoutMs = 30000;
constexpr auto kWaitForReadDataTimeoutMs = 10000;
constexpr size_t kStartupAllocSize = 10;
constexpr size_t kFirstIterationBytes = 5;
constexpr size_t kSecondIterationBytes = 7;

enum class TestMode { kCentral, kStatic };
enum class AllocatorMode { kMalloc, kCustom };

using ::testing::AllOf;
using ::testing::AnyOf;
using ::testing::Bool;
using ::testing::Contains;
using ::testing::Eq;
using ::testing::Field;
using ::testing::HasSubstr;
using ::testing::Values;

constexpr const char* kOnlyFlamegraph =
    "SELECT id, name, map_name, count, cumulative_count, size, "
    "cumulative_size, "
    "alloc_count, cumulative_alloc_count, alloc_size, cumulative_alloc_size, "
    "parent_id "
    "FROM experimental_flamegraph WHERE "
    "(ts, upid) IN (SELECT distinct ts, upid from heap_profile_allocation) AND "
    "profile_type = 'native' order by abs(cumulative_size) desc;";

struct FlamegraphNode {
  int64_t id;
  std::string name;
  std::string map_name;
  int64_t count;
  int64_t cumulative_count;
  int64_t size;
  int64_t cumulative_size;
  int64_t alloc_count;
  int64_t cumulative_alloc_count;
  int64_t alloc_size;
  int64_t cumulative_alloc_size;
  base::Optional<int64_t> parent_id;
};

std::vector<FlamegraphNode> GetFlamegraph(trace_processor::TraceProcessor* tp) {
  std::vector<FlamegraphNode> result;
  auto it = tp->ExecuteQuery(kOnlyFlamegraph);
  while (it.Next()) {
    result.push_back({
        it.Get(0).AsLong(),
        it.Get(1).AsString(),
        it.Get(2).AsString(),
        it.Get(3).AsLong(),
        it.Get(4).AsLong(),
        it.Get(5).AsLong(),
        it.Get(6).AsLong(),
        it.Get(7).AsLong(),
        it.Get(8).AsLong(),
        it.Get(9).AsLong(),
        it.Get(10).AsLong(),
        it.Get(11).is_null() ? base::nullopt
                             : base::Optional<int64_t>(it.Get(11).AsLong()),
    });
  }
  PERFETTO_CHECK(it.Status().ok());
  return result;
}

std::string AllocatorName(AllocatorMode mode) {
  switch (mode) {
    case AllocatorMode::kMalloc:
      return "libc.malloc";
    case AllocatorMode::kCustom:
      return "test";
  }
}

AllocatorMode AllocatorModeFromNameOrDie(std::string s) {
  if (s == "libc.malloc")
    return AllocatorMode::kMalloc;
  if (s == "test")
    return AllocatorMode::kCustom;
  PERFETTO_FATAL("Invalid allocator mode [malloc | test]: %s", s.c_str());
}

void ContinuousDump(HeapprofdConfig* cfg) {
  auto* cont_config = cfg->mutable_continuous_dump_config();
  cont_config->set_dump_phase_ms(0);
  cont_config->set_dump_interval_ms(100);
}

template <typename F>
TraceConfig MakeTraceConfig(F fn) {
  TraceConfig trace_config;
  trace_config.add_buffers()->set_size_kb(10 * 1024);
  trace_config.set_duration_ms(2000);
  trace_config.set_data_source_stop_timeout_ms(10000);

  auto* ds_config = trace_config.add_data_sources()->mutable_config();
  ds_config->set_name("android.heapprofd");
  ds_config->set_target_buffer(0);

  protos::gen::HeapprofdConfig heapprofd_config;
  fn(&heapprofd_config);
  ds_config->set_heapprofd_config_raw(heapprofd_config.SerializeAsString());
  return trace_config;
}

void CustomAllocateAndFree(size_t bytes) {
  static uint32_t heap_id = AHeapProfile_registerHeap(AHeapInfo_create("test"));
  AHeapProfile_reportAllocation(heap_id, 0x1234abc, bytes);
  AHeapProfile_reportFree(heap_id, 0x1234abc);
}

void SecondaryAllocAndFree(size_t bytes) {
  static uint32_t heap_id =
      AHeapProfile_registerHeap(AHeapInfo_create("secondary"));
  AHeapProfile_reportAllocation(heap_id, 0x1234abc, bytes);
  AHeapProfile_reportFree(heap_id, 0x1234abc);
}

void AllocateAndFree(size_t bytes) {
  // This volatile is needed to prevent the compiler from trying to be
  // helpful and compiling a "useless" malloc + free into a noop.
  volatile char* x = static_cast<char*>(malloc(bytes));
  if (x) {
    if (bytes > 0)
      x[0] = 'x';
    free(const_cast<char*>(x));
  }
}

void DoAllocation(AllocatorMode mode, size_t bytes) {
  switch (mode) {
    case AllocatorMode::kMalloc:
      AllocateAndFree(bytes);
      break;
    case AllocatorMode::kCustom:
      // We need to run malloc(0) even if we want to test the custom allocator,
      // as the init mechanism assumes the application uses malloc.
      AllocateAndFree(1);
      CustomAllocateAndFree(bytes);
      break;
  }
}

void ContinuousMalloc(AllocatorMode mode,
                      size_t primary_bytes,
                      size_t secondary_bytes,
                      ssize_t max_iter = -1) {
  for (ssize_t i = 0; max_iter == -1 || i < max_iter; ++i) {
    DoAllocation(mode, primary_bytes);
    if (secondary_bytes)
      SecondaryAllocAndFree(secondary_bytes);
    usleep(10 * kMsToUs);
  }
}

void StartAndWaitForHandshake(base::Subprocess* child) {
  // We cannot use base::Pipe because that assumes we want CLOEXEC.
  // We do NOT want CLOEXEC as this gets used by the RunReInit in the child.
  int ready_pipe[2];
  PERFETTO_CHECK(pipe(ready_pipe) == 0);  // NOLINT(android-cloexec-pipe)

  int ready_pipe_rd = ready_pipe[0];
  int ready_pipe_wr = ready_pipe[1];
  child->args.preserve_fds.push_back(ready_pipe_wr);
  child->args.env.push_back("HEAPPROFD_TESTING_READY_PIPE=" +
                            std::to_string(ready_pipe_wr));
  child->Start();
  close(ready_pipe_wr);
  // Wait for libc to initialize the signal handler. If we signal before the
  // handler is installed, we can kill the process.
  char buf[1];
  PERFETTO_CHECK(PERFETTO_EINTR(read(ready_pipe_rd, buf, sizeof(buf))) == 0);
  close(ready_pipe_rd);
}

void ChildFinishHandshake() {
  const char* ready_pipe = getenv("HEAPPROFD_TESTING_READY_PIPE");
  if (ready_pipe != nullptr) {
    close(static_cast<int>(base::StringToInt64(ready_pipe).value()));
  }
}

base::Subprocess ForkContinuousAlloc(AllocatorMode mode,
                                     size_t primary_bytes,
                                     size_t secondary_bytes = 0,
                                     ssize_t max_iter = -1) {
  base::Subprocess child({"/proc/self/exe"});
  child.args.posix_argv0_override_for_testing = "heapprofd_continuous_malloc";
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG0=" +
                           AllocatorName(mode));
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG1=" +
                           std::to_string(primary_bytes));
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG2=" +
                           std::to_string(secondary_bytes));
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG3=" +
                           std::to_string(max_iter));

  StartAndWaitForHandshake(&child);
  return child;
}

void __attribute__((constructor(1024))) RunContinuousMalloc() {
  const char* a0 = getenv("HEAPPROFD_TESTING_RUN_MALLOC_ARG0");
  const char* a1 = getenv("HEAPPROFD_TESTING_RUN_MALLOC_ARG1");
  const char* a2 = getenv("HEAPPROFD_TESTING_RUN_MALLOC_ARG2");
  const char* a3 = getenv("HEAPPROFD_TESTING_RUN_MALLOC_ARG3");
  if (a0 == nullptr)
    return;

  AllocatorMode arg0 = AllocatorModeFromNameOrDie(a0);
  uint32_t arg1 = a1 ? base::StringToUInt32(a1).value() : 0;
  uint32_t arg2 = a2 ? base::StringToUInt32(a2).value() : 0;
  int32_t arg3 = a3 ? base::StringToInt32(a3).value() : -1;

  ChildFinishHandshake();

  ContinuousMalloc(arg0, arg1, arg2, arg3);
  exit(0);
}

void __attribute__((constructor(1024))) RunAccurateMalloc() {
  const char* a0 = getenv("HEAPPROFD_TESTING_RUN_ACCURATE_MALLOC");
  if (a0 == nullptr)
    return;

  static std::atomic<bool> initialized{false};
  static uint32_t heap_id =
      AHeapProfile_registerHeap(AHeapInfo_setEnabledCallback(
          AHeapInfo_create("test"),
          [](void*, const AHeapProfileEnableCallbackInfo*) {
            initialized = true;
          },
          nullptr));

  ChildFinishHandshake();

  // heapprofd_client needs malloc to see the signal.
  while (!initialized)
    AllocateAndFree(1);
  // We call the callback before setting enabled=true on the heap, so we
  // wait a bit for the assignment to happen.
  usleep(100000);
  if (!AHeapProfile_reportAllocation(heap_id, 0x1, 10u))
    PERFETTO_FATAL("Expected allocation to be sampled.");
  AHeapProfile_reportFree(heap_id, 0x1);
  if (!AHeapProfile_reportAllocation(heap_id, 0x2, 15u))
    PERFETTO_FATAL("Expected allocation to be sampled.");
  if (!AHeapProfile_reportAllocation(heap_id, 0x3, 15u))
    PERFETTO_FATAL("Expected allocation to be sampled.");
  AHeapProfile_reportFree(heap_id, 0x2);

  // Wait around so we can verify it did't crash.
  for (;;) {
  }
}

void __attribute__((noreturn)) RunAccurateMallocWithVforkCommon() {
  static std::atomic<bool> initialized{false};
  static uint32_t heap_id =
      AHeapProfile_registerHeap(AHeapInfo_setEnabledCallback(
          AHeapInfo_create("test"),
          [](void*, const AHeapProfileEnableCallbackInfo*) {
            initialized = true;
          },
          nullptr));

  ChildFinishHandshake();

  // heapprofd_client needs malloc to see the signal.
  while (!initialized)
    AllocateAndFree(1);
  // We call the callback before setting enabled=true on the heap, so we
  // wait a bit for the assignment to happen.
  usleep(100000);
  if (!AHeapProfile_reportAllocation(heap_id, 0x1, 10u))
    PERFETTO_FATAL("Expected allocation to be sampled.");
  AHeapProfile_reportFree(heap_id, 0x1);
  pid_t pid = vfork();
  PERFETTO_CHECK(pid != -1);
  if (pid == 0) {
    AHeapProfile_reportAllocation(heap_id, 0x2, 15u);
    AHeapProfile_reportAllocation(heap_id, 0x3, 15u);
    exit(0);
  }
  if (!AHeapProfile_reportAllocation(heap_id, 0x2, 15u))
    PERFETTO_FATAL("Expected allocation to be sampled.");
  if (!AHeapProfile_reportAllocation(heap_id, 0x3, 15u))
    PERFETTO_FATAL("Expected allocation to be sampled.");
  AHeapProfile_reportFree(heap_id, 0x2);

  // Wait around so we can verify it did't crash.
  for (;;) {
  }
}

void __attribute__((constructor(1024))) RunAccurateSample() {
  const char* a0 = getenv("HEAPPROFD_TESTING_RUN_ACCURATE_SAMPLE");
  if (a0 == nullptr)
    return;

  static std::atomic<bool> initialized{false};
  static uint32_t heap_id =
      AHeapProfile_registerHeap(AHeapInfo_setEnabledCallback(
          AHeapInfo_create("test"),
          [](void*, const AHeapProfileEnableCallbackInfo*) {
            initialized = true;
          },
          nullptr));

  ChildFinishHandshake();

  // heapprofd_client needs malloc to see the signal.
  while (!initialized)
    AllocateAndFree(1);
  // We call the callback before setting enabled=true on the heap, so we
  // wait a bit for the assignment to happen.
  usleep(100000);
  if (!AHeapProfile_reportSample(heap_id, 0x1, 10u))
    PERFETTO_FATAL("Expected allocation to be sampled.");
  AHeapProfile_reportFree(heap_id, 0x1);
  if (!AHeapProfile_reportSample(heap_id, 0x2, 15u))
    PERFETTO_FATAL("Expected allocation to be sampled.");
  if (!AHeapProfile_reportSample(heap_id, 0x3, 15u))
    PERFETTO_FATAL("Expected allocation to be sampled.");
  AHeapProfile_reportFree(heap_id, 0x2);

  // Wait around so we can verify it did't crash.
  for (;;) {
  }
}

void __attribute__((constructor(1024))) RunAccurateMallocWithVfork() {
  const char* a0 = getenv("HEAPPROFD_TESTING_RUN_ACCURATE_MALLOC_WITH_VFORK");
  if (a0 == nullptr)
    return;
  RunAccurateMallocWithVforkCommon();
}

void __attribute__((constructor(1024))) RunAccurateMallocWithVforkThread() {
  const char* a0 =
      getenv("HEAPPROFD_TESTING_RUN_ACCURATE_MALLOC_WITH_VFORK_THREAD");
  if (a0 == nullptr)
    return;
  std::thread th(RunAccurateMallocWithVforkCommon);
  th.join();
}

void __attribute__((constructor(1024))) RunReInit() {
  const char* a0 = getenv("HEAPPROFD_TESTING_RUN_REINIT_ARG0");
  if (a0 == nullptr)
    return;

  AllocatorMode mode = AllocatorModeFromNameOrDie(a0);
  const char* a1 = getenv("HEAPPROFD_TESTING_RUN_REINIT_ARG1");
  const char* a2 = getenv("HEAPPROFD_TESTING_RUN_REINIT_ARG2");
  PERFETTO_CHECK(a1 != nullptr && a2 != nullptr);
  int signal_pipe_rd = static_cast<int>(base::StringToInt64(a1).value());
  int ack_pipe_wr = static_cast<int>(base::StringToInt64(a2).value());

  ChildFinishHandshake();

  size_t bytes = kFirstIterationBytes;
  bool signalled = false;
  for (;;) {
    DoAllocation(mode, bytes);
    char buf[1];
    if (!signalled && read(signal_pipe_rd, buf, sizeof(buf)) == 1) {
      signalled = true;
      close(signal_pipe_rd);

      // make sure the client has noticed that the session has stopped
      DoAllocation(mode, bytes);

      bytes = kSecondIterationBytes;
      PERFETTO_CHECK(PERFETTO_EINTR(write(ack_pipe_wr, "1", 1)) == 1);
      close(ack_pipe_wr);
    }
    usleep(10 * kMsToUs);
  }
  PERFETTO_FATAL("Should be unreachable");
}

void __attribute__((constructor(1024))) RunCustomLifetime() {
  const char* a0 = getenv("HEAPPROFD_TESTING_RUN_LIFETIME_ARG0");
  const char* a1 = getenv("HEAPPROFD_TESTING_RUN_LIFETIME_ARG1");
  if (a0 == nullptr)
    return;
  uint64_t arg0 = a0 ? base::StringToUInt64(a0).value() : 0;
  uint64_t arg1 = a0 ? base::StringToUInt64(a1).value() : 0;

  PERFETTO_CHECK(arg1);

  static std::atomic<bool> initialized{false};
  static std::atomic<bool> disabled{false};
  static std::atomic<uint64_t> sampling_interval;

  auto enabled_callback = [](void*,
                             const AHeapProfileEnableCallbackInfo* info) {
    sampling_interval =
        AHeapProfileEnableCallbackInfo_getSamplingInterval(info);
    initialized = true;
  };
  auto disabled_callback = [](void*, const AHeapProfileDisableCallbackInfo*) {
    disabled = true;
  };
  static uint32_t heap_id =
      AHeapProfile_registerHeap(AHeapInfo_setDisabledCallback(
          AHeapInfo_setEnabledCallback(AHeapInfo_create("test"),
                                       enabled_callback, nullptr),
          disabled_callback, nullptr));

  ChildFinishHandshake();

  // heapprofd_client needs malloc to see the signal.
  while (!initialized)
    AllocateAndFree(1);

  if (sampling_interval.load() != arg0) {
    PERFETTO_FATAL("%" PRIu64 " != %" PRIu64, sampling_interval.load(), arg0);
  }

  while (!disabled)
    AHeapProfile_reportFree(heap_id, 0x2);

  char x = 'x';
  PERFETTO_CHECK(base::WriteAll(static_cast<int>(arg1), &x, sizeof(x)) == 1);
  close(static_cast<int>(arg1));

  // Wait around so we can verify it didn't crash.
  for (;;) {
  }
}

class TraceProcessorTestHelper : public TestHelper {
 public:
  explicit TraceProcessorTestHelper(base::TestTaskRunner* task_runner)
      : TestHelper(task_runner),
        tp_(trace_processor::TraceProcessor::CreateInstance({})) {}

  void ReadTraceData(std::vector<TracePacket> packets) override {
    for (auto& packet : packets) {
      auto preamble = packet.GetProtoPreamble();
      std::string payload = packet.GetRawBytesForTesting();
      char* preamble_payload = std::get<0>(preamble);
      size_t preamble_size = std::get<1>(preamble);
      size_t buf_size = preamble_size + payload.size();
      std::unique_ptr<uint8_t[]> buf =
          std::unique_ptr<uint8_t[]>(new uint8_t[buf_size]);
      memcpy(&buf[0], preamble_payload, preamble_size);
      memcpy(&buf[preamble_size], payload.data(), payload.size());
      PERFETTO_CHECK(tp_->Parse(std::move(buf), buf_size).ok());
    }
    TestHelper::ReadTraceData(std::move(packets));
  }

  trace_processor::TraceProcessor& tp() { return *tp_; }

 private:
  std::unique_ptr<trace_processor::TraceProcessor> tp_;
};

std::unique_ptr<TraceProcessorTestHelper> GetHelper(
    base::TestTaskRunner* task_runner) {
  std::unique_ptr<TraceProcessorTestHelper> helper(
      new TraceProcessorTestHelper(task_runner));
  helper->StartServiceIfRequired();

  helper->ConnectConsumer();
  helper->WaitForConsumerConnect();
  return helper;
}

void ReadAndWait(TraceProcessorTestHelper* helper) {
  helper->WaitForTracingDisabled(kTracingDisabledTimeoutMs);
  helper->ReadData();
  helper->WaitForReadData(0, kWaitForReadDataTimeoutMs);
  helper->tp().NotifyEndOfFile();
}

std::string ToTraceString(
    const std::vector<protos::gen::TracePacket>& packets) {
  protos::gen::Trace trace;
  for (const protos::gen::TracePacket& packet : packets) {
    *trace.add_packet() = packet;
  }
  return trace.SerializeAsString();
}

#define WRITE_TRACE(trace)                 \
  do {                                     \
    WriteTrace(trace, __FILE__, __LINE__); \
  } while (0)

std::string FormatHistogram(const protos::gen::ProfilePacket_Histogram& hist) {
  std::string out;
  std::string prev_upper_limit = "-inf";
  for (const auto& bucket : hist.buckets()) {
    std::string upper_limit;
    if (bucket.max_bucket())
      upper_limit = "inf";
    else
      upper_limit = std::to_string(bucket.upper_limit());

    out += "[" + prev_upper_limit + ", " + upper_limit +
           "]: " + std::to_string(bucket.count()) + "; ";
    prev_upper_limit = std::move(upper_limit);
  }
  return out + "\n";
}

std::string FormatStats(const protos::gen::ProfilePacket_ProcessStats& stats) {
  return std::string("unwinding_errors: ") +
         std::to_string(stats.unwinding_errors()) + "\n" +
         "heap_samples: " + std::to_string(stats.heap_samples()) + "\n" +
         "map_reparses: " + std::to_string(stats.map_reparses()) + "\n" +
         "unwinding_time_us: " + FormatHistogram(stats.unwinding_time_us());
}

std::string Suffix(const std::tuple<TestMode, AllocatorMode>& param) {
  TestMode tm = std::get<0>(param);
  AllocatorMode am = std::get<1>(param);

  std::string result;
  switch (tm) {
    case TestMode::kCentral:
      result += "CentralMode";
      break;
    case TestMode::kStatic:
      result += "StaticMode";
      break;
  }
  switch (am) {
    case AllocatorMode::kMalloc:
      result += "Malloc";
      break;
    case AllocatorMode::kCustom:
      result += "Custom";
      break;
  }
  return result;
}

__attribute__((unused)) std::string TestSuffix(
    const ::testing::TestParamInfo<std::tuple<TestMode, AllocatorMode>>& info) {
  return Suffix(info.param);
}

class HeapprofdEndToEnd
    : public ::testing::TestWithParam<std::tuple<TestMode, AllocatorMode>> {
 protected:
  base::TestTaskRunner task_runner;

  TestMode test_mode() { return std::get<0>(GetParam()); }
  AllocatorMode allocator_mode() { return std::get<1>(GetParam()); }
  std::string allocator_name() { return AllocatorName(allocator_mode()); }

  void WriteTrace(const std::vector<protos::gen::TracePacket>& packets,
                  const char* filename,
                  uint64_t lineno) {
    const char* outdir = getenv("HEAPPROFD_TEST_PROFILE_OUT");
    if (!outdir)
      return;
    const std::string fq_filename =
        std::string(outdir) + "/" + basename(filename) + ":" +
        std::to_string(lineno) + "_" + Suffix(GetParam());
    base::ScopedFile fd(base::OpenFile(fq_filename, O_WRONLY | O_CREAT, 0666));
    PERFETTO_CHECK(*fd);
    std::string trace_string = ToTraceString(packets);
    PERFETTO_CHECK(
        base::WriteAll(*fd, trace_string.data(), trace_string.size()) >= 0);
  }

  std::unique_ptr<TraceProcessorTestHelper> Trace(
      const TraceConfig& trace_config) {
    auto helper = GetHelper(&task_runner);

    helper->StartTracing(trace_config);

    ReadAndWait(helper.get());
    return helper;
  }

  std::vector<std::string> GetUnwindingErrors(
      TraceProcessorTestHelper* helper) {
    std::vector<std::string> out;
    const auto& packets = helper->trace();
    for (const protos::gen::TracePacket& packet : packets) {
      for (const protos::gen::InternedString& fn :
           packet.interned_data().function_names()) {
        if (fn.str().find("ERROR ") == 0) {
          out.push_back(fn.str());
        }
      }
    }
    return out;
  }

  void PrintStats(TraceProcessorTestHelper* helper) {
    const auto& packets = helper->trace();
    for (const protos::gen::TracePacket& packet : packets) {
      for (const auto& dump : packet.profile_packet().process_dumps()) {
        // protobuf uint64 does not like the PRIu64 formatter.
        PERFETTO_LOG("Stats for %s: %s", std::to_string(dump.pid()).c_str(),
                     FormatStats(dump.stats()).c_str());
      }
    }
    std::vector<std::string> errors = GetUnwindingErrors(helper);
    for (const std::string& err : errors) {
      PERFETTO_LOG("Unwinding error: %s", err.c_str());
    }
  }

  void ValidateSampleSizes(TraceProcessorTestHelper* helper,
                           uint64_t pid,
                           uint64_t alloc_size,
                           const std::string& heap_name = "") {
    const auto& packets = helper->trace();
    for (const protos::gen::TracePacket& packet : packets) {
      for (const auto& dump : packet.profile_packet().process_dumps()) {
        if (dump.pid() != pid ||
            (!heap_name.empty() && heap_name != dump.heap_name())) {
          continue;
        }
        for (const auto& sample : dump.samples()) {
          EXPECT_EQ(sample.self_allocated() % alloc_size, 0u);
          EXPECT_EQ(sample.self_freed() % alloc_size, 0u);
          EXPECT_THAT(sample.self_allocated() - sample.self_freed(),
                      AnyOf(Eq(0u), Eq(alloc_size)));
        }
      }
    }
  }

  void ValidateFromStartup(TraceProcessorTestHelper* helper,
                           uint64_t pid,
                           bool from_startup) {
    const auto& packets = helper->trace();
    for (const protos::gen::TracePacket& packet : packets) {
      for (const auto& dump : packet.profile_packet().process_dumps()) {
        if (dump.pid() != pid)
          continue;
        EXPECT_EQ(dump.from_startup(), from_startup);
      }
    }
  }

  void ValidateRejectedConcurrent(TraceProcessorTestHelper* helper,
                                  uint64_t pid,
                                  bool rejected_concurrent) {
    const auto& packets = helper->trace();
    for (const protos::gen::TracePacket& packet : packets) {
      for (const auto& dump : packet.profile_packet().process_dumps()) {
        if (dump.pid() != pid)
          continue;
        EXPECT_EQ(dump.rejected_concurrent(), rejected_concurrent);
      }
    }
  }

  void ValidateNoSamples(TraceProcessorTestHelper* helper, uint64_t pid) {
    const auto& packets = helper->trace();
    size_t samples = 0;
    for (const protos::gen::TracePacket& packet : packets) {
      for (const auto& dump : packet.profile_packet().process_dumps()) {
        if (dump.pid() != pid)
          continue;
        samples += dump.samples().size();
      }
    }
    EXPECT_EQ(samples, 0u);
  }

  void ValidateHasSamples(TraceProcessorTestHelper* helper,
                          uint64_t pid,
                          const std::string& heap_name,
                          uint64_t sampling_interval) {
    const auto& packets = helper->trace();
    ASSERT_GT(packets.size(), 0u);
    size_t profile_packets = 0;
    size_t samples = 0;
    uint64_t last_allocated = 0;
    uint64_t last_freed = 0;
    for (const protos::gen::TracePacket& packet : packets) {
      for (const auto& dump : packet.profile_packet().process_dumps()) {
        if (dump.pid() != pid || dump.heap_name() != heap_name)
          continue;
        EXPECT_EQ(dump.sampling_interval_bytes(), sampling_interval);
        for (const auto& sample : dump.samples()) {
          last_allocated = sample.self_allocated();
          last_freed = sample.self_freed();
          samples++;
        }
        profile_packets++;
      }
    }
    EXPECT_GT(profile_packets, 0u) << heap_name;
    EXPECT_GT(samples, 0u) << heap_name;
    EXPECT_GT(last_allocated, 0u) << heap_name;
    EXPECT_GT(last_freed, 0u) << heap_name;
  }

  void ValidateOnlyPID(TraceProcessorTestHelper* helper, uint64_t pid) {
    size_t dumps = 0;
    const auto& packets = helper->trace();
    for (const protos::gen::TracePacket& packet : packets) {
      for (const auto& dump : packet.profile_packet().process_dumps()) {
        EXPECT_EQ(dump.pid(), pid);
        dumps++;
      }
    }
    EXPECT_GT(dumps, 0u);
  }
};

// This checks that the child is still running (to ensure it didn't crash
// unxpectedly) and then kills it.
void KillAssertRunning(base::Subprocess* child) {
  ASSERT_EQ(child->Poll(), base::Subprocess::kRunning)
      << "Target process not running. CHECK CRASH LOGS.";
  PERFETTO_LOG("Shutting down profile target.");
  child->KillAndWaitForTermination();
}

TEST_P(HeapprofdEndToEnd, Disabled) {
  constexpr size_t kAllocSize = 1024;

  base::Subprocess child = ForkContinuousAlloc(allocator_mode(), kAllocSize);
  const uint64_t pid = static_cast<uint64_t>(child.pid());

  TraceConfig trace_config = MakeTraceConfig([pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(1);
    cfg->add_pid(pid);
    cfg->add_heaps("invalid");
    ContinuousDump(cfg);
  });

  auto helper = Trace(trace_config);
  WRITE_TRACE(helper->full_trace());
  PrintStats(helper.get());
  KillAssertRunning(&child);

  ValidateNoSamples(helper.get(), pid);
}

TEST_P(HeapprofdEndToEnd, Smoke) {
  constexpr size_t kAllocSize = 1024;
  constexpr size_t kSamplingInterval = 1;

  base::Subprocess child = ForkContinuousAlloc(allocator_mode(), kAllocSize);
  const uint64_t pid = static_cast<uint64_t>(child.pid());

  TraceConfig trace_config = MakeTraceConfig([this, pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(kSamplingInterval);
    cfg->add_pid(pid);
    cfg->add_heaps(allocator_name());
    ContinuousDump(cfg);
  });

  auto helper = Trace(trace_config);
  WRITE_TRACE(helper->full_trace());
  PrintStats(helper.get());
  KillAssertRunning(&child);

  ValidateHasSamples(helper.get(), pid, allocator_name(), kSamplingInterval);
  ValidateOnlyPID(helper.get(), pid);
  ValidateSampleSizes(helper.get(), pid, kAllocSize);
}

TEST_P(HeapprofdEndToEnd, TwoAllocators) {
  constexpr size_t kCustomAllocSize = 1024;
  constexpr size_t kAllocSize = 7;
  constexpr size_t kSamplingInterval = 1;

  base::Subprocess child =
      ForkContinuousAlloc(allocator_mode(), kAllocSize, kCustomAllocSize);
  const uint64_t pid = static_cast<uint64_t>(child.pid());

  TraceConfig trace_config = MakeTraceConfig([this, pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(kSamplingInterval);
    cfg->add_pid(pid);
    cfg->add_heaps(allocator_name());
    cfg->add_heaps("secondary");
    ContinuousDump(cfg);
  });

  auto helper = Trace(trace_config);
  WRITE_TRACE(helper->full_trace());
  PrintStats(helper.get());
  KillAssertRunning(&child);

  ValidateHasSamples(helper.get(), pid, "secondary", kSamplingInterval);
  ValidateHasSamples(helper.get(), pid, allocator_name(), kSamplingInterval);
  ValidateOnlyPID(helper.get(), pid);
  ValidateSampleSizes(helper.get(), pid, kCustomAllocSize, "secondary");
  ValidateSampleSizes(helper.get(), pid, kAllocSize, allocator_name());
}

TEST_P(HeapprofdEndToEnd, TwoAllocatorsAll) {
  constexpr size_t kCustomAllocSize = 1024;
  constexpr size_t kAllocSize = 7;
  constexpr size_t kSamplingInterval = 1;

  base::Subprocess child =
      ForkContinuousAlloc(allocator_mode(), kAllocSize, kCustomAllocSize);
  const uint64_t pid = static_cast<uint64_t>(child.pid());

  TraceConfig trace_config = MakeTraceConfig([pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(kSamplingInterval);
    cfg->add_pid(pid);
    cfg->set_all_heaps(true);
    ContinuousDump(cfg);
  });

  auto helper = Trace(trace_config);
  WRITE_TRACE(helper->full_trace());
  PrintStats(helper.get());
  KillAssertRunning(&child);

  ValidateHasSamples(helper.get(), pid, "secondary", kSamplingInterval);
  ValidateHasSamples(helper.get(), pid, allocator_name(), kSamplingInterval);
  ValidateOnlyPID(helper.get(), pid);
  ValidateSampleSizes(helper.get(), pid, kCustomAllocSize, "secondary");
  ValidateSampleSizes(helper.get(), pid, kAllocSize, allocator_name());
}

TEST_P(HeapprofdEndToEnd, AccurateCustomReportAllocation) {
  if (allocator_mode() != AllocatorMode::kCustom)
    GTEST_SKIP();

  base::Subprocess child({"/proc/self/exe"});
  child.args.posix_argv0_override_for_testing = "heapprofd_continuous_malloc";
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_ACCURATE_MALLOC=1");
  StartAndWaitForHandshake(&child);

  const uint64_t pid = static_cast<uint64_t>(child.pid());

  TraceConfig trace_config = MakeTraceConfig([pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(1);
    cfg->add_pid(pid);
    cfg->add_heaps("test");
  });

  auto helper = Trace(trace_config);
  WRITE_TRACE(helper->full_trace());
  PrintStats(helper.get());
  KillAssertRunning(&child);

  auto flamegraph = GetFlamegraph(&helper->tp());
  EXPECT_THAT(flamegraph,
              Contains(AllOf(
                  Field(&FlamegraphNode::name, HasSubstr("RunAccurateMalloc")),
                  Field(&FlamegraphNode::cumulative_size, Eq(15)),
                  Field(&FlamegraphNode::cumulative_alloc_size, Eq(40)))));

  ValidateOnlyPID(helper.get(), pid);

  size_t total_alloc = 0;
  size_t total_freed = 0;
  for (const protos::gen::TracePacket& packet : helper->trace()) {
    for (const auto& dump : packet.profile_packet().process_dumps()) {
      for (const auto& sample : dump.samples()) {
        total_alloc += sample.self_allocated();
        total_freed += sample.self_freed();
      }
    }
  }
  EXPECT_EQ(total_alloc, 40u);
  EXPECT_EQ(total_freed, 25u);
}

#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#define MAYBE_AccurateCustomReportAllocationWithVfork \
  AccurateCustomReportAllocationWithVfork
#define MAYBE_AccurateCustomReportAllocationWithVforkThread \
  AccurateCustomReportAllocationWithVforkThread
#else
#define MAYBE_AccurateCustomReportAllocationWithVfork \
  DISABLED_AccurateCustomReportAllocationWithVfork
#define MAYBE_AccurateCustomReportAllocationWithVforkThread \
  DISABLED_AccurateCustomReportAllocationWithVforkThread
#endif

TEST_P(HeapprofdEndToEnd, MAYBE_AccurateCustomReportAllocationWithVfork) {
  if (allocator_mode() != AllocatorMode::kCustom)
    GTEST_SKIP();

  base::Subprocess child({"/proc/self/exe"});
  child.args.posix_argv0_override_for_testing = "heapprofd_continuous_malloc";
  child.args.env.push_back(
      "HEAPPROFD_TESTING_RUN_ACCURATE_MALLOC_WITH_VFORK=1");
  StartAndWaitForHandshake(&child);

  const uint64_t pid = static_cast<uint64_t>(child.pid());

  TraceConfig trace_config = MakeTraceConfig([pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(1);
    cfg->add_pid(pid);
    cfg->add_heaps("test");
  });

  auto helper = Trace(trace_config);
  WRITE_TRACE(helper->full_trace());
  PrintStats(helper.get());
  KillAssertRunning(&child);

  auto flamegraph = GetFlamegraph(&helper->tp());
  EXPECT_THAT(flamegraph,
              Contains(AllOf(
                  Field(&FlamegraphNode::name, HasSubstr("RunAccurateMalloc")),
                  Field(&FlamegraphNode::cumulative_size, Eq(15)),
                  Field(&FlamegraphNode::cumulative_alloc_size, Eq(40)))));

  ValidateOnlyPID(helper.get(), pid);

  size_t total_alloc = 0;
  size_t total_freed = 0;
  for (const protos::gen::TracePacket& packet : helper->trace()) {
    for (const auto& dump : packet.profile_packet().process_dumps()) {
      EXPECT_FALSE(dump.disconnected());
      for (const auto& sample : dump.samples()) {
        total_alloc += sample.self_allocated();
        total_freed += sample.self_freed();
      }
    }
  }
  EXPECT_EQ(total_alloc, 40u);
  EXPECT_EQ(total_freed, 25u);
}

TEST_P(HeapprofdEndToEnd, MAYBE_AccurateCustomReportAllocationWithVforkThread) {
  if (allocator_mode() != AllocatorMode::kCustom)
    GTEST_SKIP();

  base::Subprocess child({"/proc/self/exe"});
  child.args.posix_argv0_override_for_testing = "heapprofd_continuous_malloc";
  child.args.env.push_back(
      "HEAPPROFD_TESTING_RUN_ACCURATE_MALLOC_WITH_VFORK_THREAD=1");
  StartAndWaitForHandshake(&child);

  const uint64_t pid = static_cast<uint64_t>(child.pid());

  TraceConfig trace_config = MakeTraceConfig([pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(1);
    cfg->add_pid(pid);
    cfg->add_heaps("test");
  });

  auto helper = Trace(trace_config);
  WRITE_TRACE(helper->full_trace());
  PrintStats(helper.get());
  KillAssertRunning(&child);

  auto flamegraph = GetFlamegraph(&helper->tp());
  EXPECT_THAT(flamegraph,
              Contains(AllOf(
                  Field(&FlamegraphNode::name, HasSubstr("RunAccurateMalloc")),
                  Field(&FlamegraphNode::cumulative_size, Eq(15)),
                  Field(&FlamegraphNode::cumulative_alloc_size, Eq(40)))));

  ValidateOnlyPID(helper.get(), pid);

  size_t total_alloc = 0;
  size_t total_freed = 0;
  for (const protos::gen::TracePacket& packet : helper->trace()) {
    for (const auto& dump : packet.profile_packet().process_dumps()) {
      EXPECT_FALSE(dump.disconnected());
      for (const auto& sample : dump.samples()) {
        total_alloc += sample.self_allocated();
        total_freed += sample.self_freed();
      }
    }
  }
  EXPECT_EQ(total_alloc, 40u);
  EXPECT_EQ(total_freed, 25u);
}

TEST_P(HeapprofdEndToEnd, AccurateCustomReportSample) {
  if (allocator_mode() != AllocatorMode::kCustom)
    GTEST_SKIP();

  base::Subprocess child({"/proc/self/exe"});
  child.args.posix_argv0_override_for_testing = "heapprofd_continuous_malloc";
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_ACCURATE_SAMPLE=1");
  StartAndWaitForHandshake(&child);

  const uint64_t pid = static_cast<uint64_t>(child.pid());

  TraceConfig trace_config = MakeTraceConfig([pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(1000000);
    cfg->add_pid(pid);
    cfg->add_heaps("test");
  });

  auto helper = Trace(trace_config);
  WRITE_TRACE(helper->full_trace());
  PrintStats(helper.get());
  KillAssertRunning(&child);

  ValidateOnlyPID(helper.get(), pid);

  size_t total_alloc = 0;
  size_t total_freed = 0;
  for (const protos::gen::TracePacket& packet : helper->trace()) {
    for (const auto& dump : packet.profile_packet().process_dumps()) {
      for (const auto& sample : dump.samples()) {
        total_alloc += sample.self_allocated();
        total_freed += sample.self_freed();
      }
    }
  }
  EXPECT_EQ(total_alloc, 40u);
  EXPECT_EQ(total_freed, 25u);
}

TEST_P(HeapprofdEndToEnd, AccurateDumpAtMaxCustom) {
  if (allocator_mode() != AllocatorMode::kCustom)
    GTEST_SKIP();

  base::Subprocess child({"/proc/self/exe"});
  child.args.posix_argv0_override_for_testing = "heapprofd_continuous_malloc";
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_ACCURATE_MALLOC=1");
  StartAndWaitForHandshake(&child);

  const uint64_t pid = static_cast<uint64_t>(child.pid());

  TraceConfig trace_config = MakeTraceConfig([pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(1);
    cfg->add_pid(pid);
    cfg->add_heaps("test");
    cfg->set_dump_at_max(true);
  });

  auto helper = Trace(trace_config);
  WRITE_TRACE(helper->full_trace());
  PrintStats(helper.get());
  KillAssertRunning(&child);

  ValidateOnlyPID(helper.get(), pid);

  size_t total_alloc = 0;
  size_t total_count = 0;
  for (const protos::gen::TracePacket& packet : helper->trace()) {
    for (const auto& dump : packet.profile_packet().process_dumps()) {
      for (const auto& sample : dump.samples()) {
        total_alloc += sample.self_max();
        total_count += sample.self_max_count();
      }
    }
  }
  EXPECT_EQ(total_alloc, 30u);
  EXPECT_EQ(total_count, 2u);
}

TEST_P(HeapprofdEndToEnd, CustomLifetime) {
  if (allocator_mode() != AllocatorMode::kCustom)
    GTEST_SKIP();

  int disabled_pipe[2];
  PERFETTO_CHECK(pipe(disabled_pipe) == 0);  // NOLINT(android-cloexec-pipe)

  int disabled_pipe_rd = disabled_pipe[0];
  int disabled_pipe_wr = disabled_pipe[1];

  base::Subprocess child({"/proc/self/exe"});
  child.args.posix_argv0_override_for_testing = "heapprofd_continuous_malloc";
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_LIFETIME_ARG0=1000000");
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_LIFETIME_ARG1=" +
                           std::to_string(disabled_pipe_wr));
  child.args.preserve_fds.push_back(disabled_pipe_wr);
  StartAndWaitForHandshake(&child);
  close(disabled_pipe_wr);

  const uint64_t pid = static_cast<uint64_t>(child.pid());

  TraceConfig trace_config = MakeTraceConfig([pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(1000000);
    cfg->add_pid(pid);
    cfg->add_heaps("test");
  });

  auto helper = Trace(trace_config);
  WRITE_TRACE(helper->full_trace());
  PrintStats(helper.get());
  // Give client some time to notice the disconnect.
  sleep(2);
  KillAssertRunning(&child);

  char x;
  EXPECT_EQ(base::Read(disabled_pipe_rd, &x, sizeof(x)), 1);
  close(disabled_pipe_rd);
}

TEST_P(HeapprofdEndToEnd, TwoProcesses) {
  constexpr size_t kAllocSize = 1024;
  constexpr size_t kAllocSize2 = 7;
  constexpr size_t kSamplingInterval = 1;

  base::Subprocess child = ForkContinuousAlloc(allocator_mode(), kAllocSize);
  base::Subprocess child2 = ForkContinuousAlloc(allocator_mode(), kAllocSize2);
  const uint64_t pid = static_cast<uint64_t>(child.pid());
  const auto pid2 = child2.pid();

  TraceConfig trace_config =
      MakeTraceConfig([this, pid, pid2](HeapprofdConfig* cfg) {
        cfg->set_sampling_interval_bytes(kSamplingInterval);
        cfg->add_pid(pid);
        cfg->add_pid(static_cast<uint64_t>(pid2));
        cfg->add_heaps(allocator_name());
      });

  auto helper = Trace(trace_config);
  WRITE_TRACE(helper->full_trace());
  PrintStats(helper.get());

  KillAssertRunning(&child);
  KillAssertRunning(&child2);

  ValidateHasSamples(helper.get(), pid, allocator_name(), kSamplingInterval);
  ValidateSampleSizes(helper.get(), pid, kAllocSize);
  ValidateHasSamples(helper.get(), static_cast<uint64_t>(pid2),
                     allocator_name(), kSamplingInterval);
  ValidateSampleSizes(helper.get(), static_cast<uint64_t>(pid2), kAllocSize2);
}

TEST_P(HeapprofdEndToEnd, FinalFlush) {
  constexpr size_t kAllocSize = 1024;
  constexpr size_t kSamplingInterval = 1;

  base::Subprocess child = ForkContinuousAlloc(allocator_mode(), kAllocSize);
  const uint64_t pid = static_cast<uint64_t>(child.pid());
  TraceConfig trace_config = MakeTraceConfig([this, pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(kSamplingInterval);
    cfg->add_pid(pid);
    cfg->add_heaps(allocator_name());
  });

  auto helper = Trace(trace_config);
  WRITE_TRACE(helper->full_trace());
  PrintStats(helper.get());
  KillAssertRunning(&child);

  ValidateHasSamples(helper.get(), pid, allocator_name(), kSamplingInterval);
  ValidateOnlyPID(helper.get(), pid);
  ValidateSampleSizes(helper.get(), pid, kAllocSize);
}

TEST_P(HeapprofdEndToEnd, NativeStartup) {
  if (test_mode() == TestMode::kStatic)
    GTEST_SKIP();

  auto helper = GetHelper(&task_runner);

  TraceConfig trace_config = MakeTraceConfig([this](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(1);
    cfg->add_process_cmdline("heapprofd_continuous_malloc");
    cfg->add_heaps(allocator_name());
  });
  trace_config.set_duration_ms(5000);

  helper->StartTracing(trace_config);

  // Wait to guarantee that the process forked below is hooked by the profiler
  // by virtue of the startup check, and not by virtue of being seen as a
  // running process. This sleep is here to prevent that, accidentally, the
  // test gets to the fork()+exec() too soon, before the heap profiling daemon
  // has received the trace config.
  sleep(1);

  base::Subprocess child({"/proc/self/exe"});
  child.args.posix_argv0_override_for_testing = "heapprofd_continuous_malloc";
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG0=" +
                           allocator_name());
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG1=" +
                           std::to_string(kStartupAllocSize));
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG2=" +
                           std::string("0"));
  StartAndWaitForHandshake(&child);

  ReadAndWait(helper.get());
  WRITE_TRACE(helper->full_trace());

  KillAssertRunning(&child);

  const auto& packets = helper->trace();
  ASSERT_GT(packets.size(), 0u);
  size_t profile_packets = 0;
  size_t samples = 0;
  uint64_t total_allocated = 0;
  uint64_t total_freed = 0;
  for (const protos::gen::TracePacket& packet : packets) {
    if (packet.has_profile_packet() &&
        !packet.profile_packet().process_dumps().empty()) {
      const auto& dumps = packet.profile_packet().process_dumps();
      ASSERT_EQ(dumps.size(), 1u);
      const protos::gen::ProfilePacket_ProcessHeapSamples& dump = dumps[0];
      EXPECT_EQ(static_cast<pid_t>(dump.pid()), child.pid());
      profile_packets++;
      for (const auto& sample : dump.samples()) {
        samples++;
        total_allocated += sample.self_allocated();
        total_freed += sample.self_freed();
      }
    }
  }
  EXPECT_EQ(profile_packets, 1u);
  EXPECT_GT(samples, 0u);
  EXPECT_GT(total_allocated, 0u);
  EXPECT_GT(total_freed, 0u);
}

TEST_P(HeapprofdEndToEnd, NativeStartupDenormalizedCmdline) {
  if (test_mode() == TestMode::kStatic)
    GTEST_SKIP();

  auto helper = GetHelper(&task_runner);

  TraceConfig trace_config = MakeTraceConfig([this](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(1);
    cfg->add_process_cmdline("heapprofd_continuous_malloc@1.2.3");
    cfg->add_heaps(allocator_name());
  });
  trace_config.set_duration_ms(5000);

  helper->StartTracing(trace_config);

  // Wait to guarantee that the process forked below is hooked by the profiler
  // by virtue of the startup check, and not by virtue of being seen as a
  // running process. This sleep is here to prevent that, accidentally, the
  // test gets to the fork()+exec() too soon, before the heap profiling daemon
  // has received the trace config.
  sleep(1);

  base::Subprocess child({"/proc/self/exe"});
  child.args.posix_argv0_override_for_testing = "heapprofd_continuous_malloc";
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG0=" +
                           allocator_name());
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG1=" +
                           std::to_string(kStartupAllocSize));
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG2=" +
                           std::string("0"));

  StartAndWaitForHandshake(&child);

  ReadAndWait(helper.get());
  WRITE_TRACE(helper->full_trace());

  KillAssertRunning(&child);

  const auto& packets = helper->trace();
  ASSERT_GT(packets.size(), 0u);
  size_t profile_packets = 0;
  size_t samples = 0;
  uint64_t total_allocated = 0;
  uint64_t total_freed = 0;
  for (const protos::gen::TracePacket& packet : packets) {
    if (packet.has_profile_packet() &&
        !packet.profile_packet().process_dumps().empty()) {
      const auto& dumps = packet.profile_packet().process_dumps();
      ASSERT_EQ(dumps.size(), 1u);
      const protos::gen::ProfilePacket_ProcessHeapSamples& dump = dumps[0];
      EXPECT_EQ(static_cast<pid_t>(dump.pid()), child.pid());
      profile_packets++;
      for (const auto& sample : dump.samples()) {
        samples++;
        total_allocated += sample.self_allocated();
        total_freed += sample.self_freed();
      }
    }
  }
  EXPECT_EQ(profile_packets, 1u);
  EXPECT_GT(samples, 0u);
  EXPECT_GT(total_allocated, 0u);
  EXPECT_GT(total_freed, 0u);
}

TEST_P(HeapprofdEndToEnd, DiscoverByName) {
  auto helper = GetHelper(&task_runner);

  base::Subprocess child({"/proc/self/exe"});
  child.args.posix_argv0_override_for_testing = "heapprofd_continuous_malloc";
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG0=" +
                           allocator_name());
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG1=" +
                           std::to_string(kStartupAllocSize));
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG2=" +
                           std::string("0"));

  StartAndWaitForHandshake(&child);

  // Wait to make sure process is fully initialized, so we do not accidentally
  // match it by the startup logic.
  sleep(1);

  TraceConfig trace_config = MakeTraceConfig([this](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(1);
    cfg->add_process_cmdline("heapprofd_continuous_malloc");
    cfg->add_heaps(allocator_name());
  });
  trace_config.set_duration_ms(5000);

  helper->StartTracing(trace_config);
  ReadAndWait(helper.get());
  WRITE_TRACE(helper->full_trace());

  KillAssertRunning(&child);

  const auto& packets = helper->trace();
  ASSERT_GT(packets.size(), 0u);
  size_t profile_packets = 0;
  size_t samples = 0;
  uint64_t total_allocated = 0;
  uint64_t total_freed = 0;
  for (const protos::gen::TracePacket& packet : packets) {
    if (packet.has_profile_packet() &&
        !packet.profile_packet().process_dumps().empty()) {
      const auto& dumps = packet.profile_packet().process_dumps();
      ASSERT_EQ(dumps.size(), 1u);
      const protos::gen::ProfilePacket_ProcessHeapSamples& dump = dumps[0];
      EXPECT_EQ(static_cast<pid_t>(dump.pid()), child.pid());
      profile_packets++;
      for (const auto& sample : dump.samples()) {
        samples++;
        total_allocated += sample.self_allocated();
        total_freed += sample.self_freed();
      }
    }
  }
  EXPECT_EQ(profile_packets, 1u);
  EXPECT_GT(samples, 0u);
  EXPECT_GT(total_allocated, 0u);
  EXPECT_GT(total_freed, 0u);
}

TEST_P(HeapprofdEndToEnd, DiscoverByNameDenormalizedCmdline) {
  auto helper = GetHelper(&task_runner);

  // Make sure the forked process does not get reparented to init.
  base::Subprocess child({"/proc/self/exe"});
  child.args.posix_argv0_override_for_testing = "heapprofd_continuous_malloc";
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG0=" +
                           allocator_name());
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG1=" +
                           std::to_string(kStartupAllocSize));
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG2=" +
                           std::string("0"));

  StartAndWaitForHandshake(&child);

  // Wait to make sure process is fully initialized, so we do not accidentally
  // match it by the startup logic.
  sleep(1);

  TraceConfig trace_config = MakeTraceConfig([this](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(1);
    cfg->add_process_cmdline("heapprofd_continuous_malloc@1.2.3");
    cfg->add_heaps(allocator_name());
  });
  trace_config.set_duration_ms(5000);

  helper->StartTracing(trace_config);
  ReadAndWait(helper.get());
  WRITE_TRACE(helper->full_trace());

  KillAssertRunning(&child);

  const auto& packets = helper->trace();
  ASSERT_GT(packets.size(), 0u);
  size_t profile_packets = 0;
  size_t samples = 0;
  uint64_t total_allocated = 0;
  uint64_t total_freed = 0;
  for (const protos::gen::TracePacket& packet : packets) {
    if (packet.has_profile_packet() &&
        !packet.profile_packet().process_dumps().empty()) {
      const auto& dumps = packet.profile_packet().process_dumps();
      ASSERT_EQ(dumps.size(), 1u);
      const protos::gen::ProfilePacket_ProcessHeapSamples& dump = dumps[0];
      EXPECT_EQ(static_cast<pid_t>(dump.pid()), child.pid());
      profile_packets++;
      for (const auto& sample : dump.samples()) {
        samples++;
        total_allocated += sample.self_allocated();
        total_freed += sample.self_freed();
      }
    }
  }
  EXPECT_EQ(profile_packets, 1u);
  EXPECT_GT(samples, 0u);
  EXPECT_GT(total_allocated, 0u);
  EXPECT_GT(total_freed, 0u);
}

TEST_P(HeapprofdEndToEnd, ReInit) {
  constexpr size_t kSamplingInterval = 1;

  // We cannot use base::Pipe because that assumes we want CLOEXEC.
  // We do NOT want CLOEXEC as this gets used by the RunReInit in the child.
  int signal_pipe[2];
  int ack_pipe[2];

  PERFETTO_CHECK(pipe(signal_pipe) == 0);  // NOLINT(android-cloexec-pipe)
  PERFETTO_CHECK(pipe(ack_pipe) == 0);     // NOLINT(android-cloexec-pipe)

  int cur_flags = fcntl(signal_pipe[0], F_GETFL, 0);
  PERFETTO_CHECK(cur_flags >= 0);
  PERFETTO_CHECK(fcntl(signal_pipe[0], F_SETFL, cur_flags | O_NONBLOCK) == 0);
  cur_flags = fcntl(signal_pipe[1], F_GETFL, 0);
  PERFETTO_CHECK(cur_flags >= 0);
  PERFETTO_CHECK(fcntl(signal_pipe[1], F_SETFL, cur_flags | O_NONBLOCK) == 0);

  int signal_pipe_rd = signal_pipe[0];
  int signal_pipe_wr = signal_pipe[1];
  int ack_pipe_rd = ack_pipe[0];
  int ack_pipe_wr = ack_pipe[1];

  base::Subprocess child({"/proc/self/exe"});
  child.args.posix_argv0_override_for_testing = "heapprofd_continuous_malloc";
  child.args.preserve_fds.push_back(signal_pipe_rd);
  child.args.preserve_fds.push_back(ack_pipe_wr);
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_REINIT_ARG0=" +
                           allocator_name());
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_REINIT_ARG1=" +
                           std::to_string(signal_pipe_rd));
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_REINIT_ARG2=" +
                           std::to_string(ack_pipe_wr));
  StartAndWaitForHandshake(&child);

  const uint64_t pid = static_cast<uint64_t>(child.pid());

  close(signal_pipe_rd);
  close(ack_pipe_wr);

  TraceConfig trace_config = MakeTraceConfig([this, pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(kSamplingInterval);
    cfg->add_pid(pid);
    cfg->add_heaps(allocator_name());
  });

  auto helper = Trace(trace_config);
  WRITE_TRACE(helper->full_trace());

  PrintStats(helper.get());
  ValidateHasSamples(helper.get(), pid, allocator_name(), kSamplingInterval);
  ValidateOnlyPID(helper.get(), pid);
  ValidateSampleSizes(helper.get(), pid, kFirstIterationBytes);

  PERFETTO_CHECK(PERFETTO_EINTR(write(signal_pipe_wr, "1", 1)) == 1);
  close(signal_pipe_wr);
  char buf[1];
  ASSERT_EQ(PERFETTO_EINTR(read(ack_pipe_rd, buf, sizeof(buf))), 1);
  close(ack_pipe_rd);

  // A brief sleep to allow the client to notice that the profiling session is
  // to be torn down (as it rejects concurrent sessions).
  usleep(500 * kMsToUs);

  PERFETTO_LOG("HeapprofdEndToEnd::Reinit: Starting second");

  // We must keep alive the original helper because it owns the service thread.
  std::unique_ptr<TraceProcessorTestHelper> helper2 =
      std::unique_ptr<TraceProcessorTestHelper>(
          new TraceProcessorTestHelper(&task_runner));

  helper2->ConnectConsumer();
  helper2->WaitForConsumerConnect();
  helper2->StartTracing(trace_config);
  ReadAndWait(helper2.get());
  WRITE_TRACE(helper2->trace());

  PrintStats(helper2.get());
  KillAssertRunning(&child);

  ValidateHasSamples(helper2.get(), pid, allocator_name(), kSamplingInterval);
  ValidateOnlyPID(helper2.get(), pid);
  ValidateSampleSizes(helper2.get(), pid, kSecondIterationBytes);
}

TEST_P(HeapprofdEndToEnd, ReInitAfterInvalid) {
  constexpr size_t kSamplingInterval = 1;

  // We cannot use base::Pipe because that assumes we want CLOEXEC.
  // We do NOT want CLOEXEC as this gets used by the RunReInit in the child.
  int signal_pipe[2];
  int ack_pipe[2];

  PERFETTO_CHECK(pipe(signal_pipe) == 0);  // NOLINT(android-cloexec-pipe)
  PERFETTO_CHECK(pipe(ack_pipe) == 0);     // NOLINT(android-cloexec-pipe)

  int cur_flags = fcntl(signal_pipe[0], F_GETFL, 0);
  PERFETTO_CHECK(cur_flags >= 0);
  PERFETTO_CHECK(fcntl(signal_pipe[0], F_SETFL, cur_flags | O_NONBLOCK) == 0);
  cur_flags = fcntl(signal_pipe[1], F_GETFL, 0);
  PERFETTO_CHECK(cur_flags >= 0);
  PERFETTO_CHECK(fcntl(signal_pipe[1], F_SETFL, cur_flags | O_NONBLOCK) == 0);

  int signal_pipe_rd = signal_pipe[0];
  int signal_pipe_wr = signal_pipe[1];
  int ack_pipe_rd = ack_pipe[0];
  int ack_pipe_wr = ack_pipe[1];

  base::Subprocess child({"/proc/self/exe"});
  child.args.posix_argv0_override_for_testing = "heapprofd_continuous_malloc";
  child.args.preserve_fds.push_back(signal_pipe_rd);
  child.args.preserve_fds.push_back(ack_pipe_wr);
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_REINIT_ARG0=" +
                           allocator_name());
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_REINIT_ARG1=" +
                           std::to_string(signal_pipe_rd));
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_REINIT_ARG2=" +
                           std::to_string(ack_pipe_wr));
  StartAndWaitForHandshake(&child);

  const uint64_t pid = static_cast<uint64_t>(child.pid());

  close(signal_pipe_rd);
  close(ack_pipe_wr);

  TraceConfig trace_config = MakeTraceConfig([this, pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(kSamplingInterval);
    cfg->add_pid(pid);
    cfg->add_heaps(allocator_name());
  });

  auto helper = Trace(trace_config);
  WRITE_TRACE(helper->full_trace());

  PrintStats(helper.get());
  ValidateHasSamples(helper.get(), pid, allocator_name(), kSamplingInterval);
  ValidateOnlyPID(helper.get(), pid);
  ValidateSampleSizes(helper.get(), pid, kFirstIterationBytes);

  PERFETTO_CHECK(PERFETTO_EINTR(write(signal_pipe_wr, "1", 1)) == 1);
  close(signal_pipe_wr);
  char buf[1];
  ASSERT_EQ(PERFETTO_EINTR(read(ack_pipe_rd, buf, sizeof(buf))), 1);
  close(ack_pipe_rd);

  // A brief sleep to allow the client to notice that the profiling session is
  // to be torn down (as it rejects concurrent sessions).
  usleep(500 * kMsToUs);

  PERFETTO_LOG("HeapprofdEndToEnd::Reinit: Starting second");

  // We must keep alive the original helper because it owns the service thread.
  std::unique_ptr<TraceProcessorTestHelper> helper2 =
      std::unique_ptr<TraceProcessorTestHelper>(
          new TraceProcessorTestHelper(&task_runner));

  helper2->ConnectConsumer();
  helper2->WaitForConsumerConnect();
  helper2->StartTracing(trace_config);
  ReadAndWait(helper2.get());

  WRITE_TRACE(helper2->trace());

  PrintStats(helper2.get());
  KillAssertRunning(&child);

  ValidateHasSamples(helper2.get(), pid, allocator_name(), kSamplingInterval);
  ValidateOnlyPID(helper2.get(), pid);
  ValidateSampleSizes(helper2.get(), pid, kSecondIterationBytes);
}

TEST_P(HeapprofdEndToEnd, ConcurrentSession) {
  constexpr size_t kAllocSize = 1024;
  constexpr size_t kSamplingInterval = 1;

  base::Subprocess child = ForkContinuousAlloc(allocator_mode(), kAllocSize);
  const uint64_t pid = static_cast<uint64_t>(child.pid());

  TraceConfig trace_config = MakeTraceConfig([this, pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(kSamplingInterval);
    cfg->add_pid(pid);
    cfg->add_heaps(allocator_name());
    ContinuousDump(cfg);
  });
  trace_config.set_duration_ms(5000);

  auto helper = GetHelper(&task_runner);
  helper->StartTracing(trace_config);
  sleep(1);

  PERFETTO_LOG("Starting concurrent.");
  std::unique_ptr<TraceProcessorTestHelper> helper_concurrent(
      new TraceProcessorTestHelper(&task_runner));
  helper_concurrent->ConnectConsumer();
  helper_concurrent->WaitForConsumerConnect();
  helper_concurrent->StartTracing(trace_config);

  ReadAndWait(helper.get());
  WRITE_TRACE(helper->full_trace());
  PrintStats(helper.get());

  ReadAndWait(helper_concurrent.get());
  WRITE_TRACE(helper_concurrent->trace());
  PrintStats(helper_concurrent.get());
  KillAssertRunning(&child);

  ValidateHasSamples(helper.get(), pid, allocator_name(), kSamplingInterval);
  ValidateOnlyPID(helper.get(), pid);
  ValidateSampleSizes(helper.get(), pid, kAllocSize);
  ValidateRejectedConcurrent(helper.get(), pid, false);

  ValidateOnlyPID(helper_concurrent.get(), pid);
  ValidateRejectedConcurrent(helper_concurrent.get(), pid, true);
}

TEST_P(HeapprofdEndToEnd, NativeProfilingActiveAtProcessExit) {
  constexpr uint64_t kTestAllocSize = 128;
  base::Pipe start_pipe = base::Pipe::Create(base::Pipe::kBothBlock);
  int start_pipe_wr = *start_pipe.wr;

  base::Subprocess child({"/proc/self/exe"});
  child.args.posix_argv0_override_for_testing = "heapprofd_continuous_malloc";
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG0=" +
                           allocator_name());
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG1=" +
                           std::to_string(kTestAllocSize));
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG2=" +
                           std::to_string(0));
  child.args.env.push_back("HEAPPROFD_TESTING_RUN_MALLOC_ARG3=" +
                           std::to_string(200));
  child.args.preserve_fds.push_back(start_pipe_wr);
  child.args.posix_entrypoint_for_testing = [start_pipe_wr] {
    PERFETTO_CHECK(PERFETTO_EINTR(write(start_pipe_wr, "1", 1)) == 1);
    PERFETTO_CHECK(close(start_pipe_wr) == 0 || errno == EINTR);
  };

  StartAndWaitForHandshake(&child);

  const uint64_t pid = static_cast<uint64_t>(child.pid());
  start_pipe.wr.reset();

  // Construct tracing config (without starting profiling).
  auto helper = GetHelper(&task_runner);

  // Wait for child to have been scheduled at least once.
  char buf[1] = {};
  ASSERT_EQ(PERFETTO_EINTR(read(*start_pipe.rd, buf, sizeof(buf))), 1);
  start_pipe.rd.reset();

  TraceConfig trace_config = MakeTraceConfig([this, pid](HeapprofdConfig* cfg) {
    cfg->set_sampling_interval_bytes(1);
    cfg->add_pid(pid);
    cfg->add_heaps(allocator_name());
  });
  trace_config.set_duration_ms(5000);

  // Trace until child exits.
  helper->StartTracing(trace_config);

  // Wait for the child and assert that it exited successfully.
  EXPECT_TRUE(child.Wait(30000));
  EXPECT_EQ(child.status(), base::Subprocess::kTerminated);
  EXPECT_EQ(child.returncode(), 0);

  // Assert that we did profile the process.
  helper->FlushAndWait(2000);
  helper->DisableTracing();
  ReadAndWait(helper.get());
  WRITE_TRACE(helper->full_trace());

  const auto& packets = helper->trace();
  ASSERT_GT(packets.size(), 0u);
  size_t profile_packets = 0;
  size_t samples = 0;
  uint64_t total_allocated = 0;
  for (const protos::gen::TracePacket& packet : packets) {
    if (packet.has_profile_packet() &&
        !packet.profile_packet().process_dumps().empty()) {
      const auto& dumps = packet.profile_packet().process_dumps();
      ASSERT_EQ(dumps.size(), 1u);
      const protos::gen::ProfilePacket_ProcessHeapSamples& dump = dumps[0];
      EXPECT_EQ(dump.pid(), pid);
      profile_packets++;
      for (const auto& sample : dump.samples()) {
        samples++;
        total_allocated += sample.self_allocated();
      }
    }
  }
  EXPECT_EQ(profile_packets, 1u);
  EXPECT_GT(samples, 0u);
  EXPECT_GT(total_allocated, 0u);
}

// On in-tree Android, we use the system heapprofd in fork or central mode.
// For Linux and out-of-tree Android, we statically include a copy of
// heapprofd and use that. This one does not support intercepting malloc.
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#if !PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
#error "Need to start daemons for Linux test."
#endif

INSTANTIATE_TEST_CASE_P(DISABLED_Run,
                        HeapprofdEndToEnd,
                        Values(std::make_tuple(TestMode::kStatic,
                                               AllocatorMode::kCustom)),
                        TestSuffix);
#elif !PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
INSTANTIATE_TEST_CASE_P(
    Run,
    HeapprofdEndToEnd,
    Values(std::make_tuple(TestMode::kCentral, AllocatorMode::kMalloc),
           std::make_tuple(TestMode::kCentral, AllocatorMode::kCustom)),
    TestSuffix);
#endif

}  // namespace
}  // namespace profiling
}  // namespace perfetto
