// 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.

// The ExceptionHandler object installs signal handlers for a number of
// signals. We rely on the signal handler running on the thread which crashed
// in order to identify it. This is true of the synchronous signals (SEGV etc),
// but not true of ABRT. Thus, if you send ABRT to yourself in a program which
// uses ExceptionHandler, you need to use tgkill to direct it to the current
// thread.
//
// The signal flow looks like this:
//
//   SignalHandler (uses a global stack of ExceptionHandler objects to find
//        |         one to handle the signal. If the first rejects it, try
//        |         the second etc...)
//        V
//   HandleSignal ----------------------------| (clones a new process which
//        |                                   |  shares an address space with
//   (wait for cloned                         |  the crashed process. This
//     process)                               |  allows us to ptrace the crashed
//        |                                   |  process)
//        V                                   V
//   (set signal handler to             ThreadEntry (static function to bounce
//    SIG_DFL and rethrow,                    |      back into the object)
//    killing the crashed                     |
//    process)                                V
//                                          DoDump  (writes minidump)
//                                            |
//                                            V
//                                         sys_exit
//

// This code is a little fragmented. Different functions of the ExceptionHandler
// class run in a number of different contexts. Some of them run in a normal
// context and are easy to code, others run in a compromised context and the
// restrictions at the top of minidump_writer.cc apply: no libc and use the
// alternative malloc. Each function should have comment above it detailing the
// context which it runs in.

#include "client/linux/handler/exception_handler.h"

#include <errno.h>
#include <fcntl.h>
#include <linux/limits.h>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <unistd.h>

#include <sys/ucontext.h>
#include <sys/user.h>
#include <ucontext.h>

#include <algorithm>
#include <utility>
#include <vector>

#include "common/basictypes.h"
#include "common/linux/linux_libc_support.h"
#include "common/memory_allocator.h"
#include "client/linux/log/log.h"
#include "client/linux/microdump_writer/microdump_writer.h"
#include "client/linux/minidump_writer/linux_dumper.h"
#include "client/linux/minidump_writer/minidump_writer.h"
#include "common/linux/eintr_wrapper.h"
#include "third_party/lss/linux_syscall_support.h"

#if defined(__ANDROID__)
#include "linux/sched.h"
#endif

#ifndef PR_SET_PTRACER
#define PR_SET_PTRACER 0x59616d61
#endif

namespace google_breakpad {

namespace {
// The list of signals which we consider to be crashes. The default action for
// all these signals must be Core (see man 7 signal) because we rethrow the
// signal after handling it and expect that it'll be fatal.
const int kExceptionSignals[] = {
  SIGSEGV, SIGABRT, SIGFPE, SIGILL, SIGBUS, SIGTRAP
};
const int kNumHandledSignals =
    sizeof(kExceptionSignals) / sizeof(kExceptionSignals[0]);
struct sigaction old_handlers[kNumHandledSignals];
bool handlers_installed = false;

// InstallAlternateStackLocked will store the newly installed stack in new_stack
// and (if it exists) the previously installed stack in old_stack.
stack_t old_stack;
stack_t new_stack;
bool stack_installed = false;

// Create an alternative stack to run the signal handlers on. This is done since
// the signal might have been caused by a stack overflow.
// Runs before crashing: normal context.
void InstallAlternateStackLocked() {
  if (stack_installed)
    return;

  memset(&old_stack, 0, sizeof(old_stack));
  memset(&new_stack, 0, sizeof(new_stack));

  // SIGSTKSZ may be too small to prevent the signal handlers from overrunning
  // the alternative stack. Ensure that the size of the alternative stack is
  // large enough.
  static const unsigned kSigStackSize = std::max(16384, SIGSTKSZ);

  // Only set an alternative stack if there isn't already one, or if the current
  // one is too small.
  if (sys_sigaltstack(NULL, &old_stack) == -1 || !old_stack.ss_sp ||
      old_stack.ss_size < kSigStackSize) {
    new_stack.ss_sp = calloc(1, kSigStackSize);
    new_stack.ss_size = kSigStackSize;

    if (sys_sigaltstack(&new_stack, NULL) == -1) {
      free(new_stack.ss_sp);
      return;
    }
    stack_installed = true;
  }
}

// Runs before crashing: normal context.
void RestoreAlternateStackLocked() {
  if (!stack_installed)
    return;

  stack_t current_stack;
  if (sys_sigaltstack(NULL, &current_stack) == -1)
    return;

  // Only restore the old_stack if the current alternative stack is the one
  // installed by the call to InstallAlternateStackLocked.
  if (current_stack.ss_sp == new_stack.ss_sp) {
    if (old_stack.ss_sp) {
      if (sys_sigaltstack(&old_stack, NULL) == -1)
        return;
    } else {
      stack_t disable_stack;
      disable_stack.ss_flags = SS_DISABLE;
      if (sys_sigaltstack(&disable_stack, NULL) == -1)
        return;
    }
  }

  free(new_stack.ss_sp);
  stack_installed = false;
}

void InstallDefaultHandler(int sig) {
#if defined(__ANDROID__)
  // Android L+ expose signal and sigaction symbols that override the system
  // ones. There is a bug in these functions where a request to set the handler
  // to SIG_DFL is ignored. In that case, an infinite loop is entered as the
  // signal is repeatedly sent to breakpad's signal handler.
  // To work around this, directly call the system's sigaction.
  struct kernel_sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sys_sigemptyset(&sa.sa_mask);
  sa.sa_handler_ = SIG_DFL;
  sa.sa_flags = SA_RESTART;
  sys_rt_sigaction(sig, &sa, NULL, sizeof(kernel_sigset_t));
#else
  signal(sig, SIG_DFL);
#endif
}

// The global exception handler stack. This is needed because there may exist
// multiple ExceptionHandler instances in a process. Each will have itself
// registered in this stack.
std::vector<ExceptionHandler*>* g_handler_stack_ = NULL;
pthread_mutex_t g_handler_stack_mutex_ = PTHREAD_MUTEX_INITIALIZER;

// sizeof(CrashContext) can be too big w.r.t the size of alternatate stack
// for SignalHandler(). Keep the crash context as a .bss field. Exception
// handlers are serialized by the |g_handler_stack_mutex_| and at most one at a
// time can use |g_crash_context_|.
ExceptionHandler::CrashContext g_crash_context_;

FirstChanceHandler g_first_chance_handler_ = nullptr;
}  // namespace

// Runs before crashing: normal context.
ExceptionHandler::ExceptionHandler(const MinidumpDescriptor& descriptor,
                                   FilterCallback filter,
                                   MinidumpCallback callback,
                                   void* callback_context,
                                   bool install_handler,
                                   const int server_fd)
    : filter_(filter),
      callback_(callback),
      callback_context_(callback_context),
      minidump_descriptor_(descriptor),
      crash_handler_(NULL) {
  if (server_fd >= 0)
    crash_generation_client_.reset(CrashGenerationClient::TryCreate(server_fd));

  if (!IsOutOfProcess() && !minidump_descriptor_.IsFD() &&
      !minidump_descriptor_.IsMicrodumpOnConsole())
    minidump_descriptor_.UpdatePath();

#if defined(__ANDROID__)
  if (minidump_descriptor_.IsMicrodumpOnConsole())
    logger::initializeCrashLogWriter();
#endif

  pthread_mutex_lock(&g_handler_stack_mutex_);

  // Pre-fault the crash context struct. This is to avoid failing due to OOM
  // if handling an exception when the process ran out of virtual memory.
  memset(&g_crash_context_, 0, sizeof(g_crash_context_));

  if (!g_handler_stack_)
    g_handler_stack_ = new std::vector<ExceptionHandler*>;
  if (install_handler) {
    InstallAlternateStackLocked();
    InstallHandlersLocked();
  }
  g_handler_stack_->push_back(this);
  pthread_mutex_unlock(&g_handler_stack_mutex_);
}

// Runs before crashing: normal context.
ExceptionHandler::~ExceptionHandler() {
  pthread_mutex_lock(&g_handler_stack_mutex_);
  std::vector<ExceptionHandler*>::iterator handler =
      std::find(g_handler_stack_->begin(), g_handler_stack_->end(), this);
  g_handler_stack_->erase(handler);
  if (g_handler_stack_->empty()) {
    delete g_handler_stack_;
    g_handler_stack_ = NULL;
    RestoreAlternateStackLocked();
    RestoreHandlersLocked();
  }
  pthread_mutex_unlock(&g_handler_stack_mutex_);
}

// Runs before crashing: normal context.
// static
bool ExceptionHandler::InstallHandlersLocked() {
  if (handlers_installed)
    return false;

  // Fail if unable to store all the old handlers.
  for (int i = 0; i < kNumHandledSignals; ++i) {
    if (sigaction(kExceptionSignals[i], NULL, &old_handlers[i]) == -1)
      return false;
  }

  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sigemptyset(&sa.sa_mask);

  // Mask all exception signals when we're handling one of them.
  for (int i = 0; i < kNumHandledSignals; ++i)
    sigaddset(&sa.sa_mask, kExceptionSignals[i]);

  sa.sa_sigaction = SignalHandler;
  sa.sa_flags = SA_ONSTACK | SA_SIGINFO;

  for (int i = 0; i < kNumHandledSignals; ++i) {
    if (sigaction(kExceptionSignals[i], &sa, NULL) == -1) {
      // At this point it is impractical to back out changes, and so failure to
      // install a signal is intentionally ignored.
    }
  }
  handlers_installed = true;
  return true;
}

// This function runs in a compromised context: see the top of the file.
// Runs on the crashing thread.
// static
void ExceptionHandler::RestoreHandlersLocked() {
  if (!handlers_installed)
    return;

  for (int i = 0; i < kNumHandledSignals; ++i) {
    if (sigaction(kExceptionSignals[i], &old_handlers[i], NULL) == -1) {
      InstallDefaultHandler(kExceptionSignals[i]);
    }
  }
  handlers_installed = false;
}

// void ExceptionHandler::set_crash_handler(HandlerCallback callback) {
//   crash_handler_ = callback;
// }

// This function runs in a compromised context: see the top of the file.
// Runs on the crashing thread.
// static
void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) {

  // Give the first chance handler a chance to recover from this signal
  //
  // This is primarily used by V8. V8 uses guard regions to guarantee memory
  // safety in WebAssembly. This means some signals might be expected if they
  // originate from Wasm code while accessing the guard region. We give V8 the
  // chance to handle and recover from these signals first.
  if (g_first_chance_handler_ != nullptr &&
      g_first_chance_handler_(sig, info, uc)) {
    return;
  }

  // All the exception signals are blocked at this point.
  pthread_mutex_lock(&g_handler_stack_mutex_);

  // Sometimes, Breakpad runs inside a process where some other buggy code
  // saves and restores signal handlers temporarily with 'signal'
  // instead of 'sigaction'. This loses the SA_SIGINFO flag associated
  // with this function. As a consequence, the values of 'info' and 'uc'
  // become totally bogus, generally inducing a crash.
  //
  // The following code tries to detect this case. When it does, it
  // resets the signal handlers with sigaction + SA_SIGINFO and returns.
  // This forces the signal to be thrown again, but this time the kernel
  // will call the function with the right arguments.
  struct sigaction cur_handler;
  if (sigaction(sig, NULL, &cur_handler) == 0 &&
      cur_handler.sa_sigaction == SignalHandler &&
      (cur_handler.sa_flags & SA_SIGINFO) == 0) {
    // Reset signal handler with the right flags.
    sigemptyset(&cur_handler.sa_mask);
    sigaddset(&cur_handler.sa_mask, sig);

    cur_handler.sa_sigaction = SignalHandler;
    cur_handler.sa_flags = SA_ONSTACK | SA_SIGINFO;

    if (sigaction(sig, &cur_handler, NULL) == -1) {
      // When resetting the handler fails, try to reset the
      // default one to avoid an infinite loop here.
      InstallDefaultHandler(sig);
    }
    pthread_mutex_unlock(&g_handler_stack_mutex_);
    return;
  }

  bool handled = false;
  for (int i = g_handler_stack_->size() - 1; !handled && i >= 0; --i) {
    handled = (*g_handler_stack_)[i]->HandleSignal(sig, info, uc);
  }

  // Upon returning from this signal handler, sig will become unmasked and then
  // it will be retriggered. If one of the ExceptionHandlers handled it
  // successfully, restore the default handler. Otherwise, restore the
  // previously installed handler. Then, when the signal is retriggered, it will
  // be delivered to the appropriate handler.
  if (handled) {
    InstallDefaultHandler(sig);
  } else {
    RestoreHandlersLocked();
  }

  pthread_mutex_unlock(&g_handler_stack_mutex_);

  // info->si_code <= 0 iff SI_FROMUSER (SI_FROMKERNEL otherwise).
  if (info->si_code <= 0 || sig == SIGABRT) {
    // This signal was triggered by somebody sending us the signal with kill().
    // In order to retrigger it, we have to queue a new signal by calling
    // kill() ourselves.  The special case (si_pid == 0 && sig == SIGABRT) is
    // due to the kernel sending a SIGABRT from a user request via SysRQ.
    if (sys_tgkill(getpid(), syscall(__NR_gettid), sig) < 0) {
      // If we failed to kill ourselves (e.g. because a sandbox disallows us
      // to do so), we instead resort to terminating our process. This will
      // result in an incorrect exit code.
      _exit(1);
    }
  } else {
    // This was a synchronous signal triggered by a hard fault (e.g. SIGSEGV).
    // No need to reissue the signal. It will automatically trigger again,
    // when we return from the signal handler.
  }
}

struct ThreadArgument {
  pid_t pid;  // the crashing process
  const MinidumpDescriptor* minidump_descriptor;
  ExceptionHandler* handler;
  const void* context;  // a CrashContext structure
  size_t context_size;
};

// This is the entry function for the cloned process. We are in a compromised
// context here: see the top of the file.
// static
int ExceptionHandler::ThreadEntry(void *arg) {
  const ThreadArgument *thread_arg = reinterpret_cast<ThreadArgument*>(arg);

  // Close the write end of the pipe. This allows us to fail if the parent dies
  // while waiting for the continue signal.
  sys_close(thread_arg->handler->fdes[1]);

  // Block here until the crashing process unblocks us when
  // we're allowed to use ptrace
  thread_arg->handler->WaitForContinueSignal();
  sys_close(thread_arg->handler->fdes[0]);

  return thread_arg->handler->DoDump(thread_arg->pid, thread_arg->context,
                                     thread_arg->context_size) == false;
}

// This function runs in a compromised context: see the top of the file.
// Runs on the crashing thread.
bool ExceptionHandler::HandleSignal(int /*sig*/, siginfo_t* info, void* uc) {
  if (filter_ && !filter_(callback_context_))
    return false;

  // Allow ourselves to be dumped if the signal is trusted.
  bool signal_trusted = info->si_code > 0;
  bool signal_pid_trusted = info->si_code == SI_USER ||
      info->si_code == SI_TKILL;
  if (signal_trusted || (signal_pid_trusted && info->si_pid == getpid())) {
    sys_prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
  }

  // Fill in all the holes in the struct to make Valgrind happy.
  memset(&g_crash_context_, 0, sizeof(g_crash_context_));
  memcpy(&g_crash_context_.siginfo, info, sizeof(siginfo_t));
  memcpy(&g_crash_context_.context, uc, sizeof(ucontext_t));
#if defined(__aarch64__)
  ucontext_t* uc_ptr = (ucontext_t*)uc;
  struct fpsimd_context* fp_ptr =
      (struct fpsimd_context*)&uc_ptr->uc_mcontext.__reserved;
  if (fp_ptr->head.magic == FPSIMD_MAGIC) {
    memcpy(&g_crash_context_.float_state, fp_ptr,
           sizeof(g_crash_context_.float_state));
  }
#elif !defined(__ARM_EABI__) && !defined(__mips__)
  // FP state is not part of user ABI on ARM Linux.
  // In case of MIPS Linux FP state is already part of ucontext_t
  // and 'float_state' is not a member of CrashContext.
  ucontext_t* uc_ptr = (ucontext_t*)uc;
  if (uc_ptr->uc_mcontext.fpregs) {
    memcpy(&g_crash_context_.float_state, uc_ptr->uc_mcontext.fpregs,
           sizeof(g_crash_context_.float_state));
  }
#endif
  g_crash_context_.tid = syscall(__NR_gettid);
  if (crash_handler_ != NULL) {
    if (crash_handler_(&g_crash_context_, sizeof(g_crash_context_),
                       callback_context_)) {
      return true;
    }
  }
  return GenerateDump(&g_crash_context_);
}

// This is a public interface to HandleSignal that allows the client to
// generate a crash dump. This function may run in a compromised context.
bool ExceptionHandler::SimulateSignalDelivery(int sig) {
  siginfo_t siginfo = {};
  // Mimic a trusted signal to allow tracing the process (see
  // ExceptionHandler::HandleSignal().
  siginfo.si_code = SI_USER;
  siginfo.si_pid = getpid();
  ucontext_t context;
  getcontext(&context);
  return HandleSignal(sig, &siginfo, &context);
}

// This function may run in a compromised context: see the top of the file.
bool ExceptionHandler::GenerateDump(CrashContext *context) {
  if (IsOutOfProcess())
    return crash_generation_client_->RequestDump(context, sizeof(*context));

  // Allocating too much stack isn't a problem, and better to err on the side
  // of caution than smash it into random locations.
  static const unsigned kChildStackSize = 16000;
  PageAllocator allocator;
  uint8_t* stack = reinterpret_cast<uint8_t*>(allocator.Alloc(kChildStackSize));
  if (!stack)
    return false;
  // clone() needs the top-most address. (scrub just to be safe)
  stack += kChildStackSize;
  my_memset(stack - 16, 0, 16);

  ThreadArgument thread_arg;
  thread_arg.handler = this;
  thread_arg.minidump_descriptor = &minidump_descriptor_;
  thread_arg.pid = getpid();
  thread_arg.context = context;
  thread_arg.context_size = sizeof(*context);

  // We need to explicitly enable ptrace of parent processes on some
  // kernels, but we need to know the PID of the cloned process before we
  // can do this. Create a pipe here which we can use to block the
  // cloned process after creating it, until we have explicitly enabled ptrace
  if (sys_pipe(fdes) == -1) {
    // Creating the pipe failed. We'll log an error but carry on anyway,
    // as we'll probably still get a useful crash report. All that will happen
    // is the write() and read() calls will fail with EBADF
    static const char no_pipe_msg[] = "ExceptionHandler::GenerateDump "
                                      "sys_pipe failed:";
    logger::write(no_pipe_msg, sizeof(no_pipe_msg) - 1);
    logger::write(strerror(errno), strlen(strerror(errno)));
    logger::write("\n", 1);

    // Ensure fdes[0] and fdes[1] are invalid file descriptors.
    fdes[0] = fdes[1] = -1;
  }

  const pid_t child = sys_clone(
      ThreadEntry, stack, CLONE_FS | CLONE_UNTRACED, &thread_arg, NULL, NULL,
      NULL);
  if (child == -1) {
    sys_close(fdes[0]);
    sys_close(fdes[1]);
    return false;
  }

  // Close the read end of the pipe.
  sys_close(fdes[0]);
  // Allow the child to ptrace us
  sys_prctl(PR_SET_PTRACER, child, 0, 0, 0);
  SendContinueSignalToChild();
  int status = 0;
  const int r = HANDLE_EINTR(sys_waitpid(child, &status, __WALL));

  sys_close(fdes[1]);

  if (r == -1) {
    static const char msg[] = "ExceptionHandler::GenerateDump waitpid failed:";
    logger::write(msg, sizeof(msg) - 1);
    logger::write(strerror(errno), strlen(strerror(errno)));
    logger::write("\n", 1);
  }

  bool success = r != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0;
  if (callback_)
    success = callback_(minidump_descriptor_, callback_context_, success);
  return success;
}

// This function runs in a compromised context: see the top of the file.
void ExceptionHandler::SendContinueSignalToChild() {
  static const char okToContinueMessage = 'a';
  int r;
  r = HANDLE_EINTR(sys_write(fdes[1], &okToContinueMessage, sizeof(char)));
  if (r == -1) {
    static const char msg[] = "ExceptionHandler::SendContinueSignalToChild "
                              "sys_write failed:";
    logger::write(msg, sizeof(msg) - 1);
    logger::write(strerror(errno), strlen(strerror(errno)));
    logger::write("\n", 1);
  }
}

// This function runs in a compromised context: see the top of the file.
// Runs on the cloned process.
void ExceptionHandler::WaitForContinueSignal() {
  int r;
  char receivedMessage;
  r = HANDLE_EINTR(sys_read(fdes[0], &receivedMessage, sizeof(char)));
  if (r == -1) {
    static const char msg[] = "ExceptionHandler::WaitForContinueSignal "
                              "sys_read failed:";
    logger::write(msg, sizeof(msg) - 1);
    logger::write(strerror(errno), strlen(strerror(errno)));
    logger::write("\n", 1);
  }
}

// This function runs in a compromised context: see the top of the file.
// Runs on the cloned process.
bool ExceptionHandler::DoDump(pid_t crashing_process, const void* context,
                              size_t context_size) {
  const bool may_skip_dump =
      minidump_descriptor_.skip_dump_if_principal_mapping_not_referenced();
  const uintptr_t principal_mapping_address =
      minidump_descriptor_.address_within_principal_mapping();
  const bool sanitize_stacks = minidump_descriptor_.sanitize_stacks();
  if (minidump_descriptor_.IsMicrodumpOnConsole()) {
    return google_breakpad::WriteMicrodump(
        crashing_process,
        context,
        context_size,
        mapping_list_,
        may_skip_dump,
        principal_mapping_address,
        sanitize_stacks,
        *minidump_descriptor_.microdump_extra_info());
  }
  if (minidump_descriptor_.IsFD()) {
    return google_breakpad::WriteMinidump(minidump_descriptor_.fd(),
                                          minidump_descriptor_.size_limit(),
                                          crashing_process,
                                          context,
                                          context_size,
                                          mapping_list_,
                                          app_memory_list_,
                                          may_skip_dump,
                                          principal_mapping_address,
                                          sanitize_stacks);
  }
  return google_breakpad::WriteMinidump(minidump_descriptor_.path(),
                                        minidump_descriptor_.size_limit(),
                                        crashing_process,
                                        context,
                                        context_size,
                                        mapping_list_,
                                        app_memory_list_,
                                        may_skip_dump,
                                        principal_mapping_address,
                                        sanitize_stacks);
}

// static
bool ExceptionHandler::WriteMinidump(const string& dump_path,
                                     MinidumpCallback callback,
                                     void* callback_context) {
  MinidumpDescriptor descriptor(dump_path);
  ExceptionHandler eh(descriptor, NULL, callback, callback_context, false, -1);
  return eh.WriteMinidump();
}

// In order to making using EBP to calculate the desired value for ESP
// a valid operation, ensure that this function is compiled with a
// frame pointer using the following attribute. This attribute
// is supported on GCC but not on clang.
#if defined(__i386__) && defined(__GNUC__) && !defined(__clang__)
__attribute__((optimize("no-omit-frame-pointer")))
#endif
bool ExceptionHandler::WriteMinidump() {
  if (!IsOutOfProcess() && !minidump_descriptor_.IsFD() &&
      !minidump_descriptor_.IsMicrodumpOnConsole()) {
    // Update the path of the minidump so that this can be called multiple times
    // and new files are created for each minidump.  This is done before the
    // generation happens, as clients may want to access the MinidumpDescriptor
    // after this call to find the exact path to the minidump file.
    minidump_descriptor_.UpdatePath();
  } else if (minidump_descriptor_.IsFD()) {
    // Reposition the FD to its beginning and resize it to get rid of the
    // previous minidump info.
    lseek(minidump_descriptor_.fd(), 0, SEEK_SET);
    ignore_result(ftruncate(minidump_descriptor_.fd(), 0));
  }

  // Allow this process to be dumped.
  sys_prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);

  CrashContext context;
  int getcontext_result = getcontext(&context.context);
  if (getcontext_result)
    return false;

#if defined(__i386__)
  // In CPUFillFromUContext in minidumpwriter.cc the stack pointer is retrieved
  // from REG_UESP instead of from REG_ESP. REG_UESP is the user stack pointer
  // and it only makes sense when running in kernel mode with a different stack
  // pointer. When WriteMiniDump is called during normal processing REG_UESP is
  // zero which leads to bad minidump files.
  if (!context.context.uc_mcontext.gregs[REG_UESP]) {
    // If REG_UESP is set to REG_ESP then that includes the stack space for the
    // CrashContext object in this function, which is about 128 KB. Since the
    // Linux dumper only records 32 KB of stack this would mean that nothing
    // useful would be recorded. A better option is to set REG_UESP to REG_EBP,
    // perhaps with a small negative offset in case there is any code that
    // objects to them being equal.
    context.context.uc_mcontext.gregs[REG_UESP] =
      context.context.uc_mcontext.gregs[REG_EBP] - 16;
    // The stack saving is based off of REG_ESP so it must be set to match the
    // new REG_UESP.
    context.context.uc_mcontext.gregs[REG_ESP] =
      context.context.uc_mcontext.gregs[REG_UESP];
  }
#endif

#if !defined(__ARM_EABI__) && !defined(__aarch64__) && !defined(__mips__)
  // FPU state is not part of ARM EABI ucontext_t.
  memcpy(&context.float_state, context.context.uc_mcontext.fpregs,
         sizeof(context.float_state));
#endif
  context.tid = sys_gettid();

  // Add an exception stream to the minidump for better reporting.
  memset(&context.siginfo, 0, sizeof(context.siginfo));
  context.siginfo.si_signo = MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED;
#if defined(__i386__)
  context.siginfo.si_addr =
      reinterpret_cast<void*>(context.context.uc_mcontext.gregs[REG_EIP]);
#elif defined(__x86_64__)
  context.siginfo.si_addr =
      reinterpret_cast<void*>(context.context.uc_mcontext.gregs[REG_RIP]);
#elif defined(__arm__)
  context.siginfo.si_addr =
      reinterpret_cast<void*>(context.context.uc_mcontext.arm_pc);
#elif defined(__aarch64__)
  context.siginfo.si_addr =
      reinterpret_cast<void*>(context.context.uc_mcontext.pc);
#elif defined(__mips__)
  context.siginfo.si_addr =
      reinterpret_cast<void*>(context.context.uc_mcontext.pc);
#else
#error "This code has not been ported to your platform yet."
#endif

  return GenerateDump(&context);
}

void ExceptionHandler::AddMappingInfo(const string& name,
                                      const uint8_t identifier[sizeof(MDGUID)],
                                      uintptr_t start_address,
                                      size_t mapping_size,
                                      size_t file_offset) {
  MappingInfo info;
  info.start_addr = start_address;
  info.size = mapping_size;
  info.offset = file_offset;
  strncpy(info.name, name.c_str(), sizeof(info.name) - 1);
  info.name[sizeof(info.name) - 1] = '\0';

  MappingEntry mapping;
  mapping.first = info;
  memcpy(mapping.second, identifier, sizeof(MDGUID));
  mapping_list_.push_back(mapping);
}

void ExceptionHandler::RegisterAppMemory(void* ptr, size_t length) {
  AppMemoryList::iterator iter =
    std::find(app_memory_list_.begin(), app_memory_list_.end(), ptr);
  if (iter != app_memory_list_.end()) {
    // Don't allow registering the same pointer twice.
    return;
  }

  AppMemory app_memory;
  app_memory.ptr = ptr;
  app_memory.length = length;
  app_memory_list_.push_back(app_memory);
}

void ExceptionHandler::UnregisterAppMemory(void* ptr) {
  AppMemoryList::iterator iter =
    std::find(app_memory_list_.begin(), app_memory_list_.end(), ptr);
  if (iter != app_memory_list_.end()) {
    app_memory_list_.erase(iter);
  }
}

// static
bool ExceptionHandler::WriteMinidumpForChild(pid_t child,
                                             pid_t child_blamed_thread,
                                             const string& dump_path,
                                             MinidumpCallback callback,
                                             void* callback_context) {
  // This function is not run in a compromised context.
  MinidumpDescriptor descriptor(dump_path);
  descriptor.UpdatePath();
  if (!google_breakpad::WriteMinidump(descriptor.path(),
                                      child,
                                      child_blamed_thread))
      return false;

  return callback ? callback(descriptor, callback_context, true) : true;
}

void SetFirstChanceExceptionHandler(FirstChanceHandler callback) {
  g_first_chance_handler_ = callback;
}

}  // namespace google_breakpad
