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

Commit f3217de3 authored by Christopher Ferris's avatar Christopher Ferris Committed by Gerrit Code Review
Browse files

Merge "Fix problems in libbacktrace."

parents 61afb07b a16a4e10
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <signal.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
#include <inttypes.h>

@@ -29,6 +30,8 @@

#define FINISH(pid) dump_frames(&backtrace); if (pid < 0) exit(1); else return false;

#define WAIT_INTERVAL_USECS   1000

// Prototypes for functions in the test library.
int test_level_one(int, int, int, int, bool (*)(pid_t));

@@ -52,6 +55,21 @@ void dump_frames(const backtrace_t* backtrace) {
  }
}

void wait_for_stop(pid_t pid, size_t max_usecs_to_wait) {
  siginfo_t si;
  size_t usecs_waited = 0;

  while (ptrace(PTRACE_GETSIGINFO, pid, 0, &si) < 0 && (errno == EINTR || errno == ESRCH)) {
    if (usecs_waited >= max_usecs_to_wait) {
      printf("The process did not get to a stopping point in %zu usecs.\n",
             usecs_waited);
      break;
    }
    usleep(WAIT_INTERVAL_USECS);
    usecs_waited += WAIT_INTERVAL_USECS;
  }
}

bool check_frame(const backtrace_t* backtrace, size_t frame_num,
                 const char* expected_name) {
  if (backtrace->frames[frame_num].proc_name == NULL) {
@@ -153,6 +171,10 @@ void verify_proc_test(pid_t pid, bool (*verify_func)(pid_t)) {
    kill(pid, SIGKILL);
    exit(1);
  }

  // Wait up to 1 second for the process to get to a point that we can trace it.
  wait_for_stop(pid, 1000000);

  bool pass = verify_func(pid);
  if (ptrace(PTRACE_DETACH, pid, 0, 0) != 0) {
    printf("Failed to detach from pid %d\n", pid);
+10 −3
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ static bool local_get_frames(backtrace_t* backtrace) {
  bool returnValue = true;
  backtrace->num_frames = 0;
  uintptr_t map_start;
  unw_word_t value;
  do {
    frame = &backtrace->frames[backtrace->num_frames];
    frame->stack_size = 0;
@@ -56,18 +57,21 @@ static bool local_get_frames(backtrace_t* backtrace) {
    frame->proc_name = NULL;
    frame->proc_offset = 0;

    ret = unw_get_reg(&cursor, UNW_REG_IP, &frame->pc);
    ret = unw_get_reg(&cursor, UNW_REG_IP, &value);
    if (ret < 0) {
      ALOGW("get_frames: Failed to read IP %d\n", ret);
      returnValue = false;
      break;
    }
    ret = unw_get_reg(&cursor, UNW_REG_SP, &frame->sp);
    frame->pc = (uintptr_t)value;
    ret = unw_get_reg(&cursor, UNW_REG_SP, &value);
    if (ret < 0) {
      ALOGW("get_frames: Failed to read IP %d\n", ret);
      returnValue = false;
      break;
    }
    frame->sp = (uintptr_t)value;

    if (backtrace->num_frames) {
      backtrace_frame_data_t* prev = &backtrace->frames[backtrace->num_frames-1];
      prev->stack_size = frame->sp - prev->sp;
@@ -111,8 +115,11 @@ char* local_get_proc_name(const backtrace_t* backtrace, uintptr_t pc,
  unw_context_t* context = (unw_context_t*)backtrace->private_data;
  char buf[512];

  *offset = 0;
  unw_word_t value;
  if (unw_get_proc_name_by_ip(unw_local_addr_space, pc, buf, sizeof(buf),
                              offset, context) >= 0 && buf[0] != '\0') {
                              &value, context) >= 0 && buf[0] != '\0') {
    *offset = (uintptr_t)value;
    char* symbol = demangle_symbol_name(buf);
    if (!symbol) {
      symbol = strdup(buf);
+10 −3
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ static bool remote_get_frames(backtrace_t* backtrace) {
  bool returnValue = true;
  backtrace->num_frames = 0;
  uintptr_t map_start;
  unw_word_t value;
  do {
    frame = &backtrace->frames[backtrace->num_frames];
    frame->stack_size = 0;
@@ -54,18 +55,21 @@ static bool remote_get_frames(backtrace_t* backtrace) {
    frame->proc_name = NULL;
    frame->proc_offset = 0;

    ret = unw_get_reg(&cursor, UNW_REG_IP, &frame->pc);
    ret = unw_get_reg(&cursor, UNW_REG_IP, &value);
    if (ret < 0) {
      ALOGW("remote_get_frames: Failed to read IP %d\n", ret);
      returnValue = false;
      break;
    }
    ret = unw_get_reg(&cursor, UNW_REG_SP, &frame->sp);
    frame->pc = (uintptr_t)value;
    ret = unw_get_reg(&cursor, UNW_REG_SP, &value);
    if (ret < 0) {
      ALOGW("remote_get_frames: Failed to read SP %d\n", ret);
      returnValue = false;
      break;
    }
    frame->sp = (uintptr_t)value;

    if (backtrace->num_frames) {
      backtrace_frame_data_t* prev = &backtrace->frames[backtrace->num_frames-1];
      prev->stack_size = frame->sp - prev->sp;
@@ -139,8 +143,11 @@ char* remote_get_proc_name(const backtrace_t* backtrace, uintptr_t pc,
  backtrace_private_t* data = (backtrace_private_t*)backtrace->private_data;
  char buf[512];

  if (unw_get_proc_name_by_ip(data->addr_space, pc, buf, sizeof(buf), offset,
  *offset = 0;
  unw_word_t value;
  if (unw_get_proc_name_by_ip(data->addr_space, pc, buf, sizeof(buf), &value,
                              data->upt_info) >= 0 && buf[0] != '\0') {
    *offset = (uintptr_t)value;
    char* symbol = demangle_symbol_name(buf);
    if (!symbol) {
      symbol = strdup(buf);