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

Commit 2a9da2ae authored by Peter Collingbourne's avatar Peter Collingbourne Committed by Gerrit Code Review
Browse files

Merge "Switch to the new kernel API for obtaining fault address tag bits."

parents 7e3d1570 ebc78cc8
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -299,11 +299,8 @@ static void ReadCrashInfo(unique_fd& fd, siginfo_t* siginfo,
      process_info->abort_msg_address = crash_info->data.s.abort_msg_address;
      *siginfo = crash_info->data.s.siginfo;
      if (signal_has_si_addr(siginfo)) {
        // Make a copy of the ucontext field because otherwise it is not aligned enough (due to
        // being in a packed struct) and clang complains about that.
        ucontext_t ucontext = crash_info->data.s.ucontext;
        process_info->has_fault_address = true;
        process_info->fault_address = get_fault_address(siginfo, &ucontext);
        process_info->fault_address = reinterpret_cast<uintptr_t>(siginfo->si_addr);
      }
      regs->reset(unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(),
                                                        &crash_info->data.s.ucontext));
+9 −4
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ static bool get_main_thread_name(char* buf, size_t len) {
 * mutex is being held, so we don't want to use any libc functions that
 * could allocate memory or hold a lock.
 */
static void log_signal_summary(const siginfo_t* info, const ucontext_t* ucontext) {
static void log_signal_summary(const siginfo_t* info) {
  char thread_name[MAX_TASK_NAME_LEN + 1];  // one more for termination
  if (prctl(PR_GET_NAME, reinterpret_cast<unsigned long>(thread_name), 0, 0, 0) != 0) {
    strcpy(thread_name, "<name unknown>");
@@ -186,8 +186,7 @@ static void log_signal_summary(const siginfo_t* info, const ucontext_t* ucontext
  // Many signals don't have an address or sender.
  char addr_desc[32] = "";  // ", fault addr 0x1234"
  if (signal_has_si_addr(info)) {
    async_safe_format_buffer(addr_desc, sizeof(addr_desc), ", fault addr %p",
                             reinterpret_cast<void*>(get_fault_address(info, ucontext)));
    async_safe_format_buffer(addr_desc, sizeof(addr_desc), ", fault addr %p", info->si_addr);
  }
  pid_t self_pid = __getpid();
  char sender_desc[32] = {};  // " from pid 1234, uid 666"
@@ -544,7 +543,7 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* c
    return;
  }

  log_signal_summary(info, ucontext);
  log_signal_summary(info);

  debugger_thread_info thread_info = {
      .crashing_tid = __gettid(),
@@ -638,5 +637,11 @@ void debuggerd_init(debuggerd_callbacks_t* callbacks) {

  // Use the alternate signal stack if available so we can catch stack overflows.
  action.sa_flags |= SA_ONSTACK;

#define SA_EXPOSE_TAGBITS 0x00000800
  // Request that the kernel set tag bits in the fault address. This is necessary for diagnosing MTE
  // faults.
  action.sa_flags |= SA_EXPOSE_TAGBITS;

  debuggerd_register_handlers(&action);
}
+0 −2
Original line number Diff line number Diff line
@@ -91,6 +91,4 @@ void get_signal_sender(char* buf, size_t n, const siginfo_t*);
const char* get_signame(const siginfo_t*);
const char* get_sigcode(const siginfo_t*);

uintptr_t get_fault_address(const siginfo_t* siginfo, const ucontext_t* ucontext);

#endif // _DEBUGGERD_UTILITY_H
+0 −37
Original line number Diff line number Diff line
@@ -451,40 +451,3 @@ void log_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* pref
    _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, unwinder->FormatFrame(i).c_str());
  }
}

#if defined(__aarch64__)
#define FAR_MAGIC 0x46415201

struct far_context {
  struct _aarch64_ctx head;
  __u64 far;
};
#endif

uintptr_t get_fault_address(const siginfo_t* siginfo, const ucontext_t* ucontext) {
  (void)ucontext;
#if defined(__aarch64__)
  // This relies on a kernel patch:
  //   https://patchwork.kernel.org/patch/11435077/
  // that hasn't been accepted into the kernel yet. TODO(pcc): Update this to
  // use the official interface once it lands.
  auto* begin = reinterpret_cast<const char*>(ucontext->uc_mcontext.__reserved);
  auto* end = begin + sizeof(ucontext->uc_mcontext.__reserved);
  auto* ptr = begin;
  while (1) {
    auto* ctx = reinterpret_cast<const _aarch64_ctx*>(ptr);
    if (ctx->magic == 0) {
      break;
    }
    if (ctx->magic == FAR_MAGIC) {
      auto* far_ctx = reinterpret_cast<const far_context*>(ctx);
      return far_ctx->far;
    }
    ptr += ctx->size;
    if (ctx->size % sizeof(void*) != 0 || ptr < begin || ptr >= end) {
      break;
    }
  }
#endif
  return reinterpret_cast<uintptr_t>(siginfo->si_addr);
}