// Copyright (c) 2010 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 <pthread.h>
#include <stdint.h>
#include <unistd.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/wait.h>
#if defined(__mips__)
#include <sys/cachectl.h>
#endif

#include <string>

#include "breakpad_googletest_includes.h"
#include "client/linux/handler/exception_handler.h"
#include "client/linux/minidump_writer/minidump_writer.h"
#include "common/linux/eintr_wrapper.h"
#include "common/linux/ignore_ret.h"
#include "common/linux/linux_libc_support.h"
#include "common/tests/auto_tempdir.h"
#include "common/using_std_string.h"
#include "third_party/lss/linux_syscall_support.h"
#include "google_breakpad/processor/minidump.h"

using namespace google_breakpad;

namespace {

// Flush the instruction cache for a given memory range.
// Only required on ARM and mips.
void FlushInstructionCache(const char* memory, uint32_t memory_size) {
#if defined(__arm__)
  long begin = reinterpret_cast<long>(memory);
  long end = begin + static_cast<long>(memory_size);
# if defined(__ANDROID__)
  // Provided by Android's <unistd.h>
  cacheflush(begin, end, 0);
# elif defined(__linux__)
  // GLibc/ARM doesn't provide a wrapper for it, do a direct syscall.
#  ifndef __ARM_NR_cacheflush
#  define __ARM_NR_cacheflush 0xf0002
#  endif
  syscall(__ARM_NR_cacheflush, begin, end, 0);
# else
#   error "Your operating system is not supported yet"
# endif
#elif defined(__mips__)
# if defined(__ANDROID__)
  // Provided by Android's <unistd.h>
  long begin = reinterpret_cast<long>(memory);
  long end = begin + static_cast<long>(memory_size);
#if _MIPS_SIM == _ABIO32
  cacheflush(begin, end, 0);
#else
  syscall(__NR_cacheflush, begin, end, ICACHE);
#endif
# elif defined(__linux__)
  // See http://www.linux-mips.org/wiki/Cacheflush_Syscall.
  cacheflush(const_cast<char*>(memory), memory_size, ICACHE);
# else
#   error "Your operating system is not supported yet"
# endif
#endif
}

void sigchld_handler(int signo) { }

int CreateTMPFile(const string& dir, string* path) {
  string file = dir + "/exception-handler-unittest.XXXXXX";
  const char* c_file = file.c_str();
  // Copy that string, mkstemp needs a C string it can modify.
  char* c_path = strdup(c_file);
  const int fd = mkstemp(c_path);
  if (fd >= 0)
    *path = c_path;
  free(c_path);
  return fd;
}

class ExceptionHandlerTest : public ::testing::Test {
 protected:
  void SetUp() {
    // We need to be able to wait for children, so SIGCHLD cannot be SIG_IGN.
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = sigchld_handler;
    ASSERT_NE(sigaction(SIGCHLD, &sa, &old_action), -1);
  }

  void TearDown() {
    sigaction(SIGCHLD, &old_action, NULL);
  }

  struct sigaction old_action;
};


void WaitForProcessToTerminate(pid_t process_id, int expected_status) {
  int status;
  ASSERT_NE(HANDLE_EINTR(waitpid(process_id, &status, 0)), -1);
  ASSERT_TRUE(WIFSIGNALED(status));
  ASSERT_EQ(expected_status, WTERMSIG(status));
}

// Reads the minidump path sent over the pipe |fd| and sets it in |path|.
void ReadMinidumpPathFromPipe(int fd, string* path) {
  struct pollfd pfd;
  memset(&pfd, 0, sizeof(pfd));
  pfd.fd = fd;
  pfd.events = POLLIN | POLLERR;

  const int r = HANDLE_EINTR(poll(&pfd, 1, 0));
  ASSERT_EQ(1, r);
  ASSERT_TRUE(pfd.revents & POLLIN);

  int32_t len;
  ASSERT_EQ(static_cast<ssize_t>(sizeof(len)), read(fd, &len, sizeof(len)));
  ASSERT_LT(len, 2048);
  char* filename = static_cast<char*>(malloc(len + 1));
  ASSERT_EQ(len, read(fd, filename, len));
  filename[len] = 0;
  close(fd);
  *path = filename;
  free(filename);
}

}  // namespace

TEST(ExceptionHandlerTest, SimpleWithPath) {
  AutoTempDir temp_dir;
  ExceptionHandler handler(
      MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1);
  EXPECT_EQ(temp_dir.path(), handler.minidump_descriptor().directory());
  string temp_subdir = temp_dir.path() + "/subdir";
  handler.set_minidump_descriptor(MinidumpDescriptor(temp_subdir));
  EXPECT_EQ(temp_subdir, handler.minidump_descriptor().directory());
}

TEST(ExceptionHandlerTest, SimpleWithFD) {
  AutoTempDir temp_dir;
  string path;
  const int fd = CreateTMPFile(temp_dir.path(), &path);
  ExceptionHandler handler(MinidumpDescriptor(fd), NULL, NULL, NULL, true, -1);
  close(fd);
}

static bool DoneCallback(const MinidumpDescriptor& descriptor,
                         void* context,
                         bool succeeded) {
  if (!succeeded)
    return false;

  if (!descriptor.IsFD()) {
    int fd = reinterpret_cast<intptr_t>(context);
    uint32_t len = 0;
    len = my_strlen(descriptor.path());
    IGNORE_RET(HANDLE_EINTR(sys_write(fd, &len, sizeof(len))));
    IGNORE_RET(HANDLE_EINTR(sys_write(fd, descriptor.path(), len)));
  }
  return true;
}

#ifndef ADDRESS_SANITIZER

// This is a replacement for "*reinterpret_cast<volatile int*>(NULL) = 0;"
// It is needed because GCC is allowed to assume that the program will
// not execute any undefined behavior (UB) operation. Further, when GCC
// observes that UB statement is reached, it can assume that all statements
// leading to the UB one are never executed either, and can completely
// optimize them out. In the case of ExceptionHandlerTest::ExternalDumper,
// GCC-4.9 optimized out the entire set up of ExceptionHandler, causing
// test failure.
volatile int *p_null;  // external linkage, so GCC can't tell that it
                       // remains NULL. Volatile just for a good measure.
static void DoNullPointerDereference() {
  *p_null = 1;
}

void ChildCrash(bool use_fd) {
  AutoTempDir temp_dir;
  int fds[2] = {0};
  int minidump_fd = -1;
  string minidump_path;
  if (use_fd) {
    minidump_fd = CreateTMPFile(temp_dir.path(), &minidump_path);
  } else {
    ASSERT_NE(pipe(fds), -1);
  }

  const pid_t child = fork();
  if (child == 0) {
    {
      google_breakpad::scoped_ptr<ExceptionHandler> handler;
      if (use_fd) {
        handler.reset(new ExceptionHandler(MinidumpDescriptor(minidump_fd),
                                           NULL, NULL, NULL, true, -1));
      } else {
        close(fds[0]);  // Close the reading end.
        void* fd_param = reinterpret_cast<void*>(fds[1]);
        handler.reset(new ExceptionHandler(MinidumpDescriptor(temp_dir.path()),
                                           NULL, DoneCallback, fd_param,
                                           true, -1));
      }
      // Crash with the exception handler in scope.
      DoNullPointerDereference();
    }
  }
  if (!use_fd)
    close(fds[1]);  // Close the writting end.

  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV));

  if (!use_fd)
    ASSERT_NO_FATAL_FAILURE(ReadMinidumpPathFromPipe(fds[0], &minidump_path));

  struct stat st;
  ASSERT_EQ(0, stat(minidump_path.c_str(), &st));
  ASSERT_GT(st.st_size, 0);
  unlink(minidump_path.c_str());
}

TEST(ExceptionHandlerTest, ChildCrashWithPath) {
  ASSERT_NO_FATAL_FAILURE(ChildCrash(false));
}

TEST(ExceptionHandlerTest, ChildCrashWithFD) {
  ASSERT_NO_FATAL_FAILURE(ChildCrash(true));
}

#if !defined(__ANDROID_API__) || __ANDROID_API__ >= __ANDROID_API_N__
static void* SleepFunction(void* unused) {
  while (true) usleep(1000000);
  return NULL;
}

static void* CrashFunction(void* b_ptr) {
  pthread_barrier_t* b = reinterpret_cast<pthread_barrier_t*>(b_ptr);
  pthread_barrier_wait(b);
  DoNullPointerDereference();
  return NULL;
}

// Tests that concurrent crashes do not enter a loop by alternately triggering
// the signal handler.
TEST(ExceptionHandlerTest, ParallelChildCrashesDontHang) {
  AutoTempDir temp_dir;
  const pid_t child = fork();
  if (child == 0) {
    google_breakpad::scoped_ptr<ExceptionHandler> handler(
      new ExceptionHandler(MinidumpDescriptor(temp_dir.path()), NULL, NULL,
                            NULL, true, -1));

    // We start a number of threads to make sure handling the signal takes
    // enough time for the second thread to enter the signal handler.
    int num_sleep_threads = 100;
    google_breakpad::scoped_array<pthread_t> sleep_threads(
        new pthread_t[num_sleep_threads]);
    for (int i = 0; i < num_sleep_threads; ++i) {
      ASSERT_EQ(0, pthread_create(&sleep_threads[i], NULL, SleepFunction,
                                  NULL));
    }

    int num_crash_threads = 2;
    google_breakpad::scoped_array<pthread_t> crash_threads(
        new pthread_t[num_crash_threads]);
    // Barrier to synchronize crashing both threads at the same time.
    pthread_barrier_t b;
    ASSERT_EQ(0, pthread_barrier_init(&b, NULL, num_crash_threads + 1));
    for (int i = 0; i < num_crash_threads; ++i) {
      ASSERT_EQ(0, pthread_create(&crash_threads[i], NULL, CrashFunction, &b));
    }
    pthread_barrier_wait(&b);
    for (int i = 0; i < num_crash_threads; ++i) {
      ASSERT_EQ(0, pthread_join(crash_threads[i], NULL));
    }
  }

  // Wait a while until the child should have crashed.
  usleep(1000000);
  // Kill the child if it is still running.
  kill(child, SIGKILL);

  // If the child process terminated by itself, it will have returned SIGSEGV.
  // If however it got stuck in a loop, it will have been killed by the
  // SIGKILL.
  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV));
}
#endif  // !defined(__ANDROID_API__) || __ANDROID_API__ >= __ANDROID_API_N__

static bool DoneCallbackReturnFalse(const MinidumpDescriptor& descriptor,
                                    void* context,
                                    bool succeeded) {
  return false;
}

static bool DoneCallbackReturnTrue(const MinidumpDescriptor& descriptor,
                                   void* context,
                                   bool succeeded) {
  return true;
}

static bool DoneCallbackRaiseSIGKILL(const MinidumpDescriptor& descriptor,
                                     void* context,
                                     bool succeeded) {
  raise(SIGKILL);
  return true;
}

static bool FilterCallbackReturnFalse(void* context) {
  return false;
}

static bool FilterCallbackReturnTrue(void* context) {
  return true;
}

// SIGKILL cannot be blocked and a handler cannot be installed for it. In the
// following tests, if the child dies with signal SIGKILL, then the signal was
// redelivered to this handler. If the child dies with SIGSEGV then it wasn't.
static void RaiseSIGKILL(int sig) {
  raise(SIGKILL);
}

static bool InstallRaiseSIGKILL() {
  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = RaiseSIGKILL;
  return sigaction(SIGSEGV, &sa, NULL) != -1;
}

static void CrashWithCallbacks(ExceptionHandler::FilterCallback filter,
                               ExceptionHandler::MinidumpCallback done,
                               string path) {
  ExceptionHandler handler(
      MinidumpDescriptor(path), filter, done, NULL, true, -1);
  // Crash with the exception handler in scope.
  DoNullPointerDereference();
}

TEST(ExceptionHandlerTest, RedeliveryOnFilterCallbackFalse) {
  AutoTempDir temp_dir;

  const pid_t child = fork();
  if (child == 0) {
    ASSERT_TRUE(InstallRaiseSIGKILL());
    CrashWithCallbacks(FilterCallbackReturnFalse, NULL, temp_dir.path());
  }

  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL));
}

TEST(ExceptionHandlerTest, RedeliveryOnDoneCallbackFalse) {
  AutoTempDir temp_dir;

  const pid_t child = fork();
  if (child == 0) {
    ASSERT_TRUE(InstallRaiseSIGKILL());
    CrashWithCallbacks(NULL, DoneCallbackReturnFalse, temp_dir.path());
  }

  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL));
}

TEST(ExceptionHandlerTest, NoRedeliveryOnDoneCallbackTrue) {
  AutoTempDir temp_dir;

  const pid_t child = fork();
  if (child == 0) {
    ASSERT_TRUE(InstallRaiseSIGKILL());
    CrashWithCallbacks(NULL, DoneCallbackReturnTrue, temp_dir.path());
  }

  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV));
}

TEST(ExceptionHandlerTest, NoRedeliveryOnFilterCallbackTrue) {
  AutoTempDir temp_dir;

  const pid_t child = fork();
  if (child == 0) {
    ASSERT_TRUE(InstallRaiseSIGKILL());
    CrashWithCallbacks(FilterCallbackReturnTrue, NULL, temp_dir.path());
  }

  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV));
}

TEST(ExceptionHandlerTest, RedeliveryToDefaultHandler) {
  AutoTempDir temp_dir;

  const pid_t child = fork();
  if (child == 0) {
    // Custom signal handlers, which may have been installed by a test launcher,
    // are undesirable in this child.
    signal(SIGSEGV, SIG_DFL);

    CrashWithCallbacks(FilterCallbackReturnFalse, NULL, temp_dir.path());
  }

  // As RaiseSIGKILL wasn't installed, the redelivery should just kill the child
  // with SIGSEGV.
  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV));
}

// Check that saving and restoring the signal handler with 'signal'
// instead of 'sigaction' doesn't make the Breakpad signal handler
// crash. See comments in ExceptionHandler::SignalHandler for full
// details.
TEST(ExceptionHandlerTest, RedeliveryOnBadSignalHandlerFlag) {
  AutoTempDir temp_dir;
  const pid_t child = fork();
  if (child == 0) {
    // Install the RaiseSIGKILL handler for SIGSEGV.
    ASSERT_TRUE(InstallRaiseSIGKILL());

    // Create a new exception handler, this installs a new SIGSEGV
    // handler, after saving the old one.
    ExceptionHandler handler(
        MinidumpDescriptor(temp_dir.path()), NULL,
        DoneCallbackReturnFalse, NULL, true, -1);

    // Install the default SIGSEGV handler, saving the current one.
    // Then re-install the current one with 'signal', this loses the
    // SA_SIGINFO flag associated with the Breakpad handler.
    sighandler_t old_handler = signal(SIGSEGV, SIG_DFL);
    ASSERT_NE(reinterpret_cast<void*>(old_handler),
              reinterpret_cast<void*>(SIG_ERR));
    ASSERT_NE(reinterpret_cast<void*>(signal(SIGSEGV, old_handler)),
              reinterpret_cast<void*>(SIG_ERR));

    // Crash with the exception handler in scope.
    DoNullPointerDereference();
  }
  // SIGKILL means Breakpad's signal handler didn't crash.
  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL));
}

TEST(ExceptionHandlerTest, StackedHandlersDeliveredToTop) {
  AutoTempDir temp_dir;

  const pid_t child = fork();
  if (child == 0) {
    ExceptionHandler bottom(MinidumpDescriptor(temp_dir.path()),
                            NULL,
                            NULL,
                            NULL,
                            true,
                            -1);
    CrashWithCallbacks(NULL, DoneCallbackRaiseSIGKILL, temp_dir.path());
  }
  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL));
}

TEST(ExceptionHandlerTest, StackedHandlersNotDeliveredToBottom) {
  AutoTempDir temp_dir;

  const pid_t child = fork();
  if (child == 0) {
    ExceptionHandler bottom(MinidumpDescriptor(temp_dir.path()),
                            NULL,
                            DoneCallbackRaiseSIGKILL,
                            NULL,
                            true,
                            -1);
    CrashWithCallbacks(NULL, NULL, temp_dir.path());
  }
  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV));
}

TEST(ExceptionHandlerTest, StackedHandlersFilteredToBottom) {
  AutoTempDir temp_dir;

  const pid_t child = fork();
  if (child == 0) {
    ExceptionHandler bottom(MinidumpDescriptor(temp_dir.path()),
                            NULL,
                            DoneCallbackRaiseSIGKILL,
                            NULL,
                            true,
                            -1);
    CrashWithCallbacks(FilterCallbackReturnFalse, NULL, temp_dir.path());
  }
  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL));
}

TEST(ExceptionHandlerTest, StackedHandlersUnhandledToBottom) {
  AutoTempDir temp_dir;

  const pid_t child = fork();
  if (child == 0) {
    ExceptionHandler bottom(MinidumpDescriptor(temp_dir.path()),
                            NULL,
                            DoneCallbackRaiseSIGKILL,
                            NULL,
                            true,
                            -1);
    CrashWithCallbacks(NULL, DoneCallbackReturnFalse, temp_dir.path());
  }
  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL));
}

namespace {
const int kSimpleFirstChanceReturnStatus = 42;
bool SimpleFirstChanceHandler(int, siginfo_t*, void*) {
  _exit(kSimpleFirstChanceReturnStatus);
}
}

TEST(ExceptionHandlerTest, FirstChanceHandlerRuns) {
  AutoTempDir temp_dir;

  const pid_t child = fork();
  if (child == 0) {
    ExceptionHandler handler(
        MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1);
    google_breakpad::SetFirstChanceExceptionHandler(SimpleFirstChanceHandler);
    DoNullPointerDereference();
  }
  int status;
  ASSERT_NE(HANDLE_EINTR(waitpid(child, &status, 0)), -1);
  ASSERT_TRUE(WIFEXITED(status));
  ASSERT_EQ(kSimpleFirstChanceReturnStatus, WEXITSTATUS(status));
}

#endif  // !ADDRESS_SANITIZER

const unsigned char kIllegalInstruction[] = {
#if defined(__mips__)
  // mfc2 zero,Impl - usually illegal in userspace.
  0x48, 0x00, 0x00, 0x48
#else
  // This crashes with SIGILL on x86/x86-64/arm.
  0xff, 0xff, 0xff, 0xff
#endif
};

// Test that memory around the instruction pointer is written
// to the dump as a MinidumpMemoryRegion.
TEST(ExceptionHandlerTest, InstructionPointerMemory) {
  AutoTempDir temp_dir;
  int fds[2];
  ASSERT_NE(pipe(fds), -1);

  // These are defined here so the parent can use them to check the
  // data from the minidump afterwards.
  const uint32_t kMemorySize = 256;  // bytes
  const int kOffset = kMemorySize / 2;

  const pid_t child = fork();
  if (child == 0) {
    close(fds[0]);
    ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL,
                             DoneCallback, reinterpret_cast<void*>(fds[1]),
                             true, -1);
    // Get some executable memory.
    char* memory =
      reinterpret_cast<char*>(mmap(NULL,
                                   kMemorySize,
                                   PROT_READ | PROT_WRITE | PROT_EXEC,
                                   MAP_PRIVATE | MAP_ANON,
                                   -1,
                                   0));
    if (!memory)
      exit(0);

    // Write some instructions that will crash. Put them in the middle
    // of the block of memory, because the minidump should contain 128
    // bytes on either side of the instruction pointer.
    memcpy(memory + kOffset, kIllegalInstruction, sizeof(kIllegalInstruction));
    FlushInstructionCache(memory, kMemorySize);

    // Now execute the instructions, which should crash.
    typedef void (*void_function)(void);
    void_function memory_function =
        reinterpret_cast<void_function>(memory + kOffset);
    memory_function();
  }
  close(fds[1]);

  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGILL));

  string minidump_path;
  ASSERT_NO_FATAL_FAILURE(ReadMinidumpPathFromPipe(fds[0], &minidump_path));

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

  // Read the minidump. Locate the exception record and the
  // memory list, and then ensure that there is a memory region
  // in the memory list that covers the instruction pointer from
  // the exception record.
  Minidump minidump(minidump_path);
  ASSERT_TRUE(minidump.Read());

  MinidumpException* exception = minidump.GetException();
  MinidumpMemoryList* memory_list = minidump.GetMemoryList();
  ASSERT_TRUE(exception);
  ASSERT_TRUE(memory_list);
  ASSERT_LT(0U, memory_list->region_count());

  MinidumpContext* context = exception->GetContext();
  ASSERT_TRUE(context);

  uint64_t instruction_pointer;
  ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));

  MinidumpMemoryRegion* region =
      memory_list->GetMemoryRegionForAddress(instruction_pointer);
  ASSERT_TRUE(region);

  EXPECT_EQ(kMemorySize, region->GetSize());
  const uint8_t* bytes = region->GetMemory();
  ASSERT_TRUE(bytes);

  uint8_t prefix_bytes[kOffset];
  uint8_t suffix_bytes[kMemorySize - kOffset - sizeof(kIllegalInstruction)];
  memset(prefix_bytes, 0, sizeof(prefix_bytes));
  memset(suffix_bytes, 0, sizeof(suffix_bytes));
  EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0);
  EXPECT_TRUE(memcmp(bytes + kOffset, kIllegalInstruction, 
                     sizeof(kIllegalInstruction)) == 0);
  EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(kIllegalInstruction),
                     suffix_bytes, sizeof(suffix_bytes)) == 0);

  unlink(minidump_path.c_str());
}

// Test that the memory region around the instruction pointer is
// bounded correctly on the low end.
TEST(ExceptionHandlerTest, InstructionPointerMemoryMinBound) {
  AutoTempDir temp_dir;
  int fds[2];
  ASSERT_NE(pipe(fds), -1);

  // These are defined here so the parent can use them to check the
  // data from the minidump afterwards.
  const uint32_t kMemorySize = 256;  // bytes
  const int kOffset = 0;

  const pid_t child = fork();
  if (child == 0) {
    close(fds[0]);
    ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL,
                             DoneCallback, reinterpret_cast<void*>(fds[1]),
                             true, -1);
    // Get some executable memory.
    char* memory =
        reinterpret_cast<char*>(mmap(NULL,
                                     kMemorySize,
                                     PROT_READ | PROT_WRITE | PROT_EXEC,
                                     MAP_PRIVATE | MAP_ANON,
                                     -1,
                                     0));
    if (!memory)
      exit(0);

    // Write some instructions that will crash. Put them in the middle
    // of the block of memory, because the minidump should contain 128
    // bytes on either side of the instruction pointer.
    memcpy(memory + kOffset, kIllegalInstruction, sizeof(kIllegalInstruction));
    FlushInstructionCache(memory, kMemorySize);

    // Now execute the instructions, which should crash.
    typedef void (*void_function)(void);
    void_function memory_function =
        reinterpret_cast<void_function>(memory + kOffset);
    memory_function();
  }
  close(fds[1]);

  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGILL));

  string minidump_path;
  ASSERT_NO_FATAL_FAILURE(ReadMinidumpPathFromPipe(fds[0], &minidump_path));

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

  // Read the minidump. Locate the exception record and the
  // memory list, and then ensure that there is a memory region
  // in the memory list that covers the instruction pointer from
  // the exception record.
  Minidump minidump(minidump_path);
  ASSERT_TRUE(minidump.Read());

  MinidumpException* exception = minidump.GetException();
  MinidumpMemoryList* memory_list = minidump.GetMemoryList();
  ASSERT_TRUE(exception);
  ASSERT_TRUE(memory_list);
  ASSERT_LT(0U, memory_list->region_count());

  MinidumpContext* context = exception->GetContext();
  ASSERT_TRUE(context);

  uint64_t instruction_pointer;
  ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));

  MinidumpMemoryRegion* region =
      memory_list->GetMemoryRegionForAddress(instruction_pointer);
  ASSERT_TRUE(region);

  EXPECT_EQ(kMemorySize / 2, region->GetSize());
  const uint8_t* bytes = region->GetMemory();
  ASSERT_TRUE(bytes);

  uint8_t suffix_bytes[kMemorySize / 2 - sizeof(kIllegalInstruction)];
  memset(suffix_bytes, 0, sizeof(suffix_bytes));
  EXPECT_TRUE(memcmp(bytes + kOffset, kIllegalInstruction, 
                     sizeof(kIllegalInstruction)) == 0);
  EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(kIllegalInstruction),
                     suffix_bytes, sizeof(suffix_bytes)) == 0);
  unlink(minidump_path.c_str());
}

// Test that the memory region around the instruction pointer is
// bounded correctly on the high end.
TEST(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) {
  AutoTempDir temp_dir;
  int fds[2];
  ASSERT_NE(pipe(fds), -1);

  // These are defined here so the parent can use them to check the
  // data from the minidump afterwards.
  // Use 4k here because the OS will hand out a single page even
  // if a smaller size is requested, and this test wants to
  // test the upper bound of the memory range.
  const uint32_t kMemorySize = 4096;  // bytes
  const int kOffset = kMemorySize - sizeof(kIllegalInstruction);

  const pid_t child = fork();
  if (child == 0) {
    close(fds[0]);
    ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL,
                             DoneCallback, reinterpret_cast<void*>(fds[1]),
                             true, -1);
    // Get some executable memory.
    char* memory =
        reinterpret_cast<char*>(mmap(NULL,
                                     kMemorySize,
                                     PROT_READ | PROT_WRITE | PROT_EXEC,
                                     MAP_PRIVATE | MAP_ANON,
                                     -1,
                                     0));
    if (!memory)
      exit(0);

    // Write some instructions that will crash. Put them in the middle
    // of the block of memory, because the minidump should contain 128
    // bytes on either side of the instruction pointer.
    memcpy(memory + kOffset, kIllegalInstruction, sizeof(kIllegalInstruction));
    FlushInstructionCache(memory, kMemorySize);

    // Now execute the instructions, which should crash.
    typedef void (*void_function)(void);
    void_function memory_function =
        reinterpret_cast<void_function>(memory + kOffset);
    memory_function();
  }
  close(fds[1]);

  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGILL));

  string minidump_path;
  ASSERT_NO_FATAL_FAILURE(ReadMinidumpPathFromPipe(fds[0], &minidump_path));

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

  // Read the minidump. Locate the exception record and the memory list, and
  // then ensure that there is a memory region in the memory list that covers
  // the instruction pointer from the exception record.
  Minidump minidump(minidump_path);
  ASSERT_TRUE(minidump.Read());

  MinidumpException* exception = minidump.GetException();
  MinidumpMemoryList* memory_list = minidump.GetMemoryList();
  ASSERT_TRUE(exception);
  ASSERT_TRUE(memory_list);
  ASSERT_LT(0U, memory_list->region_count());

  MinidumpContext* context = exception->GetContext();
  ASSERT_TRUE(context);

  uint64_t instruction_pointer;
  ASSERT_TRUE(context->GetInstructionPointer(&instruction_pointer));

  MinidumpMemoryRegion* region =
      memory_list->GetMemoryRegionForAddress(instruction_pointer);
  ASSERT_TRUE(region);

  const size_t kPrefixSize = 128;  // bytes
  EXPECT_EQ(kPrefixSize + sizeof(kIllegalInstruction), region->GetSize());
  const uint8_t* bytes = region->GetMemory();
  ASSERT_TRUE(bytes);

  uint8_t prefix_bytes[kPrefixSize];
  memset(prefix_bytes, 0, sizeof(prefix_bytes));
  EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0);
  EXPECT_TRUE(memcmp(bytes + kPrefixSize,
                     kIllegalInstruction, sizeof(kIllegalInstruction)) == 0);

  unlink(minidump_path.c_str());
}

#ifndef ADDRESS_SANITIZER

// Ensure that an extra memory block doesn't get added when the instruction
// pointer is not in mapped memory.
TEST(ExceptionHandlerTest, InstructionPointerMemoryNullPointer) {
  AutoTempDir temp_dir;
  int fds[2];
  ASSERT_NE(pipe(fds), -1);

  const pid_t child = fork();
  if (child == 0) {
    close(fds[0]);
    ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL,
                             DoneCallback, reinterpret_cast<void*>(fds[1]),
                             true, -1);
    // Try calling a NULL pointer.
    typedef void (*void_function)(void);
    // Volatile markings are needed to keep Clang from generating invalid
    // opcodes.  See http://crbug.com/498354 for details.
    volatile void_function memory_function =
      reinterpret_cast<void_function>(NULL);
    memory_function();
    // not reached
    exit(1);
  }
  close(fds[1]);

  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV));

  string minidump_path;
  ASSERT_NO_FATAL_FAILURE(ReadMinidumpPathFromPipe(fds[0], &minidump_path));

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

  // Read the minidump. Locate the exception record and the
  // memory list, and then ensure that there is no memory region
  // in the memory list that covers the instruction pointer from
  // the exception record.
  Minidump minidump(minidump_path);
  ASSERT_TRUE(minidump.Read());

  MinidumpException* exception = minidump.GetException();
  ASSERT_TRUE(exception);

  MinidumpContext* exception_context = exception->GetContext();
  ASSERT_TRUE(exception_context);

  uint64_t instruction_pointer;
  ASSERT_TRUE(exception_context->GetInstructionPointer(&instruction_pointer));
  EXPECT_EQ(instruction_pointer, 0u);

  MinidumpMemoryList* memory_list = minidump.GetMemoryList();
  ASSERT_TRUE(memory_list);

  unsigned int region_count = memory_list->region_count();
  ASSERT_GE(region_count, 1u);

  for (unsigned int region_index = 0;
       region_index < region_count;
       ++region_index) {
    MinidumpMemoryRegion* region =
        memory_list->GetMemoryRegionAtIndex(region_index);
    uint64_t region_base = region->GetBase();
    EXPECT_FALSE(instruction_pointer >= region_base &&
                 instruction_pointer < region_base + region->GetSize());
  }

  unlink(minidump_path.c_str());
}

#endif  // !ADDRESS_SANITIZER

// Test that anonymous memory maps can be annotated with names and IDs.
TEST(ExceptionHandlerTest, ModuleInfo) {
  // 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);
  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,
                                   kMemorySize,
                                   PROT_READ | PROT_WRITE,
                                   MAP_PRIVATE | MAP_ANON,
                                   -1,
                                   0));
  const uintptr_t kMemoryAddress = reinterpret_cast<uintptr_t>(memory);
  ASSERT_TRUE(memory);

  AutoTempDir temp_dir;
  ExceptionHandler handler(
      MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1);

  // Add info about the anonymous memory mapping.
  handler.AddMappingInfo(kMemoryName,
                         kModuleGUID,
                         kMemoryAddress,
                         kMemorySize,
                         0);
  ASSERT_TRUE(handler.WriteMinidump());

  const MinidumpDescriptor& minidump_desc = handler.minidump_descriptor();
  // 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(minidump_desc.path());
  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(kMemorySize, module->size());
  EXPECT_EQ(kMemoryName, module->code_file());
  EXPECT_EQ(module_identifier, module->debug_identifier());

  unlink(minidump_desc.path());
}

#ifndef ADDRESS_SANITIZER

static const unsigned kControlMsgSize =
    CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred));

static bool
CrashHandler(const void* crash_context, size_t crash_context_size,
             void* context) {
  const int fd = (intptr_t) context;
  int fds[2];
  if (pipe(fds) == -1) {
    // There doesn't seem to be any way to reliably handle
    // this failure without the parent process hanging
    // At least make sure that this process doesn't access
    // unexpected file descriptors
    fds[0] = -1;
    fds[1] = -1;
  }
  struct kernel_msghdr msg = {0};
  struct kernel_iovec iov;
  iov.iov_base = const_cast<void*>(crash_context);
  iov.iov_len = crash_context_size;
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  char cmsg[kControlMsgSize];
  memset(cmsg, 0, kControlMsgSize);
  msg.msg_control = cmsg;
  msg.msg_controllen = sizeof(cmsg);

  struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
  hdr->cmsg_level = SOL_SOCKET;
  hdr->cmsg_type = SCM_RIGHTS;
  hdr->cmsg_len = CMSG_LEN(sizeof(int));
  *((int*) CMSG_DATA(hdr)) = fds[1];
  hdr = CMSG_NXTHDR((struct msghdr*) &msg, hdr);
  hdr->cmsg_level = SOL_SOCKET;
  hdr->cmsg_type = SCM_CREDENTIALS;
  hdr->cmsg_len = CMSG_LEN(sizeof(struct ucred));
  struct ucred *cred = reinterpret_cast<struct ucred*>(CMSG_DATA(hdr));
  cred->uid = getuid();
  cred->gid = getgid();
  cred->pid = getpid();

  ssize_t ret = HANDLE_EINTR(sys_sendmsg(fd, &msg, 0));
  sys_close(fds[1]);
  if (ret <= 0)
    return false;

  char b;
  IGNORE_RET(HANDLE_EINTR(sys_read(fds[0], &b, 1)));

  return true;
}

TEST(ExceptionHandlerTest, ExternalDumper) {
  int fds[2];
  ASSERT_NE(socketpair(AF_UNIX, SOCK_DGRAM, 0, fds), -1);
  static const int on = 1;
  setsockopt(fds[0], SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
  setsockopt(fds[1], SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));

  const pid_t child = fork();
  if (child == 0) {
    close(fds[0]);
    ExceptionHandler handler(MinidumpDescriptor("/tmp1"), NULL, NULL,
                             reinterpret_cast<void*>(fds[1]), true, -1);
    handler.set_crash_handler(CrashHandler);
    DoNullPointerDereference();
  }
  close(fds[1]);
  struct msghdr msg = {0};
  struct iovec iov;
  static const unsigned kCrashContextSize =
      sizeof(ExceptionHandler::CrashContext);
  char context[kCrashContextSize];
  char control[kControlMsgSize];
  iov.iov_base = context;
  iov.iov_len = kCrashContextSize;
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  msg.msg_control = control;
  msg.msg_controllen = kControlMsgSize;

  const ssize_t n = HANDLE_EINTR(recvmsg(fds[0], &msg, 0));
  ASSERT_EQ(static_cast<ssize_t>(kCrashContextSize), n);
  ASSERT_EQ(kControlMsgSize, msg.msg_controllen);
  ASSERT_EQ(static_cast<__typeof__(msg.msg_flags)>(0), msg.msg_flags);
  ASSERT_EQ(0, close(fds[0]));

  pid_t crashing_pid = -1;
  int signal_fd = -1;
  for (struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr;
       hdr = CMSG_NXTHDR(&msg, hdr)) {
    if (hdr->cmsg_level != SOL_SOCKET)
      continue;
    if (hdr->cmsg_type == SCM_RIGHTS) {
      const unsigned len = hdr->cmsg_len -
          (((uint8_t*)CMSG_DATA(hdr)) - (uint8_t*)hdr);
      ASSERT_EQ(sizeof(int), len);
      signal_fd = *(reinterpret_cast<int*>(CMSG_DATA(hdr)));
    } else if (hdr->cmsg_type == SCM_CREDENTIALS) {
      const struct ucred *cred =
          reinterpret_cast<struct ucred*>(CMSG_DATA(hdr));
      crashing_pid = cred->pid;
    }
  }

  ASSERT_NE(crashing_pid, -1);
  ASSERT_NE(signal_fd, -1);

  AutoTempDir temp_dir;
  string templ = temp_dir.path() + "/exception-handler-unittest";
  ASSERT_TRUE(WriteMinidump(templ.c_str(), crashing_pid, context,
                            kCrashContextSize));
  static const char b = 0;
  ASSERT_EQ(1, (HANDLE_EINTR(write(signal_fd, &b, 1))));
  ASSERT_EQ(0, close(signal_fd));

  ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV));

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

#endif  // !ADDRESS_SANITIZER

TEST(ExceptionHandlerTest, WriteMinidumpExceptionStream) {
  AutoTempDir temp_dir;
  ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL, NULL,
                           NULL, false, -1);
  ASSERT_TRUE(handler.WriteMinidump());

  string minidump_path = handler.minidump_descriptor().path();

  // Read the minidump and check the exception stream.
  Minidump minidump(minidump_path);
  ASSERT_TRUE(minidump.Read());
  MinidumpException* exception = minidump.GetException();
  ASSERT_TRUE(exception);
  const MDRawExceptionStream* raw = exception->exception();
  ASSERT_TRUE(raw);
  EXPECT_EQ(MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED,
            raw->exception_record.exception_code);
}

TEST(ExceptionHandlerTest, GenerateMultipleDumpsWithFD) {
  AutoTempDir temp_dir;
  string path;
  const int fd = CreateTMPFile(temp_dir.path(), &path);
  ExceptionHandler handler(MinidumpDescriptor(fd), NULL, NULL, NULL, false, -1);
  ASSERT_TRUE(handler.WriteMinidump());
  // Check by the size of the data written to the FD that a minidump was
  // generated.
  off_t size = lseek(fd, 0, SEEK_CUR);
  ASSERT_GT(size, 0);

  // Generate another minidump.
  ASSERT_TRUE(handler.WriteMinidump());
  size = lseek(fd, 0, SEEK_CUR);
  ASSERT_GT(size, 0);
}

TEST(ExceptionHandlerTest, GenerateMultipleDumpsWithPath) {
  AutoTempDir temp_dir;
  ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL, NULL,
                           NULL, false, -1);
  ASSERT_TRUE(handler.WriteMinidump());

  const MinidumpDescriptor& minidump_1 = handler.minidump_descriptor();
  struct stat st;
  ASSERT_EQ(0, stat(minidump_1.path(), &st));
  ASSERT_GT(st.st_size, 0);
  string minidump_1_path(minidump_1.path());
  // Check it is a valid minidump.
  Minidump minidump1(minidump_1_path);
  ASSERT_TRUE(minidump1.Read());
  unlink(minidump_1.path());

  // Generate another minidump, it should go to a different file.
  ASSERT_TRUE(handler.WriteMinidump());
  const MinidumpDescriptor& minidump_2 = handler.minidump_descriptor();
  ASSERT_EQ(0, stat(minidump_2.path(), &st));
  ASSERT_GT(st.st_size, 0);
  string minidump_2_path(minidump_2.path());
  // Check it is a valid minidump.
  Minidump minidump2(minidump_2_path);
  ASSERT_TRUE(minidump2.Read());
  unlink(minidump_2.path());

  // 2 distinct files should be produced.
  ASSERT_STRNE(minidump_1_path.c_str(), minidump_2_path.c_str());
}

// Test that an additional memory region can be added to the minidump.
TEST(ExceptionHandlerTest, AdditionalMemory) {
  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;
  }

  AutoTempDir temp_dir;
  ExceptionHandler handler(
      MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1);

  // Add the memory region to the list of memory to be included.
  handler.RegisterAppMemory(memory, kMemorySize);
  handler.WriteMinidump();

  const MinidumpDescriptor& minidump_desc = handler.minidump_descriptor();

  // Read the minidump. Ensure that the memory region is present
  Minidump minidump(minidump_desc.path());
  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;
}

// Test that a memory region that was previously registered
// can be unregistered.
TEST(ExceptionHandlerTest, AdditionalMemoryRemove) {
  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);

  AutoTempDir temp_dir;
  ExceptionHandler handler(
      MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1);

  // Add the memory region to the list of memory to be included.
  handler.RegisterAppMemory(memory, kMemorySize);

  // ...and then remove it
  handler.UnregisterAppMemory(memory);
  handler.WriteMinidump();

  const MinidumpDescriptor& minidump_desc = handler.minidump_descriptor();

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

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

  delete[] memory;
}

static bool SimpleCallback(const MinidumpDescriptor& descriptor,
                           void* context,
                           bool succeeded) {
  string* filename = reinterpret_cast<string*>(context);
  *filename = descriptor.path();
  return true;
}

TEST(ExceptionHandlerTest, WriteMinidumpForChild) {
  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);
  }
  close(fds[0]);

  AutoTempDir temp_dir;
  string minidump_filename;
  ASSERT_TRUE(
    ExceptionHandler::WriteMinidumpForChild(child, child,
                                            temp_dir.path(), SimpleCallback,
                                            (void*)&minidump_filename));

  Minidump minidump(minidump_filename);
  ASSERT_TRUE(minidump.Read());
  // Check that the crashing thread is the main thread of |child|
  MinidumpException* exception = minidump.GetException();
  ASSERT_TRUE(exception);
  uint32_t thread_id;
  ASSERT_TRUE(exception->GetThreadID(&thread_id));
  EXPECT_EQ(child, static_cast<int32_t>(thread_id));

  const MDRawExceptionStream* raw = exception->exception();
  ASSERT_TRUE(raw);
  EXPECT_EQ(MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED,
            raw->exception_record.exception_code);

  close(fds[1]);
  unlink(minidump_filename.c_str());
}
