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

#include "base/debug/stack_trace.h"

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <algorithm>
#include <map>
#include <memory>
#include <ostream>
#include <string>
#include <vector>

#if !defined(USE_SYMBOLIZE)
#include <cxxabi.h>
#endif
#if !defined(__UCLIBC__) && !defined(_AIX)
#include <execinfo.h>
#endif

#if defined(OS_MACOSX)
#include <AvailabilityMacros.h>
#endif

#if defined(OS_LINUX)
#include "base/debug/proc_maps_linux.h"
#endif

#include "base/cfi_buildflags.h"
#include "base/debug/debugger.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/free_deleter.h"
#include "base/memory/singleton.h"
#include "base/numerics/safe_conversions.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"

#if defined(USE_SYMBOLIZE)
#include "base/third_party/symbolize/symbolize.h"
#include "starboard/common/string.h"
#include "starboard/memory.h"
#include "starboard/types.h"
#endif

namespace base {
namespace debug {

namespace {

volatile sig_atomic_t in_signal_handler = 0;

bool (*try_handle_signal)(int, void*, void*) = nullptr;

#if !defined(USE_SYMBOLIZE)
// The prefix used for mangled symbols, per the Itanium C++ ABI:
// http://www.codesourcery.com/cxx-abi/abi.html#mangling
const char kMangledSymbolPrefix[] = "_Z";

// Characters that can be used for symbols, generated by Ruby:
// (('a'..'z').to_a+('A'..'Z').to_a+('0'..'9').to_a + ['_']).join
const char kSymbolCharacters[] =
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
#endif  // !defined(USE_SYMBOLIZE)

#if !defined(USE_SYMBOLIZE)
// Demangles C++ symbols in the given text. Example:
//
// "out/Debug/base_unittests(_ZN10StackTraceC1Ev+0x20) [0x817778c]"
// =>
// "out/Debug/base_unittests(StackTrace::StackTrace()+0x20) [0x817778c]"
void DemangleSymbols(std::string* text) {
  // Note: code in this function is NOT async-signal safe (std::string uses
  // malloc internally).

#if !defined(__UCLIBC__) && !defined(_AIX)
  std::string::size_type search_from = 0;
  while (search_from < text->size()) {
    // Look for the start of a mangled symbol, from search_from.
    std::string::size_type mangled_start =
        text->find(kMangledSymbolPrefix, search_from);
    if (mangled_start == std::string::npos) {
      break;  // Mangled symbol not found.
    }

    // Look for the end of the mangled symbol.
    std::string::size_type mangled_end =
        text->find_first_not_of(kSymbolCharacters, mangled_start);
    if (mangled_end == std::string::npos) {
      mangled_end = text->size();
    }
    std::string mangled_symbol =
        text->substr(mangled_start, mangled_end - mangled_start);

    // Try to demangle the mangled symbol candidate.
    int status = 0;
    std::unique_ptr<char, base::FreeDeleter> demangled_symbol(
        abi::__cxa_demangle(mangled_symbol.c_str(), nullptr, 0, &status));
    if (status == 0) {  // Demangling is successful.
      // Remove the mangled symbol.
      text->erase(mangled_start, mangled_end - mangled_start);
      // Insert the demangled symbol.
      text->insert(mangled_start, demangled_symbol.get());
      // Next time, we'll start right after the demangled symbol we inserted.
      search_from = mangled_start + strlen(demangled_symbol.get());
    } else {
      // Failed to demangle.  Retry after the "_Z" we just found.
      search_from = mangled_start + 2;
    }
  }
#endif  // !defined(__UCLIBC__) && !defined(_AIX)
}
#endif  // !defined(USE_SYMBOLIZE)

class BacktraceOutputHandler {
 public:
  virtual void HandleOutput(const char* output) = 0;

 protected:
  virtual ~BacktraceOutputHandler() = default;
};

#if !defined(__UCLIBC__) && !defined(_AIX)
void OutputPointer(void* pointer, BacktraceOutputHandler* handler) {
  // This should be more than enough to store a 64-bit number in hex:
  // 16 hex digits + 1 for null-terminator.
  char buf[17] = { '\0' };
  handler->HandleOutput("0x");
  internal::itoa_r(reinterpret_cast<intptr_t>(pointer),
                   buf, sizeof(buf), 16, 12);
  handler->HandleOutput(buf);
}

#if defined(USE_SYMBOLIZE)
void OutputFrameId(intptr_t frame_id, BacktraceOutputHandler* handler) {
  // Max unsigned 64-bit number in decimal has 20 digits (18446744073709551615).
  // Hence, 30 digits should be more than enough to represent it in decimal
  // (including the null-terminator).
  char buf[30] = { '\0' };
  handler->HandleOutput("#");
  internal::itoa_r(frame_id, buf, sizeof(buf), 10, 1);
  handler->HandleOutput(buf);
}
#endif  // defined(USE_SYMBOLIZE)

void ProcessBacktrace(void* const* trace,
                      size_t size,
                      const char* prefix_string,
                      BacktraceOutputHandler* handler) {
// NOTE: This code MUST be async-signal safe (it's used by in-process
// stack dumping signal handler). NO malloc or stdio is allowed here.

#if defined(USE_SYMBOLIZE)
  for (size_t i = 0; i < size; ++i) {
    if (prefix_string)
      handler->HandleOutput(prefix_string);

    OutputFrameId(i, handler);
    handler->HandleOutput(" ");
    OutputPointer(trace[i], handler);
    handler->HandleOutput(" ");

    char buf[1024] = { '\0' };

    // Subtract by one as return address of function may be in the next
    // function when a function is annotated as noreturn.
    void* address = static_cast<char*>(trace[i]) - 1;
    if (google::Symbolize(address, buf, sizeof(buf)))
      handler->HandleOutput(buf);
    else
      handler->HandleOutput("<unknown>");

    handler->HandleOutput("\n");
  }
#else
  bool printed = false;

  // Below part is async-signal unsafe (uses malloc), so execute it only
  // when we are not executing the signal handler.
  if (in_signal_handler == 0) {
    std::unique_ptr<char*, FreeDeleter> trace_symbols(
        backtrace_symbols(trace, size));
    if (trace_symbols.get()) {
      for (size_t i = 0; i < size; ++i) {
        std::string trace_symbol = trace_symbols.get()[i];
        DemangleSymbols(&trace_symbol);
        if (prefix_string)
          handler->HandleOutput(prefix_string);
        handler->HandleOutput(trace_symbol.c_str());
        handler->HandleOutput("\n");
      }

      printed = true;
    }
  }

  if (!printed) {
    for (size_t i = 0; i < size; ++i) {
      handler->HandleOutput(" [");
      OutputPointer(trace[i], handler);
      handler->HandleOutput("]\n");
    }
  }
#endif  // defined(USE_SYMBOLIZE)
}
#endif  // !defined(__UCLIBC__) && !defined(_AIX)

void PrintToStderr(const char* output) {
  // NOTE: This code MUST be async-signal safe (it's used by in-process
  // stack dumping signal handler). NO malloc or stdio is allowed here.
  ignore_result(
      HANDLE_EINTR(write(STDERR_FILENO, output, strlen(output))));
}

void StackDumpSignalHandler(int signal, siginfo_t* info, void* void_context) {
  // NOTE: This code MUST be async-signal safe.
  // NO malloc or stdio is allowed here.

  // Give a registered callback a chance to recover from this signal
  //
  // 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 (try_handle_signal != nullptr &&
      try_handle_signal(signal, info, void_context)) {
    // The first chance handler took care of this. The SA_RESETHAND flag
    // replaced this signal handler upon entry, but we want to stay
    // installed. Thus, we reinstall ourselves before returning.
    struct sigaction action;
    memset(&action, 0, sizeof(action));
    action.sa_flags = SA_RESETHAND | SA_SIGINFO;
    action.sa_sigaction = &StackDumpSignalHandler;
    sigemptyset(&action.sa_mask);

    sigaction(signal, &action, nullptr);
    return;
  }

// Do not take the "in signal handler" code path on Mac in a DCHECK-enabled
// build, as this prevents seeing a useful (symbolized) stack trace on a crash
// or DCHECK() failure. While it may not be fully safe to run the stack symbol
// printing code, in practice it's better to provide meaningful stack traces -
// and the risk is low given we're likely crashing already.
#if !defined(OS_MACOSX) || !DCHECK_IS_ON()
  // Record the fact that we are in the signal handler now, so that the rest
  // of StackTrace can behave in an async-signal-safe manner.
  in_signal_handler = 1;
#endif

  if (BeingDebugged())
    BreakDebugger();

  PrintToStderr("Received signal ");
  char buf[1024] = { 0 };
  internal::itoa_r(signal, buf, sizeof(buf), 10, 0);
  PrintToStderr(buf);
  if (signal == SIGBUS) {
    if (info->si_code == BUS_ADRALN)
      PrintToStderr(" BUS_ADRALN ");
    else if (info->si_code == BUS_ADRERR)
      PrintToStderr(" BUS_ADRERR ");
    else if (info->si_code == BUS_OBJERR)
      PrintToStderr(" BUS_OBJERR ");
    else
      PrintToStderr(" <unknown> ");
  } else if (signal == SIGFPE) {
    if (info->si_code == FPE_FLTDIV)
      PrintToStderr(" FPE_FLTDIV ");
    else if (info->si_code == FPE_FLTINV)
      PrintToStderr(" FPE_FLTINV ");
    else if (info->si_code == FPE_FLTOVF)
      PrintToStderr(" FPE_FLTOVF ");
    else if (info->si_code == FPE_FLTRES)
      PrintToStderr(" FPE_FLTRES ");
    else if (info->si_code == FPE_FLTSUB)
      PrintToStderr(" FPE_FLTSUB ");
    else if (info->si_code == FPE_FLTUND)
      PrintToStderr(" FPE_FLTUND ");
    else if (info->si_code == FPE_INTDIV)
      PrintToStderr(" FPE_INTDIV ");
    else if (info->si_code == FPE_INTOVF)
      PrintToStderr(" FPE_INTOVF ");
    else
      PrintToStderr(" <unknown> ");
  } else if (signal == SIGILL) {
    if (info->si_code == ILL_BADSTK)
      PrintToStderr(" ILL_BADSTK ");
    else if (info->si_code == ILL_COPROC)
      PrintToStderr(" ILL_COPROC ");
    else if (info->si_code == ILL_ILLOPN)
      PrintToStderr(" ILL_ILLOPN ");
    else if (info->si_code == ILL_ILLADR)
      PrintToStderr(" ILL_ILLADR ");
    else if (info->si_code == ILL_ILLTRP)
      PrintToStderr(" ILL_ILLTRP ");
    else if (info->si_code == ILL_PRVOPC)
      PrintToStderr(" ILL_PRVOPC ");
    else if (info->si_code == ILL_PRVREG)
      PrintToStderr(" ILL_PRVREG ");
    else
      PrintToStderr(" <unknown> ");
  } else if (signal == SIGSEGV) {
    if (info->si_code == SEGV_MAPERR)
      PrintToStderr(" SEGV_MAPERR ");
    else if (info->si_code == SEGV_ACCERR)
      PrintToStderr(" SEGV_ACCERR ");
    else
      PrintToStderr(" <unknown> ");
  }
  if (signal == SIGBUS || signal == SIGFPE ||
      signal == SIGILL || signal == SIGSEGV) {
    internal::itoa_r(reinterpret_cast<intptr_t>(info->si_addr),
                     buf, sizeof(buf), 16, 12);
    PrintToStderr(buf);
  }
  PrintToStderr("\n");

#if BUILDFLAG(CFI_ENFORCEMENT_TRAP)
  if (signal == SIGILL && info->si_code == ILL_ILLOPN) {
    PrintToStderr(
        "CFI: Most likely a control flow integrity violation; for more "
        "information see:\n");
    PrintToStderr(
        "https://www.chromium.org/developers/testing/control-flow-integrity\n");
  }
#endif  // BUILDFLAG(CFI_ENFORCEMENT_TRAP)

  debug::StackTrace().Print();

#if defined(OS_LINUX)
#if ARCH_CPU_X86_FAMILY
  ucontext_t* context = reinterpret_cast<ucontext_t*>(void_context);
  const struct {
    const char* label;
    greg_t value;
  } registers[] = {
#if ARCH_CPU_32_BITS
    { "  gs: ", context->uc_mcontext.gregs[REG_GS] },
    { "  fs: ", context->uc_mcontext.gregs[REG_FS] },
    { "  es: ", context->uc_mcontext.gregs[REG_ES] },
    { "  ds: ", context->uc_mcontext.gregs[REG_DS] },
    { " edi: ", context->uc_mcontext.gregs[REG_EDI] },
    { " esi: ", context->uc_mcontext.gregs[REG_ESI] },
    { " ebp: ", context->uc_mcontext.gregs[REG_EBP] },
    { " esp: ", context->uc_mcontext.gregs[REG_ESP] },
    { " ebx: ", context->uc_mcontext.gregs[REG_EBX] },
    { " edx: ", context->uc_mcontext.gregs[REG_EDX] },
    { " ecx: ", context->uc_mcontext.gregs[REG_ECX] },
    { " eax: ", context->uc_mcontext.gregs[REG_EAX] },
    { " trp: ", context->uc_mcontext.gregs[REG_TRAPNO] },
    { " err: ", context->uc_mcontext.gregs[REG_ERR] },
    { "  ip: ", context->uc_mcontext.gregs[REG_EIP] },
    { "  cs: ", context->uc_mcontext.gregs[REG_CS] },
    { " efl: ", context->uc_mcontext.gregs[REG_EFL] },
    { " usp: ", context->uc_mcontext.gregs[REG_UESP] },
    { "  ss: ", context->uc_mcontext.gregs[REG_SS] },
#elif ARCH_CPU_64_BITS
    { "  r8: ", context->uc_mcontext.gregs[REG_R8] },
    { "  r9: ", context->uc_mcontext.gregs[REG_R9] },
    { " r10: ", context->uc_mcontext.gregs[REG_R10] },
    { " r11: ", context->uc_mcontext.gregs[REG_R11] },
    { " r12: ", context->uc_mcontext.gregs[REG_R12] },
    { " r13: ", context->uc_mcontext.gregs[REG_R13] },
    { " r14: ", context->uc_mcontext.gregs[REG_R14] },
    { " r15: ", context->uc_mcontext.gregs[REG_R15] },
    { "  di: ", context->uc_mcontext.gregs[REG_RDI] },
    { "  si: ", context->uc_mcontext.gregs[REG_RSI] },
    { "  bp: ", context->uc_mcontext.gregs[REG_RBP] },
    { "  bx: ", context->uc_mcontext.gregs[REG_RBX] },
    { "  dx: ", context->uc_mcontext.gregs[REG_RDX] },
    { "  ax: ", context->uc_mcontext.gregs[REG_RAX] },
    { "  cx: ", context->uc_mcontext.gregs[REG_RCX] },
    { "  sp: ", context->uc_mcontext.gregs[REG_RSP] },
    { "  ip: ", context->uc_mcontext.gregs[REG_RIP] },
    { " efl: ", context->uc_mcontext.gregs[REG_EFL] },
    { " cgf: ", context->uc_mcontext.gregs[REG_CSGSFS] },
    { " erf: ", context->uc_mcontext.gregs[REG_ERR] },
    { " trp: ", context->uc_mcontext.gregs[REG_TRAPNO] },
    { " msk: ", context->uc_mcontext.gregs[REG_OLDMASK] },
    { " cr2: ", context->uc_mcontext.gregs[REG_CR2] },
#endif  // ARCH_CPU_32_BITS
  };

#if ARCH_CPU_32_BITS
  const int kRegisterPadding = 8;
#elif ARCH_CPU_64_BITS
  const int kRegisterPadding = 16;
#endif

  for (size_t i = 0; i < arraysize(registers); i++) {
    PrintToStderr(registers[i].label);
    internal::itoa_r(registers[i].value, buf, sizeof(buf),
                     16, kRegisterPadding);
    PrintToStderr(buf);

    if ((i + 1) % 4 == 0)
      PrintToStderr("\n");
  }
  PrintToStderr("\n");
#endif  // ARCH_CPU_X86_FAMILY
#endif  // defined(OS_LINUX)

  PrintToStderr("[end of stack trace]\n");

#if defined(OS_MACOSX) && !defined(OS_IOS)
  if (::signal(signal, SIG_DFL) == SIG_ERR)
    _exit(1);
#else
  // Non-Mac OSes should probably reraise the signal as well, but the Linux
  // sandbox tests break on CrOS devices.
  // https://code.google.com/p/chromium/issues/detail?id=551681
  PrintToStderr("Calling _exit(1). Core file will not be generated.\n");
  _exit(1);
#endif  // defined(OS_MACOSX) && !defined(OS_IOS)
}

class PrintBacktraceOutputHandler : public BacktraceOutputHandler {
 public:
  PrintBacktraceOutputHandler() = default;

  void HandleOutput(const char* output) override {
    // NOTE: This code MUST be async-signal safe (it's used by in-process
    // stack dumping signal handler). NO malloc or stdio is allowed here.
    PrintToStderr(output);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(PrintBacktraceOutputHandler);
};

class StreamBacktraceOutputHandler : public BacktraceOutputHandler {
 public:
  explicit StreamBacktraceOutputHandler(std::ostream* os) : os_(os) {
  }

  void HandleOutput(const char* output) override { (*os_) << output; }

 private:
  std::ostream* os_;

  DISALLOW_COPY_AND_ASSIGN(StreamBacktraceOutputHandler);
};

void WarmUpBacktrace() {
  // Warm up stack trace infrastructure. It turns out that on the first
  // call glibc initializes some internal data structures using pthread_once,
  // and even backtrace() can call malloc(), leading to hangs.
  //
  // Example stack trace snippet (with tcmalloc):
  //
  // #8  0x0000000000a173b5 in tc_malloc
  //             at ./third_party/tcmalloc/chromium/src/debugallocation.cc:1161
  // #9  0x00007ffff7de7900 in _dl_map_object_deps at dl-deps.c:517
  // #10 0x00007ffff7ded8a9 in dl_open_worker at dl-open.c:262
  // #11 0x00007ffff7de9176 in _dl_catch_error at dl-error.c:178
  // #12 0x00007ffff7ded31a in _dl_open (file=0x7ffff625e298 "libgcc_s.so.1")
  //             at dl-open.c:639
  // #13 0x00007ffff6215602 in do_dlopen at dl-libc.c:89
  // #14 0x00007ffff7de9176 in _dl_catch_error at dl-error.c:178
  // #15 0x00007ffff62156c4 in dlerror_run at dl-libc.c:48
  // #16 __GI___libc_dlopen_mode at dl-libc.c:165
  // #17 0x00007ffff61ef8f5 in init
  //             at ../sysdeps/x86_64/../ia64/backtrace.c:53
  // #18 0x00007ffff6aad400 in pthread_once
  //             at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S:104
  // #19 0x00007ffff61efa14 in __GI___backtrace
  //             at ../sysdeps/x86_64/../ia64/backtrace.c:104
  // #20 0x0000000000752a54 in base::debug::StackTrace::StackTrace
  //             at base/debug/stack_trace_posix.cc:175
  // #21 0x00000000007a4ae5 in
  //             base::(anonymous namespace)::StackDumpSignalHandler
  //             at base/process_util_posix.cc:172
  // #22 <signal handler called>
  StackTrace stack_trace;
}

#if defined(USE_SYMBOLIZE)

// class SandboxSymbolizeHelper.
//
// The purpose of this class is to prepare and install a "file open" callback
// needed by the stack trace symbolization code
// (base/third_party/symbolize/symbolize.h) so that it can function properly
// in a sandboxed process.  The caveat is that this class must be instantiated
// before the sandboxing is enabled so that it can get the chance to open all
// the object files that are loaded in the virtual address space of the current
// process.
class SandboxSymbolizeHelper {
 public:
  // Returns the singleton instance.
  static SandboxSymbolizeHelper* GetInstance() {
    return Singleton<SandboxSymbolizeHelper,
                     LeakySingletonTraits<SandboxSymbolizeHelper>>::get();
  }

 private:
  friend struct DefaultSingletonTraits<SandboxSymbolizeHelper>;

  SandboxSymbolizeHelper()
      : is_initialized_(false) {
    Init();
  }

  ~SandboxSymbolizeHelper() {
    UnregisterCallback();
    CloseObjectFiles();
  }

  // Returns a O_RDONLY file descriptor for |file_path| if it was opened
  // successfully during the initialization.  The file is repositioned at
  // offset 0.
  // IMPORTANT: This function must be async-signal-safe because it can be
  // called from a signal handler (symbolizing stack frames for a crash).
  int GetFileDescriptor(const char* file_path) {
    int fd = -1;

#if !defined(OFFICIAL_BUILD)
    if (file_path) {
      // The assumption here is that iterating over std::map<std::string, int>
      // using a const_iterator does not allocate dynamic memory, hense it is
      // async-signal-safe.
      std::map<std::string, int>::const_iterator it;
      for (it = modules_.begin(); it != modules_.end(); ++it) {
        if (strcmp((it->first).c_str(), file_path) == 0) {
          // POSIX.1-2004 requires an implementation to guarantee that dup()
          // is async-signal-safe.
          fd = HANDLE_EINTR(dup(it->second));
          break;
        }
      }
      // POSIX.1-2004 requires an implementation to guarantee that lseek()
      // is async-signal-safe.
      if (fd >= 0 && lseek(fd, 0, SEEK_SET) < 0) {
        // Failed to seek.
        fd = -1;
      }
    }
#endif  // !defined(OFFICIAL_BUILD)

    return fd;
  }

  // Searches for the object file (from /proc/self/maps) that contains
  // the specified pc.  If found, sets |start_address| to the start address
  // of where this object file is mapped in memory, sets the module base
  // address into |base_address|, copies the object file name into
  // |out_file_name|, and attempts to open the object file.  If the object
  // file is opened successfully, returns the file descriptor.  Otherwise,
  // returns -1.  |out_file_name_size| is the size of the file name buffer
  // (including the null terminator).
  // IMPORTANT: This function must be async-signal-safe because it can be
  // called from a signal handler (symbolizing stack frames for a crash).
  static int OpenObjectFileContainingPc(uint64_t pc, uint64_t& start_address,
                                        uint64_t& base_address, char* file_path,
                                        int file_path_size) {
    // This method can only be called after the singleton is instantiated.
    // This is ensured by the following facts:
    // * This is the only static method in this class, it is private, and
    //   the class has no friends (except for the DefaultSingletonTraits).
    //   The compiler guarantees that it can only be called after the
    //   singleton is instantiated.
    // * This method is used as a callback for the stack tracing code and
    //   the callback registration is done in the constructor, so logically
    //   it cannot be called before the singleton is created.
    SandboxSymbolizeHelper* instance = GetInstance();

    // The assumption here is that iterating over
    // std::vector<MappedMemoryRegion> using a const_iterator does not allocate
    // dynamic memory, hence it is async-signal-safe.
    for (const MappedMemoryRegion& region : instance->regions_) {
      if (region.start <= pc && pc < region.end) {
        start_address = region.start;
        base_address = region.base;
        if (file_path && file_path_size > 0) {
          strncpy(file_path, region.path.c_str(), file_path_size);
          // Ensure null termination.
          file_path[file_path_size - 1] = '\0';
        }
        return instance->GetFileDescriptor(region.path.c_str());
      }
    }
    return -1;
  }

  // Set the base address for each memory region by reading ELF headers in
  // process memory.
  void SetBaseAddressesForMemoryRegions() {
    base::ScopedFD mem_fd(
        HANDLE_EINTR(open("/proc/self/mem", O_RDONLY | O_CLOEXEC)));
    if (!mem_fd.is_valid())
      return;

    auto safe_memcpy = [&mem_fd](void* dst, uintptr_t src, size_t size) {
      return HANDLE_EINTR(pread(mem_fd.get(), dst, size, src)) == ssize_t(size);
    };

    uintptr_t cur_base = 0;
    for (auto& r : regions_) {
      ElfW(Ehdr) ehdr;
      static_assert(SELFMAG <= sizeof(ElfW(Ehdr)), "SELFMAG too large");
      if ((r.permissions & MappedMemoryRegion::READ) &&
          safe_memcpy(&ehdr, r.start, sizeof(ElfW(Ehdr))) &&
          memcmp(ehdr.e_ident, ELFMAG, SELFMAG) == 0) {
        switch (ehdr.e_type) {
          case ET_EXEC:
            cur_base = 0;
            break;
          case ET_DYN:
            // Find the segment containing file offset 0. This will correspond
            // to the ELF header that we just read. Normally this will have
            // virtual address 0, but this is not guaranteed. We must subtract
            // the virtual address from the address where the ELF header was
            // mapped to get the base address.
            //
            // If we fail to find a segment for file offset 0, use the address
            // of the ELF header as the base address.
            cur_base = r.start;
            for (unsigned i = 0; i != ehdr.e_phnum; ++i) {
              ElfW(Phdr) phdr;
              if (safe_memcpy(&phdr, r.start + ehdr.e_phoff + i * sizeof(phdr),
                              sizeof(phdr)) &&
                  phdr.p_type == PT_LOAD && phdr.p_offset == 0) {
                cur_base = r.start - phdr.p_vaddr;
                break;
              }
            }
            break;
          default:
            // ET_REL or ET_CORE. These aren't directly executable, so they
            // don't affect the base address.
            break;
        }
      }

      r.base = cur_base;
    }
  }

  // Parses /proc/self/maps in order to compile a list of all object file names
  // for the modules that are loaded in the current process.
  // Returns true on success.
  bool CacheMemoryRegions() {
    // Reads /proc/self/maps.
    std::string contents;
    if (!ReadProcMaps(&contents)) {
      LOG(ERROR) << "Failed to read /proc/self/maps";
      return false;
    }

    // Parses /proc/self/maps.
    if (!ParseProcMaps(contents, &regions_)) {
      LOG(ERROR) << "Failed to parse the contents of /proc/self/maps";
      return false;
    }

    SetBaseAddressesForMemoryRegions();

    is_initialized_ = true;
    return true;
  }

  // Opens all object files and caches their file descriptors.
  void OpenSymbolFiles() {
    // Pre-opening and caching the file descriptors of all loaded modules is
    // not safe for production builds.  Hence it is only done in non-official
    // builds.  For more details, take a look at: http://crbug.com/341966.
#if !defined(OFFICIAL_BUILD)
    // Open the object files for all read-only executable regions and cache
    // their file descriptors.
    std::vector<MappedMemoryRegion>::const_iterator it;
    for (it = regions_.begin(); it != regions_.end(); ++it) {
      const MappedMemoryRegion& region = *it;
      // Only interesed in read-only executable regions.
      if ((region.permissions & MappedMemoryRegion::READ) ==
              MappedMemoryRegion::READ &&
          (region.permissions & MappedMemoryRegion::WRITE) == 0 &&
          (region.permissions & MappedMemoryRegion::EXECUTE) ==
              MappedMemoryRegion::EXECUTE) {
        if (region.path.empty()) {
          // Skip regions with empty file names.
          continue;
        }
        if (region.path[0] == '[') {
          // Skip pseudo-paths, like [stack], [vdso], [heap], etc ...
          continue;
        }
        if (base::EndsWith(region.path, " (deleted)",
                           base::CompareCase::SENSITIVE)) {
          // Skip deleted files.
          continue;
        }
        // Avoid duplicates.
        if (modules_.find(region.path) == modules_.end()) {
          int fd = open(region.path.c_str(), O_RDONLY | O_CLOEXEC);
          if (fd >= 0) {
            modules_.insert(std::make_pair(region.path, fd));
          } else {
            LOG(WARNING) << "Failed to open file: " << region.path
                         << "\n  Error: " << strerror(errno);
          }
        }
      }
    }
#endif  // !defined(OFFICIAL_BUILD)
  }

  // Initializes and installs the symbolization callback.
  void Init() {
    if (CacheMemoryRegions()) {
      OpenSymbolFiles();
      google::InstallSymbolizeOpenObjectFileCallback(
          &OpenObjectFileContainingPc);
    }
  }

  // Unregister symbolization callback.
  void UnregisterCallback() {
    if (is_initialized_) {
      google::InstallSymbolizeOpenObjectFileCallback(nullptr);
      is_initialized_ = false;
    }
  }

  // Closes all file descriptors owned by this instance.
  void CloseObjectFiles() {
#if !defined(OFFICIAL_BUILD)
    std::map<std::string, int>::iterator it;
    for (it = modules_.begin(); it != modules_.end(); ++it) {
      int ret = IGNORE_EINTR(close(it->second));
      DCHECK(!ret);
      it->second = -1;
    }
    modules_.clear();
#endif  // !defined(OFFICIAL_BUILD)
  }

  // Set to true upon successful initialization.
  bool is_initialized_;

#if !defined(OFFICIAL_BUILD)
  // Mapping from file name to file descriptor.  Includes file descriptors
  // for all successfully opened object files and the file descriptor for
  // /proc/self/maps.  This code is not safe for production builds.
  std::map<std::string, int> modules_;
#endif  // !defined(OFFICIAL_BUILD)

  // Cache for the process memory regions.  Produced by parsing the contents
  // of /proc/self/maps cache.
  std::vector<MappedMemoryRegion> regions_;

  DISALLOW_COPY_AND_ASSIGN(SandboxSymbolizeHelper);
};
#endif  // USE_SYMBOLIZE

}  // namespace

bool EnableInProcessStackDumping() {
#if defined(USE_SYMBOLIZE)
  SandboxSymbolizeHelper::GetInstance();
#endif  // USE_SYMBOLIZE

  // When running in an application, our code typically expects SIGPIPE
  // to be ignored.  Therefore, when testing that same code, it should run
  // with SIGPIPE ignored as well.
  struct sigaction sigpipe_action;
  memset(&sigpipe_action, 0, sizeof(sigpipe_action));
  sigpipe_action.sa_handler = SIG_IGN;
  sigemptyset(&sigpipe_action.sa_mask);
  bool success = (sigaction(SIGPIPE, &sigpipe_action, nullptr) == 0);

  // Avoid hangs during backtrace initialization, see above.
  WarmUpBacktrace();

  struct sigaction action;
  memset(&action, 0, sizeof(action));
  action.sa_flags = SA_RESETHAND | SA_SIGINFO;
  action.sa_sigaction = &StackDumpSignalHandler;
  sigemptyset(&action.sa_mask);

  success &= (sigaction(SIGILL, &action, nullptr) == 0);
  success &= (sigaction(SIGABRT, &action, nullptr) == 0);
  success &= (sigaction(SIGFPE, &action, nullptr) == 0);
  success &= (sigaction(SIGBUS, &action, nullptr) == 0);
  success &= (sigaction(SIGSEGV, &action, nullptr) == 0);
// On Linux, SIGSYS is reserved by the kernel for seccomp-bpf sandboxing.
#if !defined(OS_LINUX)
  success &= (sigaction(SIGSYS, &action, nullptr) == 0);
#endif  // !defined(OS_LINUX)

  return success;
}

void SetStackDumpFirstChanceCallback(bool (*handler)(int, void*, void*)) {
  DCHECK(try_handle_signal == nullptr || handler == nullptr);
  try_handle_signal = handler;
}

StackTrace::StackTrace(size_t count) {
// NOTE: This code MUST be async-signal safe (it's used by in-process
// stack dumping signal handler). NO malloc or stdio is allowed here.

#if !defined(__UCLIBC__) && !defined(_AIX)
  count = std::min(arraysize(trace_), count);

  // Though the backtrace API man page does not list any possible negative
  // return values, we take no chance.
  count_ = base::saturated_cast<size_t>(backtrace(trace_, count));
#else
  count_ = 0;
#endif
}

void StackTrace::PrintWithPrefix(const char* prefix_string) const {
// NOTE: This code MUST be async-signal safe (it's used by in-process
// stack dumping signal handler). NO malloc or stdio is allowed here.

#if !defined(__UCLIBC__) && !defined(_AIX)
  PrintBacktraceOutputHandler handler;
  ProcessBacktrace(trace_, count_, prefix_string, &handler);
#endif
}

#if !defined(__UCLIBC__) && !defined(_AIX)
void StackTrace::OutputToStreamWithPrefix(std::ostream* os,
                                          const char* prefix_string) const {
  StreamBacktraceOutputHandler handler(os);
  ProcessBacktrace(trace_, count_, prefix_string, &handler);
}
#endif

namespace internal {

// NOTE: code from sandbox/linux/seccomp-bpf/demo.cc.
char* itoa_r(intptr_t i, char* buf, size_t sz, int base, size_t padding) {
  // Make sure we can write at least one NUL byte.
  size_t n = 1;
  if (n > sz)
    return nullptr;

  if (base < 2 || base > 16) {
    buf[0] = '\000';
    return nullptr;
  }

  char* start = buf;

  uintptr_t j = i;

  // Handle negative numbers (only for base 10).
  if (i < 0 && base == 10) {
    // This does "j = -i" while avoiding integer overflow.
    j = static_cast<uintptr_t>(-(i + 1)) + 1;

    // Make sure we can write the '-' character.
    if (++n > sz) {
      buf[0] = '\000';
      return nullptr;
    }
    *start++ = '-';
  }

  // Loop until we have converted the entire number. Output at least one
  // character (i.e. '0').
  char* ptr = start;
  do {
    // Make sure there is still enough space left in our output buffer.
    if (++n > sz) {
      buf[0] = '\000';
      return nullptr;
    }

    // Output the next digit.
    *ptr++ = "0123456789abcdef"[j % base];
    j /= base;

    if (padding > 0)
      padding--;
  } while (j > 0 || padding > 0);

  // Terminate the output with a NUL character.
  *ptr = '\000';

  // Conversion to ASCII actually resulted in the digits being in reverse
  // order. We can't easily generate them in forward order, as we can't tell
  // the number of characters needed until we are done converting.
  // So, now, we reverse the string (except for the possible "-" sign).
  while (--ptr > start) {
    char ch = *ptr;
    *ptr = *start;
    *start++ = ch;
  }
  return buf;
}

}  // namespace internal

}  // namespace debug
}  // namespace base
