// Copyright (c) 2011 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <fcntl.h>
#include <poll.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <ucontext.h>
#include <unistd.h>

#include <string>

#include "breakpad_googletest_includes.h"
#include "client/linux/handler/exception_handler.h"
#include "client/linux/minidump_writer/linux_dumper.h"
#include "client/linux/minidump_writer/minidump_writer.h"
#include "client/linux/minidump_writer/minidump_writer_unittest_utils.h"
#include "common/linux/breakpad_getcontext.h"
#include "common/linux/eintr_wrapper.h"
#include "common/linux/file_id.h"
#include "common/linux/ignore_ret.h"
#include "common/linux/safe_readlink.h"
#include "common/scoped_ptr.h"
#include "common/tests/auto_tempdir.h"
#include "common/tests/file_utils.h"
#include "common/using_std_string.h"
#include "google_breakpad/processor/minidump.h"

using namespace google_breakpad;

namespace {

typedef testing::Test MinidumpWriterTest;

const char kMDWriterUnitTestFileName[] = "/minidump-writer-unittest";

TEST(MinidumpWriterTest, SetupWithPath) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b))));
    close(fds[0]);
    syscall(__NR_exit_group);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));

  AutoTempDir temp_dir;
  string templ = temp_dir.path() + kMDWriterUnitTestFileName;
  // Set a non-zero tid to avoid tripping asserts.
  context.tid = child;
  ASSERT_TRUE(WriteMinidump(templ.c_str(), child, &context, sizeof(context)));
  struct stat st;
  ASSERT_EQ(0, stat(templ.c_str(), &st));
  ASSERT_GT(st.st_size, 0);

  close(fds[1]);
  IGNORE_EINTR(waitpid(child, nullptr, 0));
}

TEST(MinidumpWriterTest, SetupWithFD) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    HANDLE_EINTR(read(fds[0], &b, sizeof(b)));
    close(fds[0]);
    syscall(__NR_exit_group);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));

  AutoTempDir temp_dir;
  string templ = temp_dir.path() + kMDWriterUnitTestFileName;
  int fd = open(templ.c_str(), O_CREAT | O_WRONLY, S_IRWXU);
  // Set a non-zero tid to avoid tripping asserts.
  context.tid = child;
  ASSERT_TRUE(WriteMinidump(fd, child, &context, sizeof(context)));
  struct stat st;
  ASSERT_EQ(0, stat(templ.c_str(), &st));
  ASSERT_GT(st.st_size, 0);

  close(fds[1]);
  IGNORE_EINTR(waitpid(child, nullptr, 0));
}

// Test that mapping info can be specified when writing a minidump,
// and that it ends up in the module list of the minidump.
TEST(MinidumpWriterTest, MappingInfo) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  // These are defined here so the parent can use them to check the
  // data from the minidump afterwards.
  const uint32_t memory_size = sysconf(_SC_PAGESIZE);
  const char* kMemoryName = "a fake module";
  const uint8_t kModuleGUID[sizeof(MDGUID)] = {
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
  };
  const string module_identifier = "33221100554477668899AABBCCDDEEFF0";

  // Get some memory.
  char* memory =
    reinterpret_cast<char*>(mmap(NULL,
                                 memory_size,
                                 PROT_READ | PROT_WRITE,
                                 MAP_PRIVATE | MAP_ANON,
                                 -1,
                                 0));
  const uintptr_t kMemoryAddress = reinterpret_cast<uintptr_t>(memory);
  ASSERT_TRUE(memory);

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b))));
    close(fds[0]);
    syscall(__NR_exit_group);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));
  ASSERT_EQ(0, getcontext(&context.context));
  context.tid = child;

  AutoTempDir temp_dir;
  string templ = temp_dir.path() + kMDWriterUnitTestFileName;

  // Add information about the mapped memory.
  MappingInfo info;
  info.start_addr = kMemoryAddress;
  info.size = memory_size;
  info.offset = 0;
  info.exec = false;
  strcpy(info.name, kMemoryName);

  MappingList mappings;
  AppMemoryList memory_list;
  MappingEntry mapping;
  mapping.first = info;
  memcpy(mapping.second, kModuleGUID, sizeof(MDGUID));
  mappings.push_back(mapping);
  ASSERT_TRUE(WriteMinidump(templ.c_str(), child, &context, sizeof(context),
                            mappings, memory_list, false, 0, false));

  // Read the minidump. Load the module list, and ensure that
  // the mmap'ed |memory| is listed with the given module name
  // and debug ID.
  Minidump minidump(templ);
  ASSERT_TRUE(minidump.Read());

  MinidumpModuleList* module_list = minidump.GetModuleList();
  ASSERT_TRUE(module_list);
  const MinidumpModule* module =
    module_list->GetModuleForAddress(kMemoryAddress);
  ASSERT_TRUE(module);

  EXPECT_EQ(kMemoryAddress, module->base_address());
  EXPECT_EQ(memory_size, module->size());
  EXPECT_EQ(kMemoryName, module->code_file());
  EXPECT_EQ(module_identifier, module->debug_identifier());

  uint32_t len;
  // These streams are expected to be there
  EXPECT_TRUE(minidump.SeekToStreamType(MD_THREAD_LIST_STREAM, &len));
  EXPECT_TRUE(minidump.SeekToStreamType(MD_MEMORY_LIST_STREAM, &len));
  EXPECT_TRUE(minidump.SeekToStreamType(MD_EXCEPTION_STREAM, &len));
  EXPECT_TRUE(minidump.SeekToStreamType(MD_SYSTEM_INFO_STREAM, &len));
  EXPECT_TRUE(minidump.SeekToStreamType(MD_LINUX_CPU_INFO, &len));
  EXPECT_TRUE(minidump.SeekToStreamType(MD_LINUX_PROC_STATUS, &len));
  EXPECT_TRUE(minidump.SeekToStreamType(MD_LINUX_CMD_LINE, &len));
  EXPECT_TRUE(minidump.SeekToStreamType(MD_LINUX_ENVIRON, &len));
  EXPECT_TRUE(minidump.SeekToStreamType(MD_LINUX_AUXV, &len));
  EXPECT_TRUE(minidump.SeekToStreamType(MD_LINUX_MAPS, &len));
  EXPECT_TRUE(minidump.SeekToStreamType(MD_LINUX_DSO_DEBUG, &len));

  close(fds[1]);
  IGNORE_EINTR(waitpid(child, nullptr, 0));
}

// Test that minidumping is skipped while writing minidumps if principal mapping
// is not referenced.
TEST(MinidumpWriterTest, MinidumpSkippedIfRequested) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b))));
    close(fds[0]);
    syscall(__NR_exit_group);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));
  ASSERT_EQ(0, getcontext(&context.context));
  context.tid = child;

  AutoTempDir temp_dir;
  string templ = temp_dir.path() + kMDWriterUnitTestFileName;

  // pass an invalid principal mapping address, which will force
  // WriteMinidump to not write a minidump.
  ASSERT_FALSE(WriteMinidump(templ.c_str(), child, &context, sizeof(context),
                            true, static_cast<uintptr_t>(0x0102030405060708ull),
                            false));
  close(fds[1]);
  IGNORE_EINTR(waitpid(child, nullptr, 0));
}

// Test that minidumping is skipped while writing minidumps if principal mapping
// is not referenced.
TEST(MinidumpWriterTest, MinidumpStacksSkippedIfRequested) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);

    // Create a thread that does not return, and only references libc (not the
    // current executable). This thread should not be captured in the minidump.
    pthread_t thread;
    pthread_attr_t thread_attributes;
    pthread_attr_init(&thread_attributes);
    pthread_attr_setdetachstate(&thread_attributes, PTHREAD_CREATE_DETACHED);
    sigset_t sigset;
    sigemptyset(&sigset);
    pthread_create(&thread, &thread_attributes,
                   reinterpret_cast<void* (*)(void*)>(&sigsuspend), &sigset);

    char b;
    IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b))));
    close(fds[0]);
    syscall(__NR_exit_group);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));
  ASSERT_EQ(0, getcontext(&context.context));
  context.tid = child;

  AutoTempDir temp_dir;
  string templ = temp_dir.path() + kMDWriterUnitTestFileName;

  // Pass an invalid principal mapping address, which will force
  // WriteMinidump to not dump any thread stacks.
  ASSERT_TRUE(WriteMinidump(
      templ.c_str(), child, &context, sizeof(context), true,
      reinterpret_cast<uintptr_t>(google_breakpad::WriteFile), false));

  // Read the minidump. And ensure that thread memory was dumped only for the
  // main thread.
  Minidump minidump(templ);
  ASSERT_TRUE(minidump.Read());

  MinidumpThreadList* threads = minidump.GetThreadList();
  int threads_with_stacks = 0;
  for (unsigned int i = 0; i < threads->thread_count(); ++i) {
    MinidumpThread* thread = threads->GetThreadAtIndex(i);
    if (thread->GetMemory()) {
      ++threads_with_stacks;
    }
  }
#if defined(THREAD_SANITIZER) || defined(ADDRESS_SANITIZER)
  ASSERT_GE(threads_with_stacks, 1);
#else
  ASSERT_EQ(threads_with_stacks, 1);
#endif
  close(fds[1]);
  IGNORE_EINTR(waitpid(child, nullptr, 0));
}

// Test that stacks can be sanitized while writing minidumps.
TEST(MinidumpWriterTest, StacksAreSanitizedIfRequested) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b))));
    close(fds[0]);
    syscall(__NR_exit_group);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));
  ASSERT_EQ(0, getcontext(&context.context));
  context.tid = child;

  AutoTempDir temp_dir;
  string templ = temp_dir.path() + kMDWriterUnitTestFileName;
  // pass an invalid principal mapping address, which will force
  // WriteMinidump to not dump any thread stacks.
  ASSERT_TRUE(WriteMinidump(templ.c_str(), child, &context, sizeof(context),
                            false, 0, true));

  // Read the minidump. And ensure that thread memory contains a defaced value.
  Minidump minidump(templ);
  ASSERT_TRUE(minidump.Read());

  const uintptr_t defaced =
#if defined(__LP64__)
      0x0defaced0defaced;
#else
      0x0defaced;
#endif
  MinidumpThreadList* threads = minidump.GetThreadList();
  for (unsigned int i = 0; i < threads->thread_count(); ++i) {
    MinidumpThread* thread = threads->GetThreadAtIndex(i);
    MinidumpMemoryRegion* mem = thread->GetMemory();
    ASSERT_TRUE(mem != nullptr);
    uint32_t sz = mem->GetSize();
    const uint8_t* data = mem->GetMemory();
    ASSERT_TRUE(memmem(data, sz, &defaced, sizeof(defaced)) != nullptr);
  }
  close(fds[1]);
  IGNORE_EINTR(waitpid(child, nullptr, 0));
}

// Test that a binary with a longer-than-usual build id note
// makes its way all the way through to the minidump unscathed.
// The linux_client_unittest is linked with an explicit --build-id
// in Makefile.am.
TEST(MinidumpWriterTest, BuildIDLong) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b))));
    close(fds[0]);
    syscall(__NR_exit_group);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));
  ASSERT_EQ(0, getcontext(&context.context));
  context.tid = child;

  AutoTempDir temp_dir;
  const string dump_path = temp_dir.path() + kMDWriterUnitTestFileName;

  EXPECT_TRUE(WriteMinidump(dump_path.c_str(),
                            child, &context, sizeof(context)));
  close(fds[1]);

  // Read the minidump. Load the module list, and ensure that
  // the main module has the correct debug id and code id.
  Minidump minidump(dump_path);
  ASSERT_TRUE(minidump.Read());

  MinidumpModuleList* module_list = minidump.GetModuleList();
  ASSERT_TRUE(module_list);
  const MinidumpModule* module = module_list->GetMainModule();
  ASSERT_TRUE(module);
  const string module_identifier = "030201000504070608090A0B0C0D0E0F0";
  // This is passed explicitly to the linker in Makefile.am
  const string build_id =
      "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
  EXPECT_EQ(module_identifier, module->debug_identifier());
  EXPECT_EQ(build_id, module->code_identifier());

  IGNORE_EINTR(waitpid(child, nullptr, 0));
}

// Test that mapping info can be specified, and that it overrides
// existing mappings that are wholly contained within the specified
// range.
TEST(MinidumpWriterTest, MappingInfoContained) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  // These are defined here so the parent can use them to check the
  // data from the minidump afterwards.
  const int32_t memory_size = sysconf(_SC_PAGESIZE);
  const char* kMemoryName = "a fake module";
  const uint8_t kModuleGUID[sizeof(MDGUID)] = {
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
  };
  const string module_identifier = "33221100554477668899AABBCCDDEEFF0";

  // mmap a file
  AutoTempDir temp_dir;
  string tempfile = temp_dir.path() + "/minidump-writer-unittest-temp";
  int fd = open(tempfile.c_str(), O_RDWR | O_CREAT, 0);
  ASSERT_NE(-1, fd);
  unlink(tempfile.c_str());
  // fill with zeros
  google_breakpad::scoped_array<char> buffer(new char[memory_size]);
  memset(buffer.get(), 0, memory_size);
  ASSERT_EQ(memory_size, write(fd, buffer.get(), memory_size));
  lseek(fd, 0, SEEK_SET);

  char* memory =
    reinterpret_cast<char*>(mmap(NULL,
                                 memory_size,
                                 PROT_READ | PROT_WRITE,
                                 MAP_PRIVATE,
                                 fd,
                                 0));
  const uintptr_t kMemoryAddress = reinterpret_cast<uintptr_t>(memory);
  ASSERT_TRUE(memory);
  close(fd);

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b))));
    close(fds[0]);
    syscall(__NR_exit_group);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));
  context.tid = 1;

  string dumpfile = temp_dir.path() + kMDWriterUnitTestFileName;

  // Add information about the mapped memory. Report it as being larger than
  // it actually is.
  MappingInfo info;
  info.start_addr = kMemoryAddress - memory_size;
  info.size = memory_size * 3;
  info.offset = 0;
  info.exec = false;
  strcpy(info.name, kMemoryName);

  MappingList mappings;
  AppMemoryList memory_list;
  MappingEntry mapping;
  mapping.first = info;
  memcpy(mapping.second, kModuleGUID, sizeof(MDGUID));
  mappings.push_back(mapping);
  ASSERT_TRUE(WriteMinidump(dumpfile.c_str(), child, &context, sizeof(context),
                            mappings, memory_list));

  // Read the minidump. Load the module list, and ensure that
  // the mmap'ed |memory| is listed with the given module name
  // and debug ID.
  Minidump minidump(dumpfile);
  ASSERT_TRUE(minidump.Read());

  MinidumpModuleList* module_list = minidump.GetModuleList();
  ASSERT_TRUE(module_list);
  const MinidumpModule* module =
    module_list->GetModuleForAddress(kMemoryAddress);
  ASSERT_TRUE(module);

  EXPECT_EQ(info.start_addr, module->base_address());
  EXPECT_EQ(info.size, module->size());
  EXPECT_EQ(kMemoryName, module->code_file());
  EXPECT_EQ(module_identifier, module->debug_identifier());

  close(fds[1]);
  IGNORE_EINTR(waitpid(child, nullptr, 0));
}

TEST(MinidumpWriterTest, DeletedBinary) {
  const string kNumberOfThreadsArgument = "1";
  const string helper_path(GetHelperBinary());
  if (helper_path.empty()) {
    FAIL() << "Couldn't find helper binary";
    exit(1);
  }

  // Copy binary to a temp file.
  AutoTempDir temp_dir;
  string binpath = temp_dir.path() + "/linux-dumper-unittest-helper";
  ASSERT_TRUE(CopyFile(helper_path, binpath))
      << "Failed to copy " << helper_path << " to " << binpath;
  ASSERT_EQ(0, chmod(binpath.c_str(), 0755));

  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  pid_t child_pid = fork();
  if (child_pid == 0) {
    // In child process.
    close(fds[0]);

    // Pass the pipe fd and the number of threads as arguments.
    char pipe_fd_string[8];
    sprintf(pipe_fd_string, "%d", fds[1]);
    execl(binpath.c_str(),
          binpath.c_str(),
          pipe_fd_string,
          kNumberOfThreadsArgument.c_str(),
          NULL);
  }
  close(fds[1]);
  // Wait for the child process to signal that it's ready.
  struct pollfd pfd;
  memset(&pfd, 0, sizeof(pfd));
  pfd.fd = fds[0];
  pfd.events = POLLIN | POLLERR;

  const int r = HANDLE_EINTR(poll(&pfd, 1, 1000));
  ASSERT_EQ(1, r);
  ASSERT_TRUE(pfd.revents & POLLIN);
  uint8_t junk;
  const int nr = HANDLE_EINTR(read(fds[0], &junk, sizeof(junk)));
  ASSERT_EQ(static_cast<ssize_t>(sizeof(junk)), nr);
  close(fds[0]);

  // Child is ready now.
  // Unlink the test binary.
  unlink(binpath.c_str());

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));

  string templ = temp_dir.path() + kMDWriterUnitTestFileName;
  // Set a non-zero tid to avoid tripping asserts.
  context.tid = child_pid;
  ASSERT_TRUE(WriteMinidump(templ.c_str(), child_pid, &context,
                            sizeof(context)));
  kill(child_pid, SIGKILL);

  struct stat st;
  ASSERT_EQ(0, stat(templ.c_str(), &st));
  ASSERT_GT(st.st_size, 0);

  Minidump minidump(templ);
  ASSERT_TRUE(minidump.Read());

  // Check that the main module filename is correct.
  MinidumpModuleList* module_list = minidump.GetModuleList();
  ASSERT_TRUE(module_list);
  const MinidumpModule* module = module_list->GetMainModule();
  EXPECT_STREQ(binpath.c_str(), module->code_file().c_str());
  // Check that the file ID is correct.
  FileID fileid(helper_path.c_str());
  PageAllocator allocator;
  wasteful_vector<uint8_t> identifier(&allocator, kDefaultBuildIdSize);
  EXPECT_TRUE(fileid.ElfFileIdentifier(identifier));
  string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier);
  string module_identifier(identifier_string);
  // Strip out dashes
  size_t pos;
  while ((pos = module_identifier.find('-')) != string::npos) {
    module_identifier.erase(pos, 1);
  }
  // And append a zero, because module IDs include an "age" field
  // which is always zero on Linux.
  module_identifier += "0";
  EXPECT_EQ(module_identifier, module->debug_identifier());

  IGNORE_EINTR(waitpid(child_pid, nullptr, 0));
}

// Test that an additional memory region can be added to the minidump.
TEST(MinidumpWriterTest, AdditionalMemory) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  // These are defined here so the parent can use them to check the
  // data from the minidump afterwards.
  const uint32_t kMemorySize = sysconf(_SC_PAGESIZE);

  // Get some heap memory.
  uint8_t* memory = new uint8_t[kMemorySize];
  const uintptr_t kMemoryAddress = reinterpret_cast<uintptr_t>(memory);
  ASSERT_TRUE(memory);

  // Stick some data into the memory so the contents can be verified.
  for (uint32_t i = 0; i < kMemorySize; ++i) {
    memory[i] = i % 255;
  }

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    HANDLE_EINTR(read(fds[0], &b, sizeof(b)));
    close(fds[0]);
    syscall(__NR_exit_group);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;

  // This needs a valid context for minidump writing to work, but getting
  // a useful one from the child is too much work, so just use one from
  // the parent since the child is just a forked copy anyway.
  ASSERT_EQ(0, getcontext(&context.context));
  context.tid = child;

  AutoTempDir temp_dir;
  string templ = temp_dir.path() + kMDWriterUnitTestFileName;
  unlink(templ.c_str());

  MappingList mappings;
  AppMemoryList memory_list;

  // Add the memory region to the list of memory to be included.
  AppMemory app_memory;
  app_memory.ptr = memory;
  app_memory.length = kMemorySize;
  memory_list.push_back(app_memory);
  ASSERT_TRUE(WriteMinidump(templ.c_str(), child, &context, sizeof(context),
                            mappings, memory_list));

  // Read the minidump. Ensure that the memory region is present
  Minidump minidump(templ);
  ASSERT_TRUE(minidump.Read());

  MinidumpMemoryList* dump_memory_list = minidump.GetMemoryList();
  ASSERT_TRUE(dump_memory_list);
  const MinidumpMemoryRegion* region =
    dump_memory_list->GetMemoryRegionForAddress(kMemoryAddress);
  ASSERT_TRUE(region);

  EXPECT_EQ(kMemoryAddress, region->GetBase());
  EXPECT_EQ(kMemorySize, region->GetSize());

  // Verify memory contents.
  EXPECT_EQ(0, memcmp(region->GetMemory(), memory, kMemorySize));

  delete[] memory;
  close(fds[1]);
  IGNORE_EINTR(waitpid(child, nullptr, 0));
}

// Test that an invalid thread stack pointer still results in a minidump.
TEST(MinidumpWriterTest, InvalidStackPointer) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    HANDLE_EINTR(read(fds[0], &b, sizeof(b)));
    close(fds[0]);
    syscall(__NR_exit_group);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;

  // This needs a valid context for minidump writing to work, but getting
  // a useful one from the child is too much work, so just use one from
  // the parent since the child is just a forked copy anyway.
  ASSERT_EQ(0, getcontext(&context.context));
  context.tid = child;

  // Fake the child's stack pointer for its crashing thread.  NOTE: This must
  // be an invalid memory address for the child process (stack or otherwise).
  // Try 1MB below the current stack.
  uintptr_t invalid_stack_pointer =
      reinterpret_cast<uintptr_t>(&context) - 1024*1024;
#if defined(__i386)
  context.context.uc_mcontext.gregs[REG_ESP] = invalid_stack_pointer;
#elif defined(__x86_64)
  context.context.uc_mcontext.gregs[REG_RSP] = invalid_stack_pointer;
#elif defined(__ARM_EABI__)
  context.context.uc_mcontext.arm_sp = invalid_stack_pointer;
#elif defined(__aarch64__)
  context.context.uc_mcontext.sp = invalid_stack_pointer;
#elif defined(__mips__)
  context.context.uc_mcontext.gregs[MD_CONTEXT_MIPS_REG_SP] =
      invalid_stack_pointer;
#else
# error "This code has not been ported to your platform yet."
#endif

  AutoTempDir temp_dir;
  string templ = temp_dir.path() + kMDWriterUnitTestFileName;
  // NOTE: In previous versions of Breakpad, WriteMinidump() would fail if
  // presented with an invalid stack pointer.
  ASSERT_TRUE(WriteMinidump(templ.c_str(), child, &context, sizeof(context)));

  // Read the minidump. Ensure that the memory region is present
  Minidump minidump(templ);
  ASSERT_TRUE(minidump.Read());

  // TODO(ted.mielczarek,mkrebs): Enable this part of the test once
  // https://breakpad.appspot.com/413002/ is committed.
#if 0
  // Make sure there's a thread without a stack.  NOTE: It's okay if
  // GetThreadList() shows the error: "ERROR: MinidumpThread has a memory
  // region problem".
  MinidumpThreadList* dump_thread_list = minidump.GetThreadList();
  ASSERT_TRUE(dump_thread_list);
  bool found_empty_stack = false;
  for (int i = 0; i < dump_thread_list->thread_count(); i++) {
    MinidumpThread* thread = dump_thread_list->GetThreadAtIndex(i);
    ASSERT_TRUE(thread->thread() != NULL);
    // When the stack size is zero bytes, GetMemory() returns NULL.
    if (thread->GetMemory() == NULL) {
      found_empty_stack = true;
      break;
    }
  }
  // NOTE: If you fail this, first make sure that "invalid_stack_pointer"
  // above is indeed set to an invalid address.
  ASSERT_TRUE(found_empty_stack);
#endif

  close(fds[1]);
  IGNORE_EINTR(waitpid(child, nullptr, 0));
}

// Test that limiting the size of the minidump works.
TEST(MinidumpWriterTest, MinidumpSizeLimit) {
  static const int kNumberOfThreadsInHelperProgram = 40;

  char number_of_threads_arg[3];
  sprintf(number_of_threads_arg, "%d", kNumberOfThreadsInHelperProgram);

  string helper_path(GetHelperBinary());
  if (helper_path.empty()) {
    FAIL() << "Couldn't find helper binary";
    exit(1);
  }

  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  pid_t child_pid = fork();
  if (child_pid == 0) {
    // In child process.
    close(fds[0]);

    // Pass the pipe fd and the number of threads as arguments.
    char pipe_fd_string[8];
    sprintf(pipe_fd_string, "%d", fds[1]);
    execl(helper_path.c_str(),
          helper_path.c_str(),
          pipe_fd_string,
          number_of_threads_arg,
          NULL);
  }
  close(fds[1]);

  // Wait for all child threads to indicate that they have started
  for (int threads = 0; threads < kNumberOfThreadsInHelperProgram; threads++) {
    struct pollfd pfd;
    memset(&pfd, 0, sizeof(pfd));
    pfd.fd = fds[0];
    pfd.events = POLLIN | POLLERR;

    const int r = HANDLE_EINTR(poll(&pfd, 1, 1000));
    ASSERT_EQ(1, r);
    ASSERT_TRUE(pfd.revents & POLLIN);
    uint8_t junk;
    ASSERT_EQ(read(fds[0], &junk, sizeof(junk)),
              static_cast<ssize_t>(sizeof(junk)));
  }
  close(fds[0]);

  // There is a race here because we may stop a child thread before
  // it is actually running the busy loop. Empirically this sleep
  // is sufficient to avoid the race.
  usleep(100000);

  // Child and its threads are ready now.


  off_t normal_file_size;
  int total_normal_stack_size = 0;
  AutoTempDir temp_dir;

  // First, write a minidump with no size limit.
  {
    string normal_dump = temp_dir.path() +
        "/minidump-writer-unittest.dmp";
    ASSERT_TRUE(WriteMinidump(normal_dump.c_str(), -1,
                              child_pid, NULL, 0,
                              MappingList(), AppMemoryList()));
    struct stat st;
    ASSERT_EQ(0, stat(normal_dump.c_str(), &st));
    ASSERT_GT(st.st_size, 0);
    normal_file_size = st.st_size;

    Minidump minidump(normal_dump);
    ASSERT_TRUE(minidump.Read());
    MinidumpThreadList* dump_thread_list = minidump.GetThreadList();
    ASSERT_TRUE(dump_thread_list);
    for (unsigned int i = 0; i < dump_thread_list->thread_count(); i++) {
      MinidumpThread* thread = dump_thread_list->GetThreadAtIndex(i);
      ASSERT_TRUE(thread->thread() != NULL);
      // When the stack size is zero bytes, GetMemory() returns NULL.
      MinidumpMemoryRegion* memory = thread->GetMemory();
      ASSERT_TRUE(memory != NULL);
      total_normal_stack_size += memory->GetSize();
    }
  }

  // Second, write a minidump with a size limit big enough to not trigger
  // anything.
  {
    // Set size limit arbitrarily 1MB larger than the normal file size -- such
    // that the limiting code will not kick in.
    const off_t minidump_size_limit = normal_file_size + 1024*1024;

    string same_dump = temp_dir.path() +
        "/minidump-writer-unittest-same.dmp";
    ASSERT_TRUE(WriteMinidump(same_dump.c_str(), minidump_size_limit,
                              child_pid, NULL, 0,
                              MappingList(), AppMemoryList()));
    struct stat st;
    ASSERT_EQ(0, stat(same_dump.c_str(), &st));
    // Make sure limiting wasn't actually triggered.  NOTE: If you fail this,
    // first make sure that "minidump_size_limit" above is indeed set to a
    // large enough value -- the limit-checking code in minidump_writer.cc
    // does just a rough estimate.
    ASSERT_EQ(normal_file_size, st.st_size);
  }

  // Third, write a minidump with a size limit small enough to be triggered.
  {
    // Set size limit to some arbitrary amount, such that the limiting code
    // will kick in.  The equation used to set this value was determined by
    // simply reversing the size-limit logic a little bit in order to pick a
    // size we know will trigger it.  The definition of
    // kLimitAverageThreadStackLength here was copied from class
    // MinidumpWriter in minidump_writer.cc.
    static const unsigned kLimitAverageThreadStackLength = 8 * 1024;
    off_t minidump_size_limit = kNumberOfThreadsInHelperProgram *
        kLimitAverageThreadStackLength;
    // If, in reality, each of the threads' stack is *smaller* than
    // kLimitAverageThreadStackLength, the normal file size could very well be
    // smaller than the arbitrary limit that was just set.  In that case,
    // either of these numbers should trigger the size-limiting code, but we
    // might as well pick the smallest.
    if (normal_file_size < minidump_size_limit)
      minidump_size_limit = normal_file_size;

    string limit_dump = temp_dir.path() +
        "/minidump-writer-unittest-limit.dmp";
    ASSERT_TRUE(WriteMinidump(limit_dump.c_str(), minidump_size_limit,
                              child_pid, NULL, 0,
                              MappingList(), AppMemoryList()));
    struct stat st;
    ASSERT_EQ(0, stat(limit_dump.c_str(), &st));
    ASSERT_GT(st.st_size, 0);
    // Make sure the file size is at least smaller than the original.  If this
    // fails because it's the same size, then the size-limit logic didn't kick
    // in like it was supposed to.
    EXPECT_LT(st.st_size, normal_file_size);

    Minidump minidump(limit_dump);
    ASSERT_TRUE(minidump.Read());
    MinidumpThreadList* dump_thread_list = minidump.GetThreadList();
    ASSERT_TRUE(dump_thread_list);
    int total_limit_stack_size = 0;
    for (unsigned int i = 0; i < dump_thread_list->thread_count(); i++) {
      MinidumpThread* thread = dump_thread_list->GetThreadAtIndex(i);
      ASSERT_TRUE(thread->thread() != NULL);
      // When the stack size is zero bytes, GetMemory() returns NULL.
      MinidumpMemoryRegion* memory = thread->GetMemory();
      ASSERT_TRUE(memory != NULL);
      total_limit_stack_size += memory->GetSize();
    }

    // Make sure stack size shrunk by at least 1KB per extra thread.  The
    // definition of kLimitBaseThreadCount here was copied from class
    // MinidumpWriter in minidump_writer.cc.
    // Note: The 1KB is arbitrary, and assumes that the thread stacks are big
    // enough to shrink by that much.  For example, if each thread stack was
    // originally only 2KB, the current size-limit logic wouldn't actually
    // shrink them because that's the size to which it tries to shrink.  If
    // you fail this part of the test due to something like that, the test
    // logic should probably be improved to account for your situation.
    const unsigned kLimitBaseThreadCount = 20;
    const unsigned kMinPerExtraThreadStackReduction = 1024;
    const int min_expected_reduction = (kNumberOfThreadsInHelperProgram -
        kLimitBaseThreadCount) * kMinPerExtraThreadStackReduction;
    EXPECT_LT(total_limit_stack_size,
              total_normal_stack_size - min_expected_reduction);
  }

  // Kill the helper program.
  kill(child_pid, SIGKILL);
  IGNORE_EINTR(waitpid(child_pid, nullptr, 0));
}

}  // namespace
