mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-26 18:47:39 +00:00
162 lines
3.8 KiB
C
162 lines
3.8 KiB
C
/* log_monitor.c - New thread to monitor logcat
|
|
*
|
|
* A universal logcat monitor for many usages. Add listeners to the list,
|
|
* and the pointer of the new log line will be sent through pipes to trigger
|
|
* asynchronous events without polling
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <limits.h>
|
|
#include <pthread.h>
|
|
#include <unistd.h>
|
|
#include <sys/wait.h>
|
|
|
|
#include "magisk.h"
|
|
#include "utils.h"
|
|
|
|
int logcat_events[] = { -1, -1, -1 };
|
|
extern int is_restart;
|
|
|
|
#ifdef MAGISK_DEBUG
|
|
static int debug_log_pid, debug_log_fd;
|
|
#endif
|
|
|
|
static void *logger_thread(void *args) {
|
|
// Setup error handler
|
|
err_handler = exit_thread;
|
|
|
|
int log_fd = -1, log_pid;
|
|
char line[4096];
|
|
|
|
while (1) {
|
|
// 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) {
|
|
char *s = strdup(line);
|
|
xwrite(logcat_events[i], &s, sizeof(s));
|
|
}
|
|
}
|
|
if (kill(log_pid, 0))
|
|
break;
|
|
}
|
|
// Clear buffer if restart required
|
|
exec_command_sync("logcat", "-b", "all", "-c", NULL);
|
|
}
|
|
|
|
// Should never be here, but well...
|
|
return NULL;
|
|
}
|
|
|
|
static void *magisk_log_thread(void *args) {
|
|
// Setup error handler
|
|
err_handler = exit_thread;
|
|
|
|
int have_data = 0;
|
|
|
|
// Temp buffer for logs before we have data access
|
|
struct vector logs;
|
|
vec_init(&logs);
|
|
|
|
FILE *log;
|
|
int pipefd[2];
|
|
if (xpipe2(pipefd, O_CLOEXEC) == -1)
|
|
return NULL;
|
|
|
|
// Register our listener
|
|
logcat_events[LOG_EVENT] = pipefd[1];
|
|
|
|
for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line)) {
|
|
char *ss;
|
|
if ((ss = strstr(line, " Magisk")) && (ss[-1] != 'D') && (ss[-1] != 'V')) {
|
|
if (!have_data) {
|
|
if ((have_data = check_data())) {
|
|
// Dump buffered logs to file
|
|
if (!is_restart)
|
|
rename(LOGFILE, LASTLOG);
|
|
log = xfopen(LOGFILE, "a");
|
|
setbuf(log, NULL);
|
|
char *tmp;
|
|
vec_for_each(&logs, tmp) {
|
|
fprintf(log, "%s", tmp);
|
|
free(tmp);
|
|
}
|
|
vec_destroy(&logs);
|
|
} else {
|
|
vec_push_back(&logs, line);
|
|
}
|
|
}
|
|
if (have_data)
|
|
fprintf(log, "%s", line);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static void *debug_magisk_log_thread(void *args) {
|
|
// Setup error handler
|
|
err_handler = exit_thread;
|
|
|
|
FILE *log = xfopen(DEBUG_LOG, "a");
|
|
setbuf(log, NULL);
|
|
int pipefd[2];
|
|
if (xpipe2(pipefd, O_CLOEXEC) == -1)
|
|
return NULL;
|
|
|
|
// Register our listener
|
|
logcat_events[DEBUG_EVENT] = pipefd[1];
|
|
|
|
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;
|
|
}
|
|
|
|
/* Start new threads to monitor logcat and dump to logfile */
|
|
void monitor_logs() {
|
|
pthread_t thread;
|
|
|
|
// Start log file dumper before monitor
|
|
xpthread_create(&thread, NULL, magisk_log_thread, NULL);
|
|
pthread_detach(thread);
|
|
|
|
// Start logcat monitor
|
|
xpthread_create(&thread, NULL, logger_thread, NULL);
|
|
pthread_detach(thread);
|
|
|
|
}
|
|
|
|
void start_debug_full_log() {
|
|
#ifdef MAGISK_DEBUG
|
|
// Log everything initially
|
|
debug_log_fd = xopen(DEBUG_LOG, O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, 0644);
|
|
debug_log_pid = exec_command(0, &debug_log_fd, NULL, "logcat", "-v", "threadtime", NULL);
|
|
close(debug_log_fd);
|
|
#endif
|
|
}
|
|
|
|
void stop_debug_full_log() {
|
|
#ifdef MAGISK_DEBUG
|
|
// Stop recording the boot logcat after every boot task is done
|
|
kill(debug_log_pid, SIGTERM);
|
|
waitpid(debug_log_pid, NULL, 0);
|
|
pthread_t thread;
|
|
// Start debug thread
|
|
xpthread_create(&thread, NULL, debug_magisk_log_thread, NULL);
|
|
pthread_detach(thread);
|
|
start_debug_log();
|
|
#endif
|
|
}
|
|
|
|
void start_debug_log() {
|
|
#ifdef MAGISK_DEBUG
|
|
pthread_t thread;
|
|
// Start debug thread
|
|
xpthread_create(&thread, NULL, debug_magisk_log_thread, NULL);
|
|
pthread_detach(thread);
|
|
#endif
|
|
}
|