Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 843f7e64 authored by Peter Collingbourne's avatar Peter Collingbourne
Browse files

Create a ProcessInfo structure with the process-wide information from the crasher.

We're now passing around a couple of addresses for GWP-ASan in addition
to abort_msg_address and fdsan_table_address, and I'm going to need to add
more of them for MTE. Move them into a data structure in order to simplify
various function signatures.

Bug: 135772972
Change-Id: Ie01e1bd93a9ab64f21865f56574696825a6a125f
parent ad9d034e
Loading
Loading
Loading
Loading
+11 −20
Original line number Diff line number Diff line
@@ -254,9 +254,7 @@ static void ParseArgs(int argc, char** argv, pid_t* pseudothread_tid, DebuggerdD
}

static void ReadCrashInfo(unique_fd& fd, siginfo_t* siginfo,
                          std::unique_ptr<unwindstack::Regs>* regs, uintptr_t* abort_msg_address,
                          uintptr_t* fdsan_table_address, uintptr_t* gwp_asan_state,
                          uintptr_t* gwp_asan_metadata) {
                          std::unique_ptr<unwindstack::Regs>* regs, ProcessInfo* process_info) {
  std::aligned_storage<sizeof(CrashInfo) + 1, alignof(CrashInfo)>::type buf;
  CrashInfo* crash_info = reinterpret_cast<CrashInfo*>(&buf);
  ssize_t rc = TEMP_FAILURE_RETRY(read(fd.get(), &buf, sizeof(buf)));
@@ -288,19 +286,16 @@ static void ReadCrashInfo(unique_fd& fd, siginfo_t* siginfo,
    }
  }

  *fdsan_table_address = 0;
  *gwp_asan_state = 0;
  *gwp_asan_metadata = 0;
  switch (crash_info->header.version) {
    case 3:
      *gwp_asan_state = crash_info->data.v3.gwp_asan_state;
      *gwp_asan_metadata = crash_info->data.v3.gwp_asan_metadata;
      process_info->gwp_asan_state = crash_info->data.v3.gwp_asan_state;
      process_info->gwp_asan_metadata = crash_info->data.v3.gwp_asan_metadata;
      FALLTHROUGH_INTENDED;
    case 2:
      *fdsan_table_address = crash_info->data.v2.fdsan_table_address;
      process_info->fdsan_table_address = crash_info->data.v2.fdsan_table_address;
      FALLTHROUGH_INTENDED;
    case 1:
      *abort_msg_address = crash_info->data.v1.abort_msg_address;
      process_info->abort_msg_address = crash_info->data.v1.abort_msg_address;
      *siginfo = crash_info->data.v1.siginfo;
      regs->reset(unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(),
                                                        &crash_info->data.v1.ucontext));
@@ -425,10 +420,7 @@ int main(int argc, char** argv) {
  ATRACE_NAME("after reparent");
  pid_t pseudothread_tid;
  DebuggerdDumpType dump_type;
  uintptr_t abort_msg_address = 0;
  uintptr_t fdsan_table_address = 0;
  uintptr_t gwp_asan_state = 0;
  uintptr_t gwp_asan_metadata = 0;
  ProcessInfo process_info;

  Initialize(argv);
  ParseArgs(argc, argv, &pseudothread_tid, &dump_type);
@@ -489,8 +481,7 @@ int main(int argc, char** argv) {

      if (thread == g_target_thread) {
        // Read the thread's registers along with the rest of the crash info out of the pipe.
        ReadCrashInfo(input_pipe, &siginfo, &info.registers, &abort_msg_address,
                      &fdsan_table_address, &gwp_asan_state, &gwp_asan_metadata);
        ReadCrashInfo(input_pipe, &siginfo, &info.registers, &process_info);
        info.siginfo = &siginfo;
        info.signo = info.siginfo->si_signo;
      } else {
@@ -599,14 +590,14 @@ int main(int argc, char** argv) {
  } else {
    {
      ATRACE_NAME("fdsan table dump");
      populate_fdsan_table(&open_files, unwinder.GetProcessMemory(), fdsan_table_address);
      populate_fdsan_table(&open_files, unwinder.GetProcessMemory(),
                           process_info.fdsan_table_address);
    }

    {
      ATRACE_NAME("engrave_tombstone");
      engrave_tombstone(std::move(g_output_fd), &unwinder, thread_info, g_target_thread,
                        abort_msg_address, &open_files, &amfd_data, gwp_asan_state,
                        gwp_asan_metadata);
      engrave_tombstone(std::move(g_output_fd), &unwinder, thread_info, g_target_thread, process_info,
                        &open_files, &amfd_data);
    }
  }

+4 −5
Original line number Diff line number Diff line
@@ -63,12 +63,11 @@ static const gwp_asan::AllocationMetadata* retrieve_gwp_asan_metadata(
}

GwpAsanCrashData::GwpAsanCrashData(unwindstack::Memory* process_memory,
                                   uintptr_t gwp_asan_state_ptr, uintptr_t gwp_asan_metadata_ptr,
                                   const ThreadInfo& thread_info) {
  if (!process_memory || !gwp_asan_metadata_ptr || !gwp_asan_state_ptr) return;
                                   const ProcessInfo& process_info, const ThreadInfo& thread_info) {
  if (!process_memory || !process_info.gwp_asan_metadata || !process_info.gwp_asan_state) return;
  // Extract the GWP-ASan regions from the dead process.
  if (!retrieve_gwp_asan_state(process_memory, gwp_asan_state_ptr, &state_)) return;
  metadata_.reset(retrieve_gwp_asan_metadata(process_memory, state_, gwp_asan_metadata_ptr));
  if (!retrieve_gwp_asan_state(process_memory, process_info.gwp_asan_state, &state_)) return;
  metadata_.reset(retrieve_gwp_asan_metadata(process_memory, state_, process_info.gwp_asan_metadata));
  if (!metadata_.get()) return;

  // Get the external crash address from the thread info.
+2 −2
Original line number Diff line number Diff line
@@ -38,8 +38,8 @@ class GwpAsanCrashData {
  // still be responsible, as it terminates when it detects an internal error
  // (double free, invalid free). In these cases, we will retrieve the fault
  // address from the GWP-ASan allocator's state.
  GwpAsanCrashData(unwindstack::Memory* process_memory, uintptr_t gwp_asan_state_ptr,
                   uintptr_t gwp_asan_metadata_ptr, const ThreadInfo& thread_info);
  GwpAsanCrashData(unwindstack::Memory* process_memory, const ProcessInfo& process_info,
                   const ThreadInfo& thread_info);

  // Is GWP-ASan responsible for this crash.
  bool CrashIsMine() const;
+4 −9
Original line number Diff line number Diff line
@@ -44,18 +44,13 @@ constexpr size_t kMaxFrames = 256;
int open_tombstone(std::string* path);

/* Creates a tombstone file and writes the crash dump to it. */
void engrave_tombstone(int tombstone_fd, unwindstack::Unwinder* unwinder,
                       const OpenFilesList* open_files, pid_t pid, pid_t tid,
                       const std::string& process_name, const std::map<pid_t, std::string>& threads,
                       uint64_t abort_msg_address, std::string* amfd_data);
void engrave_tombstone(android::base::unique_fd output_fd, unwindstack::Unwinder* unwinder,
                       const std::map<pid_t, ThreadInfo>& thread_info, pid_t target_thread,
                       const ProcessInfo& process_info, OpenFilesList* open_files,
                       std::string* amfd_data);

void engrave_tombstone_ucontext(int tombstone_fd, uint64_t abort_msg_address, siginfo_t* siginfo,
                                ucontext_t* ucontext);

void engrave_tombstone(android::base::unique_fd output_fd, unwindstack::Unwinder* unwinder,
                       const std::map<pid_t, ThreadInfo>& thread_info, pid_t target_thread,
                       uint64_t abort_msg_address, OpenFilesList* open_files,
                       std::string* amfd_data, uintptr_t gwp_asan_state,
                       uintptr_t gwp_asan_metadata);

#endif  // _DEBUGGERD_TOMBSTONE_H
+7 −0
Original line number Diff line number Diff line
@@ -35,3 +35,10 @@ struct ThreadInfo {
  int signo = 0;
  siginfo_t* siginfo = nullptr;
};

struct ProcessInfo {
  uintptr_t abort_msg_address = 0;
  uintptr_t fdsan_table_address = 0;
  uintptr_t gwp_asan_state = 0;
  uintptr_t gwp_asan_metadata = 0;
};
Loading