Merge "dumpstate: dump all threads in show_wchan"
This commit is contained in:
commit
5f7e348746
@ -102,7 +102,7 @@ static void dumpstate() {
|
|||||||
run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL);
|
run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL);
|
||||||
|
|
||||||
for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
|
for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
|
||||||
for_each_pid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
|
for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
|
||||||
|
|
||||||
// dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
|
// dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
|
||||||
run_command("SYSTEM LOG", 20, "logcat", "-v", "threadtime", "-d", "*:v", NULL);
|
run_command("SYSTEM LOG", 20, "logcat", "-v", "threadtime", "-d", "*:v", NULL);
|
||||||
|
@ -19,10 +19,14 @@
|
|||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define SU_PATH "/system/xbin/su"
|
#define SU_PATH "/system/xbin/su"
|
||||||
|
|
||||||
|
typedef void (for_each_pid_func)(int, const char *);
|
||||||
|
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);
|
||||||
|
|
||||||
@ -42,10 +46,13 @@ pid_t redirect_to_file(FILE *redirect, char *path, int gzip_level);
|
|||||||
const char *dump_traces();
|
const char *dump_traces();
|
||||||
|
|
||||||
/* for each process in the system, run the specified function */
|
/* for each process in the system, run the specified function */
|
||||||
void for_each_pid(void (*func)(int, const char *), const char *header);
|
void for_each_pid(for_each_pid_func func, const char *header);
|
||||||
|
|
||||||
|
/* for each thread in the system, run the specified function */
|
||||||
|
void for_each_tid(for_each_tid_func func, const char *header);
|
||||||
|
|
||||||
/* Displays a blocked processes in-kernel wait channel */
|
/* Displays a blocked processes in-kernel wait channel */
|
||||||
void show_wchan(int pid, const char *name);
|
void show_wchan(int pid, int tid, const char *name);
|
||||||
|
|
||||||
/* Runs "showmap" for a process */
|
/* Runs "showmap" for a process */
|
||||||
void do_showmap(int pid, const char *name);
|
void do_showmap(int pid, const char *name);
|
||||||
|
@ -48,7 +48,7 @@ static const char* native_processes_to_dump[] = {
|
|||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
void for_each_pid(void (*func)(int, const char *), const char *header) {
|
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;
|
||||||
|
|
||||||
@ -73,23 +73,85 @@ void for_each_pid(void (*func)(int, const char *), const char *header) {
|
|||||||
if ((fd = open(cmdpath, O_RDONLY)) < 0) {
|
if ((fd = open(cmdpath, O_RDONLY)) < 0) {
|
||||||
strcpy(cmdline, "N/A");
|
strcpy(cmdline, "N/A");
|
||||||
} else {
|
} else {
|
||||||
read(fd, cmdline, sizeof(cmdline));
|
read(fd, cmdline, sizeof(cmdline) - 1);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
func(pid, cmdline);
|
helper(pid, cmdline, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(d);
|
closedir(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
void show_wchan(int pid, const char *name) {
|
static void for_each_pid_helper(int pid, const char *cmdline, void *arg) {
|
||||||
|
for_each_pid_func *func = arg;
|
||||||
|
func(pid, cmdline);
|
||||||
|
}
|
||||||
|
|
||||||
|
void for_each_pid(for_each_pid_func func, const char *header) {
|
||||||
|
__for_each_pid(for_each_pid_helper, header, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void for_each_tid_helper(int pid, const char *cmdline, void *arg) {
|
||||||
|
DIR *d;
|
||||||
|
struct dirent *de;
|
||||||
|
char taskpath[255];
|
||||||
|
for_each_tid_func *func = arg;
|
||||||
|
|
||||||
|
sprintf(taskpath, "/proc/%d/task", pid);
|
||||||
|
|
||||||
|
if (!(d = opendir(taskpath))) {
|
||||||
|
printf("Failed to open %s (%s)\n", taskpath, strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
func(pid, pid, cmdline);
|
||||||
|
|
||||||
|
while ((de = readdir(d))) {
|
||||||
|
int tid;
|
||||||
|
int fd;
|
||||||
|
char commpath[255];
|
||||||
|
char comm[255];
|
||||||
|
|
||||||
|
if (!(tid = atoi(de->d_name))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tid == pid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sprintf(commpath,"/proc/%d/comm", tid);
|
||||||
|
memset(comm, 0, sizeof(cmdline));
|
||||||
|
if ((fd = open(commpath, O_RDONLY)) < 0) {
|
||||||
|
strcpy(comm, "N/A");
|
||||||
|
} else {
|
||||||
|
char *c;
|
||||||
|
read(fd, comm, sizeof(comm) - 1);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
c = strrchr(comm, '\n');
|
||||||
|
if (c) {
|
||||||
|
*c = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func(pid, tid, comm);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void for_each_tid(for_each_tid_func func, const char *header) {
|
||||||
|
__for_each_pid(for_each_tid_helper, header, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
void show_wchan(int pid, int tid, const char *name) {
|
||||||
char path[255];
|
char path[255];
|
||||||
char buffer[255];
|
char buffer[255];
|
||||||
int fd;
|
int fd;
|
||||||
|
char name_buffer[255];
|
||||||
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
|
||||||
sprintf(path, "/proc/%d/wchan", pid);
|
sprintf(path, "/proc/%d/wchan", tid);
|
||||||
if ((fd = open(path, O_RDONLY)) < 0) {
|
if ((fd = 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;
|
||||||
@ -100,7 +162,10 @@ void show_wchan(int pid, const char *name) {
|
|||||||
goto out_close;
|
goto out_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%-7d %-32s %s\n", pid, name, buffer);
|
snprintf(name_buffer, sizeof(name_buffer), "%*s%s",
|
||||||
|
pid == tid ? 0 : 3, "", name);
|
||||||
|
|
||||||
|
printf("%-7d %-32s %s\n", tid, name_buffer, buffer);
|
||||||
|
|
||||||
out_close:
|
out_close:
|
||||||
close(fd);
|
close(fd);
|
||||||
|
Loading…
Reference in New Issue
Block a user