#include "snapshot/linux/process_reader_linux.h"
#include <elf.h>
#include <errno.h>
#include <sched.h>
#include <string.h>
#include <sys/resource.h>
#include <unistd.h>
#include <algorithm>
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "snapshot/linux/debug_rendezvous.h"
#include "util/linux/auxiliary_vector.h"
#include "util/linux/proc_stat_reader.h"
#if BUILDFLAG(IS_ANDROID)
#include <android/api-level.h>
#endif
namespace crashpad {
namespace {
bool ShouldMergeStackMappings(const MemoryMap::Mapping& stack_mapping,
const MemoryMap::Mapping& adj_mapping) { … }
}
ProcessReaderLinux::Thread::Thread()
: … { … }
ProcessReaderLinux::Thread::~Thread() { … }
bool ProcessReaderLinux::Thread::InitializePtrace(
PtraceConnection* connection) { … }
void ProcessReaderLinux::Thread::InitializeStack(ProcessReaderLinux* reader) { … }
void ProcessReaderLinux::Thread::InitializeStackFromSP(
ProcessReaderLinux* reader,
LinuxVMAddress stack_pointer) { … }
ProcessReaderLinux::Module::Module()
: … { … }
ProcessReaderLinux::Module::~Module() = default;
ProcessReaderLinux::ProcessReaderLinux()
: … { … }
ProcessReaderLinux::~ProcessReaderLinux() { … }
bool ProcessReaderLinux::Initialize(PtraceConnection* connection) { … }
bool ProcessReaderLinux::StartTime(timeval* start_time) const { … }
bool ProcessReaderLinux::CPUTimes(timeval* user_time,
timeval* system_time) const { … }
const std::vector<ProcessReaderLinux::Thread>& ProcessReaderLinux::Threads() { … }
const std::vector<ProcessReaderLinux::Module>& ProcessReaderLinux::Modules() { … }
void ProcessReaderLinux::InitializeAbortMessage() { … }
#if BUILDFLAG(IS_ANDROID)
template <bool is64Bit>
struct abort_msg_t {
uint32_t size;
char msg[0];
};
template <>
struct abort_msg_t<true> {
uint64_t size;
char msg[0];
};
template <bool is64Bit>
struct magic_abort_msg_t {
uint64_t magic1;
uint64_t magic2;
abort_msg_t<is64Bit> msg;
};
template <bool is64Bit>
void ProcessReaderLinux::ReadAbortMessage(const MemoryMap::Mapping* mapping) {
magic_abort_msg_t<is64Bit> header;
if (!Memory()->Read(
mapping->range.Base(), sizeof(magic_abort_msg_t<is64Bit>), &header)) {
return;
}
size_t size = header.msg.size - sizeof(magic_abort_msg_t<is64Bit>) - 1;
if (header.magic1 != 0xb18e40886ac388f0ULL ||
header.magic2 != 0xc6dfba755a1de0b5ULL ||
mapping->range.Size() <
offsetof(magic_abort_msg_t<is64Bit>, msg.msg) + size) {
return;
}
abort_message_.resize(size);
if (!Memory()->Read(
mapping->range.Base() + offsetof(magic_abort_msg_t<is64Bit>, msg.msg),
size,
&abort_message_[0])) {
abort_message_.clear();
}
}
#endif
const std::string& ProcessReaderLinux::AbortMessage() { … }
void ProcessReaderLinux::InitializeThreads() { … }
void ProcessReaderLinux::InitializeModules() { … }
}