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

Commit 2bc6196f authored by Josh Gao's avatar Josh Gao Committed by Gerrit Code Review
Browse files

Merge "debuggerd_handler: use syscall(__NR_get[pt]id) instead of get[pt]id."

parents ee9e5d09 2e7b8e2d
Loading
Loading
Loading
Loading
+35 −3
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@


#include <android-base/file.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/logging.h>
#include <android-base/macros.h>
#include <android-base/parseint.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <android-base/strings.h>
@@ -149,7 +150,7 @@ class CrasherTest : public ::testing::Test {
  // Returns -1 if we fail to read a response from tombstoned, otherwise the received return code.
  // Returns -1 if we fail to read a response from tombstoned, otherwise the received return code.
  void FinishIntercept(int* result);
  void FinishIntercept(int* result);


  void StartProcess(std::function<void()> function);
  void StartProcess(std::function<void()> function, std::function<pid_t()> forker = fork);
  void StartCrasher(const std::string& crash_type);
  void StartCrasher(const std::string& crash_type);
  void FinishCrasher();
  void FinishCrasher();
  void AssertDeath(int signo);
  void AssertDeath(int signo);
@@ -195,14 +196,14 @@ void CrasherTest::FinishIntercept(int* result) {
  }
  }
}
}


void CrasherTest::StartProcess(std::function<void()> function) {
void CrasherTest::StartProcess(std::function<void()> function, std::function<pid_t()> forker) {
  unique_fd read_pipe;
  unique_fd read_pipe;
  unique_fd crasher_read_pipe;
  unique_fd crasher_read_pipe;
  if (!Pipe(&crasher_read_pipe, &crasher_pipe)) {
  if (!Pipe(&crasher_read_pipe, &crasher_pipe)) {
    FAIL() << "failed to create pipe: " << strerror(errno);
    FAIL() << "failed to create pipe: " << strerror(errno);
  }
  }


  crasher_pid = fork();
  crasher_pid = forker();
  if (crasher_pid == -1) {
  if (crasher_pid == -1) {
    FAIL() << "fork failed: " << strerror(errno);
    FAIL() << "fork failed: " << strerror(errno);
  } else if (crasher_pid == 0) {
  } else if (crasher_pid == 0) {
@@ -527,6 +528,37 @@ TEST_F(CrasherTest, capabilities) {
  ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(tgkill)");
  ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(tgkill)");
}
}


TEST_F(CrasherTest, fake_pid) {
  int intercept_result;
  unique_fd output_fd;

  // Prime the getpid/gettid caches.
  UNUSED(getpid());
  UNUSED(gettid());

  std::function<pid_t()> clone_fn = []() {
    return syscall(__NR_clone, SIGCHLD, nullptr, nullptr, nullptr, nullptr);
  };
  StartProcess(
      []() {
        ASSERT_NE(getpid(), syscall(__NR_getpid));
        ASSERT_NE(gettid(), syscall(__NR_gettid));
        raise(SIGSEGV);
      },
      clone_fn);

  StartIntercept(&output_fd);
  FinishCrasher();
  AssertDeath(SIGSEGV);
  FinishIntercept(&intercept_result);

  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);
  ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(tgkill)");
}

TEST(crash_dump, zombie) {
TEST(crash_dump, zombie) {
  pid_t forkpid = fork();
  pid_t forkpid = fork();


+15 −5
Original line number Original line Diff line number Diff line
@@ -61,6 +61,16 @@


#define CRASH_DUMP_PATH "/system/bin/" CRASH_DUMP_NAME
#define CRASH_DUMP_PATH "/system/bin/" CRASH_DUMP_NAME


// Wrappers that directly invoke the respective syscalls, in case the cached values are invalid.
#pragma GCC poison getpid gettid
static pid_t __getpid() {
  return syscall(__NR_getpid);
}

static pid_t __gettid() {
  return syscall(__NR_gettid);
}

static inline void futex_wait(volatile void* ftx, int value) {
static inline void futex_wait(volatile void* ftx, int value) {
  syscall(__NR_futex, ftx, FUTEX_WAIT, value, nullptr, nullptr, 0);
  syscall(__NR_futex, ftx, FUTEX_WAIT, value, nullptr, nullptr, 0);
}
}
@@ -124,7 +134,7 @@ static void log_signal_summary(int signum, const siginfo_t* info) {
  }
  }


  if (signum == DEBUGGER_SIGNAL) {
  if (signum == DEBUGGER_SIGNAL) {
    async_safe_format_log(ANDROID_LOG_INFO, "libc", "Requested dump for tid %d (%s)", gettid(),
    async_safe_format_log(ANDROID_LOG_INFO, "libc", "Requested dump for tid %d (%s)", __gettid(),
                          thread_name);
                          thread_name);
    return;
    return;
  }
  }
@@ -177,7 +187,7 @@ static void log_signal_summary(int signum, const siginfo_t* info) {
  }
  }


  async_safe_format_log(ANDROID_LOG_FATAL, "libc", "Fatal signal %d (%s)%s%s in tid %d (%s)",
  async_safe_format_log(ANDROID_LOG_FATAL, "libc", "Fatal signal %d (%s)%s%s in tid %d (%s)",
                        signum, signal_name, code_desc, addr_desc, gettid(), thread_name);
                        signum, signal_name, code_desc, addr_desc, __gettid(), thread_name);
}
}


/*
/*
@@ -337,7 +347,7 @@ static void resend_signal(siginfo_t* info, bool crash_dump_started) {
  // rt_tgsigqueueinfo(2) to preserve SA_SIGINFO) will cause it to be delivered
  // rt_tgsigqueueinfo(2) to preserve SA_SIGINFO) will cause it to be delivered
  // when our signal handler returns.
  // when our signal handler returns.
  if (crash_dump_started || info->si_signo != DEBUGGER_SIGNAL) {
  if (crash_dump_started || info->si_signo != DEBUGGER_SIGNAL) {
    int rc = syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), info->si_signo, info);
    int rc = syscall(SYS_rt_tgsigqueueinfo, __getpid(), __gettid(), info->si_signo, info);
    if (rc != 0) {
    if (rc != 0) {
      fatal_errno("failed to resend signal during crash");
      fatal_errno("failed to resend signal during crash");
    }
    }
@@ -362,7 +372,7 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* c
    memset(&si, 0, sizeof(si));
    memset(&si, 0, sizeof(si));
    si.si_signo = signal_number;
    si.si_signo = signal_number;
    si.si_code = SI_USER;
    si.si_code = SI_USER;
    si.si_pid = getpid();
    si.si_pid = __getpid();
    si.si_uid = getuid();
    si.si_uid = getuid();
    info = &si;
    info = &si;
  } else if (info->si_code >= 0 || info->si_code == SI_TKILL) {
  } else if (info->si_code >= 0 || info->si_code == SI_TKILL) {
@@ -404,7 +414,7 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* c
  debugger_thread_info thread_info = {
  debugger_thread_info thread_info = {
    .crash_dump_started = false,
    .crash_dump_started = false,
    .pseudothread_tid = -1,
    .pseudothread_tid = -1,
    .crashing_tid = gettid(),
    .crashing_tid = __gettid(),
    .signal_number = signal_number,
    .signal_number = signal_number,
    .info = info
    .info = info
  };
  };