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

Commit 123edd9f authored by Christopher Ferris's avatar Christopher Ferris
Browse files

resolved conflicts for merge of 04e13acd to master

Change-Id: I9bbc9907a5cbde8b374398493bc0dc6b056ea734
parents 59b0b568 04e13acd
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -64,7 +64,8 @@ static void get_tombstone_fds(tombstone_data_t data[NUM_TOMBSTONES]) {
    time_t thirty_minutes_ago = time(NULL) - 60*30;
    time_t thirty_minutes_ago = time(NULL) - 60*30;
    for (size_t i = 0; i < NUM_TOMBSTONES; i++) {
    for (size_t i = 0; i < NUM_TOMBSTONES; i++) {
        snprintf(data[i].name, sizeof(data[i].name), "%s%02zu", TOMBSTONE_FILE_PREFIX, i);
        snprintf(data[i].name, sizeof(data[i].name), "%s%02zu", TOMBSTONE_FILE_PREFIX, i);
        int fd = open(data[i].name, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
        int fd = TEMP_FAILURE_RETRY(open(data[i].name,
                                         O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK));
        struct stat st;
        struct stat st;
        if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode) &&
        if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode) &&
                (time_t) st.st_mtime >= thirty_minutes_ago) {
                (time_t) st.st_mtime >= thirty_minutes_ago) {
@@ -184,7 +185,8 @@ static void dumpstate() {
    if (!anr_traces_path[0]) {
    if (!anr_traces_path[0]) {
        printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
        printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
    } else {
    } else {
      int fd = open(anr_traces_path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
      int fd = TEMP_FAILURE_RETRY(open(anr_traces_path,
                                       O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK));
      if (fd < 0) {
      if (fd < 0) {
          printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno));
          printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno));
      } else {
      } else {
+3 −1
Original line number Original line Diff line number Diff line
@@ -30,7 +30,9 @@ typedef void (for_each_tid_func)(int, int, const char *);
/* prints the contents of a file */
/* prints the contents of a file */
int dump_file(const char *title, const char *path);
int dump_file(const char *title, const char *path);


/* prints the contents of the fd */
/* prints the contents of the fd
 * fd must have been opened with the flag O_NONBLOCK.
 */
int dump_file_from_fd(const char *title, const char *path, int fd);
int dump_file_from_fd(const char *title, const char *path, int fd);


/* forks a command and waits for it to finish -- terminate args with NULL */
/* forks a command and waits for it to finish -- terminate args with NULL */
+101 −36
Original line number Original line Diff line number Diff line
@@ -53,6 +53,35 @@ static const char* native_processes_to_dump[] = {
        NULL,
        NULL,
};
};


static uint64_t nanotime() {
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return (uint64_t)ts.tv_sec * NANOS_PER_SEC + ts.tv_nsec;
}

void for_each_userid(void (*func)(int), const char *header) {
    DIR *d;
    struct dirent *de;

    if (header) printf("\n------ %s ------\n", header);
    func(0);

    if (!(d = opendir("/data/system/users"))) {
        printf("Failed to open /data/system/users (%s)\n", strerror(errno));
        return;
    }

    while ((de = readdir(d))) {
        int userid;
        if (de->d_type != DT_DIR || !(userid = atoi(de->d_name))) {
            continue;
        }
        func(userid);
    }

    closedir(d);
}

static void __for_each_pid(void (*helper)(int, const char *, void *), const char *header, void *arg) {
static void __for_each_pid(void (*helper)(int, const char *, void *), const char *header, void *arg) {
    DIR *d;
    DIR *d;
    struct dirent *de;
    struct dirent *de;
@@ -75,7 +104,7 @@ static void __for_each_pid(void (*helper)(int, const char *, void *), const char


        sprintf(cmdpath,"/proc/%d/cmdline", pid);
        sprintf(cmdpath,"/proc/%d/cmdline", pid);
        memset(cmdline, 0, sizeof(cmdline));
        memset(cmdline, 0, sizeof(cmdline));
        if ((fd = open(cmdpath, O_RDONLY)) < 0) {
        if ((fd = TEMP_FAILURE_RETRY(open(cmdpath, O_RDONLY))) < 0) {
            strcpy(cmdline, "N/A");
            strcpy(cmdline, "N/A");
        } else {
        } else {
            read(fd, cmdline, sizeof(cmdline) - 1);
            read(fd, cmdline, sizeof(cmdline) - 1);
@@ -126,7 +155,7 @@ static void for_each_tid_helper(int pid, const char *cmdline, void *arg) {


        sprintf(commpath,"/proc/%d/comm", tid);
        sprintf(commpath,"/proc/%d/comm", tid);
        memset(comm, 0, sizeof(comm));
        memset(comm, 0, sizeof(comm));
        if ((fd = open(commpath, O_RDONLY)) < 0) {
        if ((fd = TEMP_FAILURE_RETRY(open(commpath, O_RDONLY))) < 0) {
            strcpy(comm, "N/A");
            strcpy(comm, "N/A");
        } else {
        } else {
            char *c;
            char *c;
@@ -157,7 +186,7 @@ void show_wchan(int pid, int tid, const char *name) {
    memset(buffer, 0, sizeof(buffer));
    memset(buffer, 0, sizeof(buffer));


    sprintf(path, "/proc/%d/wchan", tid);
    sprintf(path, "/proc/%d/wchan", tid);
    if ((fd = open(path, O_RDONLY)) < 0) {
    if ((fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY))) < 0) {
        printf("Failed to open '%s' (%s)\n", path, strerror(errno));
        printf("Failed to open '%s' (%s)\n", path, strerror(errno));
        return;
        return;
    }
    }
@@ -211,22 +240,7 @@ void do_showmap(int pid, const char *name) {
    run_command(title, 10, SU_PATH, "root", "showmap", arg, NULL);
    run_command(title, 10, SU_PATH, "root", "showmap", arg, NULL);
}
}


/* prints the contents of a file */
static int _dump_file_from_fd(const char *title, const char *path, int fd) {
int dump_file(const char *title, const char *path) {
    int fd = open(path, O_RDONLY);
    if (fd < 0) {
        int err = errno;
        if (title) printf("------ %s (%s) ------\n", title, path);
        printf("*** %s: %s\n", path, strerror(err));
        if (title) printf("\n");
        return -1;
    }
    return dump_file_from_fd(title, path, fd);
}

int dump_file_from_fd(const char *title, const char *path, int fd) {
    char buffer[32768];

    if (title) printf("------ %s (%s", title, path);
    if (title) printf("------ %s (%s", title, path);


    if (title) {
    if (title) {
@@ -240,26 +254,76 @@ int dump_file_from_fd(const char *title, const char *path, int fd) {
        printf(") ------\n");
        printf(") ------\n");
    }
    }


    int newline = 0;
    bool newline = false;
    for (;;) {
    fd_set read_set;
        int ret = read(fd, buffer, sizeof(buffer));
    struct timeval tm;
        if (ret > 0) {
    while (1) {
            newline = (buffer[ret - 1] == '\n');
        FD_ZERO(&read_set);
            ret = fwrite(buffer, ret, 1, stdout);
        FD_SET(fd, &read_set);
        /* Timeout if no data is read for 30 seconds. */
        tm.tv_sec = 30;
        tm.tv_usec = 0;
        uint64_t elapsed = nanotime();
        int ret = TEMP_FAILURE_RETRY(select(fd + 1, &read_set, NULL, NULL, &tm));
        if (ret == -1) {
            printf("*** %s: select failed: %s\n", path, strerror(errno));
            newline = true;
            break;
        } else if (ret == 0) {
            elapsed = nanotime() - elapsed;
            printf("*** %s: Timed out after %.3fs\n", path,
                   (float) elapsed / NANOS_PER_SEC);
            newline = true;
            break;
        } else {
            char buffer[65536];
            ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, sizeof(buffer)));
            if (bytes_read > 0) {
                fwrite(buffer, bytes_read, 1, stdout);
                newline = (buffer[bytes_read-1] == '\n');
            } else {
                if (bytes_read == -1) {
                    printf("*** %s: Failed to read from fd: %s", path, strerror(errno));
                    newline = true;
                }
                }
        if (ret <= 0) break;
                break;
            }
            }
    close(fd);
        }
    }
    TEMP_FAILURE_RETRY(close(fd));


    if (!newline) printf("\n");
    if (!newline) printf("\n");
    if (title) printf("\n");
    if (title) printf("\n");
    return 0;
    return 0;
}
}


static int64_t nanotime() {
/* prints the contents of a file */
    struct timespec ts;
int dump_file(const char *title, const char *path) {
    clock_gettime(CLOCK_MONOTONIC, &ts);
    int fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC));
    return (int64_t)ts.tv_sec * NANOS_PER_SEC + ts.tv_nsec;
    if (fd < 0) {
        int err = errno;
        if (title) printf("------ %s (%s) ------\n", title, path);
        printf("*** %s: %s\n", path, strerror(err));
        if (title) printf("\n");
        return -1;
    }
    return _dump_file_from_fd(title, path, fd);
}

/* fd must have been opened with the flag O_NONBLOCK. With this flag set,
 * it's possible to avoid issues where opening the file itself can get
 * stuck.
 */
int dump_file_from_fd(const char *title, const char *path, int fd) {
    int flags = fcntl(fd, F_GETFL);
    if (flags == -1) {
        printf("*** %s: failed to get flags on fd %d: %s\n", path, fd, strerror(errno));
        return -1;
    } else if (!(flags & O_NONBLOCK)) {
        printf("*** %s: fd must have O_NONBLOCK set.\n", path);
        return -1;
    }
    return _dump_file_from_fd(title, path, fd);
}
}


bool waitpid_with_timeout(pid_t pid, int timeout_seconds, int* status) {
bool waitpid_with_timeout(pid_t pid, int timeout_seconds, int* status) {
@@ -309,7 +373,7 @@ bool waitpid_with_timeout(pid_t pid, int timeout_seconds, int* status) {
/* forks a command and waits for it to finish */
/* forks a command and waits for it to finish */
int run_command(const char *title, int timeout_seconds, const char *command, ...) {
int run_command(const char *title, int timeout_seconds, const char *command, ...) {
    fflush(stdout);
    fflush(stdout);
    int64_t start = nanotime();
    uint64_t start = nanotime();
    pid_t pid = fork();
    pid_t pid = fork();


    /* handle error case */
    /* handle error case */
@@ -511,7 +575,8 @@ const char *dump_traces() {
    }
    }


    /* create a new, empty traces.txt file to receive stack dumps */
    /* create a new, empty traces.txt file to receive stack dumps */
    int fd = open(traces_path, O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW, 0666);  /* -rw-rw-rw- */
    int fd = TEMP_FAILURE_RETRY(open(traces_path, O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW,
                                     0666));  /* -rw-rw-rw- */
    if (fd < 0) {
    if (fd < 0) {
        fprintf(stderr, "%s: %s\n", traces_path, strerror(errno));
        fprintf(stderr, "%s: %s\n", traces_path, strerror(errno));
        return NULL;
        return NULL;
@@ -561,7 +626,7 @@ const char *dump_traces() {
        if (!strncmp(data, "/system/bin/app_process", strlen("/system/bin/app_process"))) {
        if (!strncmp(data, "/system/bin/app_process", strlen("/system/bin/app_process"))) {
            /* skip zygote -- it won't dump its stack anyway */
            /* skip zygote -- it won't dump its stack anyway */
            snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
            snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
            int cfd = open(path, O_RDONLY);
            int cfd = TEMP_FAILURE_RETRY(open(path, O_RDONLY));
            len = read(cfd, data, sizeof(data) - 1);
            len = read(cfd, data, sizeof(data) - 1);
            close(cfd);
            close(cfd);
            if (len <= 0) {
            if (len <= 0) {
@@ -573,7 +638,7 @@ const char *dump_traces() {
            }
            }


            ++dalvik_found;
            ++dalvik_found;
            int64_t start = nanotime();
            uint64_t start = nanotime();
            if (kill(pid, SIGQUIT)) {
            if (kill(pid, SIGQUIT)) {
                fprintf(stderr, "kill(%d, SIGQUIT): %s\n", pid, strerror(errno));
                fprintf(stderr, "kill(%d, SIGQUIT): %s\n", pid, strerror(errno));
                continue;
                continue;
@@ -603,7 +668,7 @@ const char *dump_traces() {
                fprintf(stderr, "lseek: %s\n", strerror(errno));
                fprintf(stderr, "lseek: %s\n", strerror(errno));
            } else {
            } else {
                static uint16_t timeout_failures = 0;
                static uint16_t timeout_failures = 0;
                int64_t start = nanotime();
                uint64_t start = nanotime();


                /* If 3 backtrace dumps fail in a row, consider debuggerd dead. */
                /* If 3 backtrace dumps fail in a row, consider debuggerd dead. */
                if (timeout_failures == 3) {
                if (timeout_failures == 3) {