Reduce effort and memory of log monitor
This commit is contained in:
parent
5fc2058336
commit
b0567eadfd
@ -13,9 +13,36 @@
|
|||||||
#include "magisk.h"
|
#include "magisk.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
int logcat_events[] = { -1, -1, -1 };
|
|
||||||
extern int is_daemon_init;
|
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
|
#ifdef MAGISK_DEBUG
|
||||||
static int debug_log_pid, debug_log_fd;
|
static int debug_log_pid, debug_log_fd;
|
||||||
#endif
|
#endif
|
||||||
@ -30,10 +57,10 @@ static void *logger_thread(void *args) {
|
|||||||
// Start logcat
|
// Start logcat
|
||||||
log_pid = exec_command(0, &log_fd, NULL, "logcat", "-b", "all" , "-v", "threadtime", "-s", "am_proc_start", "Magisk", NULL);
|
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)) {
|
while (fdgets(line, sizeof(line), log_fd)) {
|
||||||
for (int i = 0; i < (sizeof(logcat_events) / sizeof(int)); ++i) {
|
for (int i = 0; i < (sizeof(log_events) / sizeof(struct log_listener)); ++i) {
|
||||||
if (logcat_events[i] > 0) {
|
if (log_events[i].fd > 0 && log_events[i].filter(line)) {
|
||||||
char *s = strdup(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))
|
if (kill(log_pid, 0))
|
||||||
@ -66,32 +93,29 @@ static void *magisk_log_thread(void *args) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Register our listener
|
// Register our listener
|
||||||
logcat_events[LOG_EVENT] = pipefd[1];
|
log_events[LOG_EVENT].fd = pipefd[1];
|
||||||
|
|
||||||
LOGD("log_monitor: magisk log dumper start");
|
LOGD("log_monitor: magisk log dumper start");
|
||||||
|
|
||||||
FILE *log;
|
FILE *log;
|
||||||
char *ss;
|
|
||||||
for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line)) {
|
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) {
|
if ((have_data = check_data())) {
|
||||||
if ((have_data = check_data())) {
|
// Dump buffered logs to file
|
||||||
// Dump buffered logs to file
|
log = xfopen(LOGFILE, "w");
|
||||||
log = xfopen(LOGFILE, "w");
|
setbuf(log, NULL);
|
||||||
setbuf(log, NULL);
|
char *tmp;
|
||||||
char *tmp;
|
vec_for_each(&logs, tmp) {
|
||||||
vec_for_each(&logs, tmp) {
|
fprintf(log, "%s", tmp);
|
||||||
fprintf(log, "%s", tmp);
|
free(tmp);
|
||||||
free(tmp);
|
|
||||||
}
|
|
||||||
vec_destroy(&logs);
|
|
||||||
} else {
|
|
||||||
vec_push_back(&logs, strdup(line));
|
|
||||||
}
|
}
|
||||||
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -106,13 +130,11 @@ static void *debug_magisk_log_thread(void *args) {
|
|||||||
LOGD("log_monitor: debug log dumper start");
|
LOGD("log_monitor: debug log dumper start");
|
||||||
|
|
||||||
// Register our listener
|
// 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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,13 @@ enum {
|
|||||||
LOG_EVENT,
|
LOG_EVENT,
|
||||||
DEBUG_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 monitor_logs();
|
||||||
void start_debug_full_log();
|
void start_debug_full_log();
|
||||||
|
@ -28,7 +28,7 @@ static void term_thread(int sig) {
|
|||||||
destroy_list();
|
destroy_list();
|
||||||
hideEnabled = 0;
|
hideEnabled = 0;
|
||||||
// Unregister listener
|
// Unregister listener
|
||||||
logcat_events[HIDE_EVENT] = -1;
|
log_events[HIDE_EVENT].fd = -1;
|
||||||
close(pipefd[0]);
|
close(pipefd[0]);
|
||||||
close(pipefd[1]);
|
close(pipefd[1]);
|
||||||
pipefd[0] = pipefd[1] = -1;
|
pipefd[0] = pipefd[1] = -1;
|
||||||
@ -193,79 +193,75 @@ void proc_monitor() {
|
|||||||
|
|
||||||
// Register our listener to logcat monitor
|
// Register our listener to logcat monitor
|
||||||
xpipe2(pipefd, O_CLOEXEC);
|
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)) {
|
if (read(pipefd[0], &log, sizeof(log)) != sizeof(log)) {
|
||||||
/* It might be interrupted */
|
/* It might be interrupted */
|
||||||
log = NULL;
|
log = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
char *ss;
|
char *ss = strchr(log, '[');
|
||||||
if ((ss = strstr(log, "am_proc_start")) && (ss = strchr(ss, '['))) {
|
int pid, ret, comma = 0;
|
||||||
int pid, ret, comma = 0;
|
char *pos = ss, processName[256], ns[32];
|
||||||
char *pos = ss, processName[256], ns[32];
|
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
pos = strchr(pos, ',');
|
pos = strchr(pos, ',');
|
||||||
if(pos == NULL)
|
if(pos == NULL)
|
||||||
break;
|
break;
|
||||||
pos[0] = ' ';
|
pos[0] = ' ';
|
||||||
++comma;
|
++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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user