mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-27 20:15:29 +00:00
Test the log buffers before running command
This commit is contained in:
parent
c3a6179a21
commit
5d5ec08566
@ -16,6 +16,7 @@
|
||||
#include "daemon.h"
|
||||
|
||||
int loggable = 1;
|
||||
static struct vector log_cmd, clear_cmd;
|
||||
static int sockfd;
|
||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
@ -49,18 +50,6 @@ static struct log_listener events[] = {
|
||||
};
|
||||
#define EVENT_NUM (sizeof(events) / sizeof(struct log_listener))
|
||||
|
||||
static void test_logcat() {
|
||||
int log_fd = -1, log_pid;
|
||||
char buf[1];
|
||||
log_pid = exec_command(0, &log_fd, NULL, "logcat", NULL);
|
||||
if (read(log_fd, buf, sizeof(buf)) != sizeof(buf)) {
|
||||
loggable = 0;
|
||||
LOGD("magisklogd: cannot read from logcat, disable logging");
|
||||
}
|
||||
kill(log_pid, SIGTERM);
|
||||
waitpid(log_pid, NULL, 0);
|
||||
}
|
||||
|
||||
static void sigpipe_handler(int sig) {
|
||||
close(events[HIDE_EVENT].fd);
|
||||
events[HIDE_EVENT].fd = -1;
|
||||
@ -93,12 +82,12 @@ static void *monitor_thread(void *args) {
|
||||
// Give the main daemon some time before we monitor it
|
||||
sleep(5);
|
||||
int fd;
|
||||
char b[1];
|
||||
char b;
|
||||
do {
|
||||
fd = connect_daemon();
|
||||
write_int(fd, MONITOR);
|
||||
// This should hold unless the daemon is killed
|
||||
read(fd, b, sizeof(b));
|
||||
read(fd, &b, sizeof(b));
|
||||
// The main daemon crashed, spawn a new one
|
||||
close(fd);
|
||||
} while (1);
|
||||
@ -131,17 +120,27 @@ void log_daemon() {
|
||||
rename(LOGFILE, LOGFILE ".bak");
|
||||
events[LOG_EVENT].fd = xopen(LOGFILE, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC | O_APPEND, 0644);
|
||||
|
||||
// Construct cmdline
|
||||
vec_init(&log_cmd);
|
||||
vec_push_back(&log_cmd, "/system/bin/logcat");
|
||||
// Test whether these buffers actually works
|
||||
const char* b[] = { "main", "events", "crash" };
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (exec_command_sync("/system/bin/logcat", "-b", b[i], "-d", "-f", "/dev/null", NULL) == 0)
|
||||
vec_push_back_all(&log_cmd, "-b", b[i], NULL);
|
||||
}
|
||||
vec_dup(&log_cmd, &clear_cmd);
|
||||
vec_push_back_all(&log_cmd, "-v", "threadtime", "-s", "am_proc_start", "Magisk", "*:F", NULL);
|
||||
vec_push_back(&log_cmd, NULL);
|
||||
vec_push_back(&clear_cmd, "-c");
|
||||
vec_push_back(&clear_cmd, NULL);
|
||||
|
||||
int log_fd = -1, log_pid;
|
||||
char line[PIPE_BUF];
|
||||
|
||||
while (1) {
|
||||
// Start logcat
|
||||
log_pid = exec_command(0, &log_fd, NULL,
|
||||
"/system/bin/logcat",
|
||||
"-b", "events", "-b", "main", "-b", "crash",
|
||||
"-v", "threadtime",
|
||||
"-s", "am_proc_start", "Magisk", "*:F",
|
||||
NULL);
|
||||
log_pid = exec_array(0, &log_fd, NULL, (char **) vec_entry(&log_cmd));
|
||||
FILE *logs = fdopen(log_fd, "r");
|
||||
while (fgets(line, sizeof(line), logs)) {
|
||||
if (line[0] == '-')
|
||||
@ -162,13 +161,14 @@ void log_daemon() {
|
||||
|
||||
LOGI("magisklogd: logcat output EOF");
|
||||
// Clear buffer
|
||||
exec_command_sync("logcat", "-b", "events", "-b", "main", "-b", "crash", "-c", NULL);
|
||||
log_pid = exec_array(0, NULL, NULL, (char **) vec_entry(&clear_cmd));
|
||||
waitpid(log_pid, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Start new threads to monitor logcat and dump to logfile */
|
||||
void monitor_logs() {
|
||||
test_logcat();
|
||||
loggable = exec_command_sync("/system/bin/logcat", "-d", "-f", "/dev/null", NULL) == 0;
|
||||
if (loggable) {
|
||||
int fd;
|
||||
connect_daemon2(LOG_DAEMON, &fd);
|
||||
|
@ -83,7 +83,8 @@ void ps(void (*func)(int));
|
||||
void ps_filter_proc_name(const char *filter, void (*func)(int));
|
||||
void unlock_blocks();
|
||||
void setup_sighandlers(void (*handler)(int));
|
||||
int exec_command(int err, int *fd, void (*setupenv)(struct vector*), const char *argv0, ...);
|
||||
int exec_array(int err, int *fd, void (*setenv)(struct vector *), char *const *argv);
|
||||
int exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *argv0, ...);
|
||||
int exec_command_sync(char *const argv0, ...);
|
||||
int bind_mount(const char *from, const char *to);
|
||||
void get_client_cred(int fd, struct ucred *cred);
|
||||
|
@ -14,11 +14,12 @@ struct vector {
|
||||
|
||||
void vec_init(struct vector *v);
|
||||
void vec_push_back(struct vector *v, void *p);
|
||||
void vec_push_back_all(struct vector *v, void *p, ...);
|
||||
void *vec_pop_back(struct vector *v);
|
||||
void vec_sort(struct vector *v, int (*compar)(const void *, const void *));
|
||||
void vec_destroy(struct vector *v);
|
||||
void vec_deep_destroy(struct vector *v);
|
||||
struct vector *vec_dup(struct vector *v);
|
||||
void vec_dup(struct vector *v, struct vector *vv);
|
||||
|
||||
#define vec_size(v) (v)->size
|
||||
#define vec_cap(v) (v)->cap
|
||||
|
@ -245,9 +245,9 @@ void setup_sighandlers(void (*handler)(int)) {
|
||||
fd == NULL -> Ignore output
|
||||
*fd < 0 -> Open pipe and set *fd to the read end
|
||||
*fd >= 0 -> STDOUT (or STDERR) will be redirected to *fd
|
||||
*cb -> A callback function which runs after fork
|
||||
*setenv -> A callback function which sets up a vector of environment variables
|
||||
*/
|
||||
static int v_exec_command(int err, int *fd, void (*setupenv)(struct vector*), const char *argv0, va_list argv) {
|
||||
int exec_array(int err, int *fd, void (*setenv)(struct vector *), char *const *argv) {
|
||||
int pipefd[2], writeEnd = -1;
|
||||
|
||||
if (fd) {
|
||||
@ -260,20 +260,12 @@ static int v_exec_command(int err, int *fd, void (*setupenv)(struct vector*), co
|
||||
}
|
||||
}
|
||||
|
||||
// Collect va_list into vector
|
||||
struct vector args;
|
||||
vec_init(&args);
|
||||
vec_push_back(&args, strdup(argv0));
|
||||
for (void *arg = va_arg(argv, void*); arg; arg = va_arg(argv, void*))
|
||||
vec_push_back(&args, strdup(arg));
|
||||
vec_push_back(&args, NULL);
|
||||
|
||||
// Setup environment
|
||||
char *const *envp;
|
||||
struct vector env;
|
||||
vec_init(&env);
|
||||
if (setupenv) {
|
||||
setupenv(&env);
|
||||
if (setenv) {
|
||||
setenv(&env);
|
||||
envp = (char **) vec_entry(&env);
|
||||
} else {
|
||||
extern char **environ;
|
||||
@ -287,21 +279,34 @@ static int v_exec_command(int err, int *fd, void (*setupenv)(struct vector*), co
|
||||
*fd = pipefd[0];
|
||||
close(pipefd[1]);
|
||||
}
|
||||
vec_deep_destroy(&args);
|
||||
vec_deep_destroy(&env);
|
||||
return pid;
|
||||
}
|
||||
|
||||
if (fd) {
|
||||
xdup2(writeEnd, STDOUT_FILENO);
|
||||
if (err) xdup2(writeEnd, STDERR_FILENO);
|
||||
if (err)
|
||||
xdup2(writeEnd, STDERR_FILENO);
|
||||
}
|
||||
|
||||
execvpe(argv0, (char **) vec_entry(&args), envp);
|
||||
PLOGE("execvpe %s", argv0);
|
||||
execvpe(argv[0], argv, envp);
|
||||
PLOGE("execvpe %s", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int v_exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *argv0, va_list argv) {
|
||||
// Collect va_list into vector
|
||||
struct vector args;
|
||||
vec_init(&args);
|
||||
vec_push_back(&args, strdup(argv0));
|
||||
for (void *arg = va_arg(argv, void*); arg; arg = va_arg(argv, void*))
|
||||
vec_push_back(&args, strdup(arg));
|
||||
vec_push_back(&args, NULL);
|
||||
int pid = exec_array(err, fd, setenv, (char **) vec_entry(&args));
|
||||
vec_deep_destroy(&args);
|
||||
return pid;
|
||||
}
|
||||
|
||||
int exec_command_sync(char *const argv0, ...) {
|
||||
va_list argv;
|
||||
va_start(argv, argv0);
|
||||
@ -314,10 +319,10 @@ int exec_command_sync(char *const argv0, ...) {
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
int exec_command(int err, int *fd, void (*setupenv)(struct vector*), const char *argv0, ...) {
|
||||
int exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *argv0, ...) {
|
||||
va_list argv;
|
||||
va_start(argv, argv0);
|
||||
int pid = v_exec_command(err, fd, setupenv, argv0, argv);
|
||||
int pid = v_exec_command(err, fd, setenv, argv0, argv);
|
||||
va_end(argv);
|
||||
return pid;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "vector.h"
|
||||
|
||||
@ -23,6 +24,15 @@ void vec_push_back(struct vector *v, void *p) {
|
||||
++vec_size(v);
|
||||
}
|
||||
|
||||
void vec_push_back_all(struct vector *v, void *p, ...) {
|
||||
va_list argv;
|
||||
va_start(argv, p);
|
||||
vec_push_back(v, p);
|
||||
for (void *arg = va_arg(argv, char*); arg; arg = va_arg(argv, char*))
|
||||
vec_push_back(v, arg);
|
||||
va_end(argv);
|
||||
}
|
||||
|
||||
void *vec_pop_back(struct vector *v) {
|
||||
void *ret = vec_entry(v)[vec_size(v) - 1];
|
||||
--vec_size(v);
|
||||
@ -73,11 +83,9 @@ void vec_deep_destroy(struct vector *v) {
|
||||
vec_destroy(v);
|
||||
}
|
||||
|
||||
struct vector *vec_dup(struct vector *v) {
|
||||
struct vector *ret = malloc(sizeof(*ret));
|
||||
vec_size(ret) = vec_size(v);
|
||||
vec_cap(ret) = vec_cap(v);
|
||||
vec_entry(v) = malloc(sizeof(void*) * vec_cap(ret));
|
||||
memcpy(vec_entry(ret), vec_entry(v), sizeof(void*) * vec_cap(ret));
|
||||
return ret;
|
||||
void vec_dup(struct vector *v, struct vector *vv) {
|
||||
vec_size(vv) = vec_size(v);
|
||||
vec_cap(vv) = vec_cap(v);
|
||||
vec_entry(vv) = malloc(sizeof(void*) * vec_cap(v));
|
||||
memcpy(vec_entry(vv), vec_entry(v), sizeof(void*) * vec_cap(v));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user