From b0567eadfd9a0fc75db7e232a2e60a7afd91bb02 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Mon, 18 Dec 2017 18:17:37 +0800 Subject: [PATCH] Reduce effort and memory of log monitor --- core/jni/core/log_monitor.c | 78 ++++++++++------- core/jni/include/logging.h | 8 +- core/jni/magiskhide/proc_monitor.c | 130 ++++++++++++++--------------- 3 files changed, 120 insertions(+), 96 deletions(-) diff --git a/core/jni/core/log_monitor.c b/core/jni/core/log_monitor.c index 6ac5a1077..6808fcffc 100644 --- a/core/jni/core/log_monitor.c +++ b/core/jni/core/log_monitor.c @@ -13,9 +13,36 @@ #include "magisk.h" #include "utils.h" -int logcat_events[] = { -1, -1, -1 }; extern int is_daemon_init; +static int am_proc_start_filter(const char *log) { + return strstr(log, "am_proc_start") != NULL; +} + +static int magisk_log_filter(const char *log) { + char *ss; + return (ss = strstr(log, " Magisk")) && (ss[-1] != 'D') && (ss[-1] != 'V'); +} + +static int magisk_debug_log_filter(const char *log) { + return strstr(log, "Magisk") != NULL; +} + +struct log_listener log_events[] = { + { /* HIDE_EVENT */ + .fd = -1, + .filter = am_proc_start_filter + }, + { /* LOG_EVENT */ + .fd = -1, + .filter = magisk_log_filter + }, + { /* DEBUG_EVENT */ + .fd = -1, + .filter = magisk_debug_log_filter + } +}; + #ifdef MAGISK_DEBUG static int debug_log_pid, debug_log_fd; #endif @@ -30,10 +57,10 @@ static void *logger_thread(void *args) { // Start logcat log_pid = exec_command(0, &log_fd, NULL, "logcat", "-b", "all" , "-v", "threadtime", "-s", "am_proc_start", "Magisk", NULL); while (fdgets(line, sizeof(line), log_fd)) { - for (int i = 0; i < (sizeof(logcat_events) / sizeof(int)); ++i) { - if (logcat_events[i] > 0) { + for (int i = 0; i < (sizeof(log_events) / sizeof(struct log_listener)); ++i) { + if (log_events[i].fd > 0 && log_events[i].filter(line)) { char *s = strdup(line); - xwrite(logcat_events[i], &s, sizeof(s)); + xwrite(log_events[i].fd, &s, sizeof(s)); } } if (kill(log_pid, 0)) @@ -66,32 +93,29 @@ static void *magisk_log_thread(void *args) { return NULL; // Register our listener - logcat_events[LOG_EVENT] = pipefd[1]; + log_events[LOG_EVENT].fd = pipefd[1]; LOGD("log_monitor: magisk log dumper start"); FILE *log; - char *ss; for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line)) { - if ((ss = strstr(line, " Magisk")) && (ss[-1] != 'D') && (ss[-1] != 'V')) { - if (!have_data) { - if ((have_data = check_data())) { - // Dump buffered logs to file - log = xfopen(LOGFILE, "w"); - setbuf(log, NULL); - char *tmp; - vec_for_each(&logs, tmp) { - fprintf(log, "%s", tmp); - free(tmp); - } - vec_destroy(&logs); - } else { - vec_push_back(&logs, strdup(line)); + if (!have_data) { + if ((have_data = check_data())) { + // Dump buffered logs to file + log = xfopen(LOGFILE, "w"); + setbuf(log, NULL); + char *tmp; + vec_for_each(&logs, tmp) { + fprintf(log, "%s", tmp); + free(tmp); } + vec_destroy(&logs); + } else { + vec_push_back(&logs, strdup(line)); } - if (have_data) - fprintf(log, "%s", line); } + if (have_data) + fprintf(log, "%s", line); } return NULL; } @@ -106,13 +130,11 @@ static void *debug_magisk_log_thread(void *args) { LOGD("log_monitor: debug log dumper start"); // Register our listener - logcat_events[DEBUG_EVENT] = pipefd[1]; + log_events[DEBUG_EVENT].fd = pipefd[1]; + + for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line)) + fprintf(log, "%s", line); - for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line)) { - char *ss; - if ((ss = strstr(line, "Magisk"))) - fprintf(log, "%s", line); - } return NULL; } diff --git a/core/jni/include/logging.h b/core/jni/include/logging.h index e9434a704..21908a785 100644 --- a/core/jni/include/logging.h +++ b/core/jni/include/logging.h @@ -51,7 +51,13 @@ enum { LOG_EVENT, DEBUG_EVENT }; -extern int logcat_events[]; + +struct log_listener { + int fd; + int (*filter) (const char*); +}; + +extern struct log_listener log_events[]; void monitor_logs(); void start_debug_full_log(); diff --git a/core/jni/magiskhide/proc_monitor.c b/core/jni/magiskhide/proc_monitor.c index d421ef9e5..92f72f9fc 100644 --- a/core/jni/magiskhide/proc_monitor.c +++ b/core/jni/magiskhide/proc_monitor.c @@ -28,7 +28,7 @@ static void term_thread(int sig) { destroy_list(); hideEnabled = 0; // Unregister listener - logcat_events[HIDE_EVENT] = -1; + log_events[HIDE_EVENT].fd = -1; close(pipefd[0]); close(pipefd[1]); pipefd[0] = pipefd[1] = -1; @@ -193,79 +193,75 @@ void proc_monitor() { // Register our listener to logcat monitor xpipe2(pipefd, O_CLOEXEC); - logcat_events[HIDE_EVENT] = pipefd[1]; + log_events[HIDE_EVENT].fd = pipefd[1]; - for (char *log, *line; 1; free(log)) { + for (char *log, *line;; free(log)) { if (read(pipefd[0], &log, sizeof(log)) != sizeof(log)) { /* It might be interrupted */ log = NULL; continue; } - char *ss; - if ((ss = strstr(log, "am_proc_start")) && (ss = strchr(ss, '['))) { - int pid, ret, comma = 0; - char *pos = ss, processName[256], ns[32]; + char *ss = strchr(log, '['); + int pid, ret, comma = 0; + char *pos = ss, processName[256], ns[32]; - while(1) { - pos = strchr(pos, ','); - if(pos == NULL) - break; - pos[0] = ' '; - ++comma; - } - - if (comma == 6) - ret = sscanf(ss, "[%*d %d %*d %*d %256s", &pid, processName); - else - ret = sscanf(ss, "[%*d %d %*d %256s", &pid, processName); - - if(ret != 2) - continue; - - ret = 0; - - // Critical region - pthread_mutex_lock(&hide_lock); - vec_for_each(hide_list, line) { - if (strcmp(processName, line) == 0) { - while(1) { - ret = 1; - for (int i = 0; i < zygote_num; ++i) { - read_namespace(pid, ns, sizeof(ns)); - if (strcmp(ns, zygote_ns[i]) == 0) { - usleep(50); - ret = 0; - break; - } - } - if (ret) break; - } - - // Send pause signal ASAP - if (kill(pid, SIGSTOP) == -1) continue; - - LOGI("proc_monitor: %s (PID=%d ns=%s)\n", processName, pid, ns); - - xmount(NULL, "/", NULL, MS_REMOUNT, NULL); - unlink("/magisk"); - unlink("/data/magisk"); - unlink("/data/magisk.img"); - unlink(MAGISKRC); - xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL); - ++hide_queue; - - /* - * The setns system call do not support multithread processes - * We have to fork a new process, setns, then do the unmounts - */ - int selfpid = getpid(); - if (fork_dont_care() == 0) - hide_daemon(pid, selfpid); - - break; - } - } - pthread_mutex_unlock(&hide_lock); + while(1) { + pos = strchr(pos, ','); + if(pos == NULL) + break; + pos[0] = ' '; + ++comma; } + + if (comma == 6) + ret = sscanf(ss, "[%*d %d %*d %*d %256s", &pid, processName); + else + ret = sscanf(ss, "[%*d %d %*d %256s", &pid, processName); + + if(ret != 2) + continue; + + // Critical region + pthread_mutex_lock(&hide_lock); + vec_for_each(hide_list, line) { + if (strcmp(processName, line) == 0) { + while(1) { + ret = 1; + for (int i = 0; i < zygote_num; ++i) { + read_namespace(pid, ns, sizeof(ns)); + if (strcmp(ns, zygote_ns[i]) == 0) { + usleep(50); + ret = 0; + break; + } + } + if (ret) break; + } + + // Send pause signal ASAP + if (kill(pid, SIGSTOP) == -1) continue; + + LOGI("proc_monitor: %s (PID=%d ns=%s)\n", processName, pid, ns); + + xmount(NULL, "/", NULL, MS_REMOUNT, NULL); + unlink("/magisk"); + unlink("/data/magisk"); + unlink("/data/magisk.img"); + unlink(MAGISKRC); + xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL); + ++hide_queue; + + /* + * The setns system call do not support multithread processes + * We have to fork a new process, setns, then do the unmounts + */ + int selfpid = getpid(); + if (fork_dont_care() == 0) + hide_daemon(pid, selfpid); + + break; + } + } + pthread_mutex_unlock(&hide_lock); } }