mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-01-11 23:33:37 +00:00
Setup logging infra in the Rust side
This commit is contained in:
parent
3817167ba1
commit
b4863eb51b
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#undef _FORTIFY_SOURCE
|
#undef _FORTIFY_SOURCE
|
||||||
|
|
||||||
extern int __vloge(const char* fmt, va_list ap);
|
extern void __vloge(const char* fmt, va_list ap);
|
||||||
|
|
||||||
static inline __noreturn __printflike(1, 2) void __fortify_fatal(const char* fmt, ...) {
|
static inline __noreturn __printflike(1, 2) void __fortify_fatal(const char* fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@ -5,3 +5,4 @@
|
|||||||
#include "../files.hpp"
|
#include "../files.hpp"
|
||||||
#include "../misc.hpp"
|
#include "../misc.hpp"
|
||||||
#include "../logging.hpp"
|
#include "../logging.hpp"
|
||||||
|
#include <base-rs.hpp>
|
||||||
|
@ -2,41 +2,52 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include <flags.h>
|
#include <flags.h>
|
||||||
|
#include <base.hpp>
|
||||||
|
|
||||||
#include "logging.hpp"
|
// Just need to include it somewhere
|
||||||
|
#include <base-rs.cpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
int nop_log(const char *, va_list) { return 0; }
|
void nop_log(const char *, va_list) {}
|
||||||
|
|
||||||
void nop_ex(int) {}
|
|
||||||
|
|
||||||
log_callback log_cb = {
|
log_callback log_cb = {
|
||||||
.d = nop_log,
|
.d = nop_log,
|
||||||
.i = nop_log,
|
.i = nop_log,
|
||||||
.w = nop_log,
|
.w = nop_log,
|
||||||
.e = nop_log,
|
.e = nop_log,
|
||||||
.ex = nop_ex
|
|
||||||
};
|
};
|
||||||
|
static bool EXIT_ON_ERROR = false;
|
||||||
|
|
||||||
void no_logging() {
|
static void fmt_and_log_with_rs(LogLevel level, const char *fmt, va_list ap) {
|
||||||
log_cb.d = nop_log;
|
char buf[4096];
|
||||||
log_cb.i = nop_log;
|
int len = vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||||
log_cb.w = nop_log;
|
if (len > 0 && buf[len - 1] == '\n') {
|
||||||
log_cb.e = nop_log;
|
// It's unfortunate that all logging on the C++ side always manually include
|
||||||
log_cb.ex = nop_ex;
|
// a newline at the end due to how it was originally implemented.
|
||||||
|
// The logging infrastructure on the rust side does NOT expect a newline
|
||||||
|
// at the end, so we will have to strip it out before sending it over.
|
||||||
|
buf[len - 1] = '\0';
|
||||||
|
}
|
||||||
|
log_with_rs(level, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vprintfe(const char *fmt, va_list ap) {
|
#define rlog(prio) [](auto fmt, auto ap) { fmt_and_log_with_rs(LogLevel::prio, fmt, ap); }
|
||||||
return vfprintf(stderr, fmt, ap);
|
static void forward_logging_to_rs() {
|
||||||
|
log_cb.d = rlog(Debug);
|
||||||
|
log_cb.i = rlog(Info);
|
||||||
|
log_cb.w = rlog(Warn);
|
||||||
|
log_cb.e = rlog(Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmdline_logging() {
|
void cmdline_logging() {
|
||||||
log_cb.d = vprintfe;
|
rs::logging::cmdline_logging();
|
||||||
log_cb.i = vprintf;
|
forward_logging_to_rs();
|
||||||
log_cb.w = vprintfe;
|
}
|
||||||
log_cb.e = vprintfe;
|
|
||||||
log_cb.ex = exit;
|
void exit_on_error(bool b) {
|
||||||
|
rs::logging::exit_on_error(b);
|
||||||
|
EXIT_ON_ERROR = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOG_BODY(prio) { \
|
#define LOG_BODY(prio) { \
|
||||||
@ -54,9 +65,9 @@ void LOGD(const char *fmt, ...) {}
|
|||||||
#endif
|
#endif
|
||||||
void LOGI(const char *fmt, ...) { LOG_BODY(i) }
|
void LOGI(const char *fmt, ...) { LOG_BODY(i) }
|
||||||
void LOGW(const char *fmt, ...) { LOG_BODY(w) }
|
void LOGW(const char *fmt, ...) { LOG_BODY(w) }
|
||||||
void LOGE(const char *fmt, ...) { LOG_BODY(e); log_cb.ex(EXIT_FAILURE); }
|
void LOGE(const char *fmt, ...) { LOG_BODY(e); if (EXIT_ON_ERROR) exit(EXIT_FAILURE); }
|
||||||
|
|
||||||
// Export raw symbol to fortify compat
|
// Export raw symbol to fortify compat
|
||||||
extern "C" int __vloge(const char* fmt, va_list ap) {
|
extern "C" void __vloge(const char* fmt, va_list ap) {
|
||||||
return log_cb.e(fmt, ap);
|
log_cb.e(fmt, ap);
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,10 @@
|
|||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
|
|
||||||
struct log_callback {
|
struct log_callback {
|
||||||
int (*d)(const char* fmt, va_list ap);
|
void (*d)(const char* fmt, va_list ap);
|
||||||
int (*i)(const char* fmt, va_list ap);
|
void (*i)(const char* fmt, va_list ap);
|
||||||
int (*w)(const char* fmt, va_list ap);
|
void (*w)(const char* fmt, va_list ap);
|
||||||
int (*e)(const char* fmt, va_list ap);
|
void (*e)(const char* fmt, va_list ap);
|
||||||
void (*ex)(int code);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern log_callback log_cb;
|
extern log_callback log_cb;
|
||||||
@ -19,8 +18,7 @@ void LOGW(const char *fmt, ...) __printflike(1, 2);
|
|||||||
void LOGE(const char *fmt, ...) __printflike(1, 2);
|
void LOGE(const char *fmt, ...) __printflike(1, 2);
|
||||||
#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s\n", ##args, errno, std::strerror(errno))
|
#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s\n", ##args, errno, std::strerror(errno))
|
||||||
|
|
||||||
int nop_log(const char *, va_list);
|
void nop_log(const char *, va_list);
|
||||||
void nop_ex(int);
|
|
||||||
|
|
||||||
void no_logging();
|
|
||||||
void cmdline_logging();
|
void cmdline_logging();
|
||||||
|
void exit_on_error(bool b);
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#include <resetprop.hpp>
|
#include <resetprop.hpp>
|
||||||
#include <flags.h>
|
#include <flags.h>
|
||||||
|
|
||||||
|
#include <core-rs.cpp>
|
||||||
|
|
||||||
#include "core.hpp"
|
#include "core.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -166,22 +166,22 @@ extern "C" int magisk_log_print(int prio, const char *tag, const char *fmt, ...)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define mlog(prio) [](auto fmt, auto ap){ return magisk_log(ANDROID_LOG_##prio, fmt, ap); }
|
#define mlog(prio) [](auto fmt, auto ap){ magisk_log(ANDROID_LOG_##prio, fmt, ap); }
|
||||||
void magisk_logging() {
|
void magisk_logging() {
|
||||||
log_cb.d = mlog(DEBUG);
|
log_cb.d = mlog(DEBUG);
|
||||||
log_cb.i = mlog(INFO);
|
log_cb.i = mlog(INFO);
|
||||||
log_cb.w = mlog(WARN);
|
log_cb.w = mlog(WARN);
|
||||||
log_cb.e = mlog(ERROR);
|
log_cb.e = mlog(ERROR);
|
||||||
log_cb.ex = nop_ex;
|
exit_on_error(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define alog(prio) [](auto fmt, auto ap){ return __android_log_vprint(ANDROID_LOG_##prio, "Magisk", fmt, ap); }
|
#define alog(prio) [](auto fmt, auto ap){ __android_log_vprint(ANDROID_LOG_##prio, "Magisk", fmt, ap); }
|
||||||
void android_logging() {
|
void android_logging() {
|
||||||
log_cb.d = alog(DEBUG);
|
log_cb.d = alog(DEBUG);
|
||||||
log_cb.i = alog(INFO);
|
log_cb.i = alog(INFO);
|
||||||
log_cb.w = alog(WARN);
|
log_cb.w = alog(WARN);
|
||||||
log_cb.e = alog(ERROR);
|
log_cb.e = alog(ERROR);
|
||||||
log_cb.ex = nop_ex;
|
exit_on_error(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_log_daemon() {
|
void start_log_daemon() {
|
||||||
|
@ -127,6 +127,7 @@ int magisk_main(int argc, char *argv[]) {
|
|||||||
#if 0
|
#if 0
|
||||||
/* Entry point for testing stuffs */
|
/* Entry point for testing stuffs */
|
||||||
else if (argv[1] == "--test"sv) {
|
else if (argv[1] == "--test"sv) {
|
||||||
|
rust_test_entry();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include <socket.hpp>
|
#include <socket.hpp>
|
||||||
|
#include <core-rs.hpp>
|
||||||
|
|
||||||
#define AID_ROOT 0
|
#define AID_ROOT 0
|
||||||
#define AID_SHELL 2000
|
#define AID_SHELL 2000
|
||||||
|
@ -119,9 +119,9 @@ static bool check_key_combo() {
|
|||||||
|
|
||||||
static FILE *kmsg;
|
static FILE *kmsg;
|
||||||
static char kmsg_buf[4096];
|
static char kmsg_buf[4096];
|
||||||
static int vprintk(const char *fmt, va_list ap) {
|
static void vprintk(const char *fmt, va_list ap) {
|
||||||
vsnprintf(kmsg_buf + 12, sizeof(kmsg_buf) - 12, fmt, ap);
|
vsnprintf(kmsg_buf + 12, sizeof(kmsg_buf) - 12, fmt, ap);
|
||||||
return fprintf(kmsg, "%s", kmsg_buf);
|
fprintf(kmsg, "%s", kmsg_buf);
|
||||||
}
|
}
|
||||||
void setup_klog() {
|
void setup_klog() {
|
||||||
// Shut down first 3 fds
|
// Shut down first 3 fds
|
||||||
@ -150,7 +150,7 @@ void setup_klog() {
|
|||||||
kmsg = fdopen(fd, "w");
|
kmsg = fdopen(fd, "w");
|
||||||
setbuf(kmsg, nullptr);
|
setbuf(kmsg, nullptr);
|
||||||
log_cb.d = log_cb.i = log_cb.w = log_cb.e = vprintk;
|
log_cb.d = log_cb.i = log_cb.w = log_cb.e = vprintk;
|
||||||
log_cb.ex = nop_ex;
|
exit_on_error(false);
|
||||||
strcpy(kmsg_buf, "magiskinit: ");
|
strcpy(kmsg_buf, "magiskinit: ");
|
||||||
|
|
||||||
// Disable kmsg rate limiting
|
// Disable kmsg rate limiting
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static bool verbose = false;
|
|
||||||
|
|
||||||
#ifdef APPLET_STUB_MAIN
|
#ifdef APPLET_STUB_MAIN
|
||||||
#define system_property_set __system_property_set
|
#define system_property_set __system_property_set
|
||||||
#define system_property_find __system_property_find
|
#define system_property_find __system_property_find
|
||||||
@ -297,10 +295,9 @@ void load_prop_file(const char *filename, bool prop_svc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int resetprop_main(int argc, char *argv[]) {
|
int resetprop_main(int argc, char *argv[]) {
|
||||||
log_cb.d = [](auto fmt, auto ap) -> int { return verbose ? vfprintf(stderr, fmt, ap) : 0; };
|
|
||||||
|
|
||||||
bool prop_svc = true;
|
bool prop_svc = true;
|
||||||
bool persist = false;
|
bool persist = false;
|
||||||
|
bool verbose = false;
|
||||||
char *argv0 = argv[0];
|
char *argv0 = argv[0];
|
||||||
|
|
||||||
--argc;
|
--argc;
|
||||||
@ -340,6 +337,9 @@ int resetprop_main(int argc, char *argv[]) {
|
|||||||
++argv;
|
++argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!verbose)
|
||||||
|
log_cb.d = nop_log;
|
||||||
|
|
||||||
switch (argc) {
|
switch (argc) {
|
||||||
case 0:
|
case 0:
|
||||||
print_props(persist);
|
print_props(persist);
|
||||||
|
@ -311,7 +311,7 @@ void su_daemon_handler(int client, const sock_cred *cred) {
|
|||||||
LOGD("su: fork handler\n");
|
LOGD("su: fork handler\n");
|
||||||
|
|
||||||
// Abort upon any error occurred
|
// Abort upon any error occurred
|
||||||
log_cb.ex = exit;
|
exit_on_error(true);
|
||||||
|
|
||||||
// ack
|
// ack
|
||||||
write_int(client, 0);
|
write_int(client, 0);
|
||||||
|
@ -17,15 +17,15 @@ using namespace std;
|
|||||||
|
|
||||||
void *self_handle = nullptr;
|
void *self_handle = nullptr;
|
||||||
|
|
||||||
static int zygisk_log(int prio, const char *fmt, va_list ap);
|
static void zygisk_log(int prio, const char *fmt, va_list ap);
|
||||||
|
|
||||||
#define zlog(prio) [](auto fmt, auto ap){ return zygisk_log(ANDROID_LOG_##prio, fmt, ap); }
|
#define zlog(prio) [](auto fmt, auto ap){ zygisk_log(ANDROID_LOG_##prio, fmt, ap); }
|
||||||
static void zygisk_logging() {
|
static void zygisk_logging() {
|
||||||
log_cb.d = zlog(DEBUG);
|
log_cb.d = zlog(DEBUG);
|
||||||
log_cb.i = zlog(INFO);
|
log_cb.i = zlog(INFO);
|
||||||
log_cb.w = zlog(WARN);
|
log_cb.w = zlog(WARN);
|
||||||
log_cb.e = zlog(ERROR);
|
log_cb.e = zlog(ERROR);
|
||||||
log_cb.ex = nop_ex;
|
exit_on_error(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure /proc/self/environ is sanitized
|
// Make sure /proc/self/environ is sanitized
|
||||||
@ -114,7 +114,7 @@ static void zygisk_init() {
|
|||||||
|
|
||||||
// The following code runs in zygote/app process
|
// The following code runs in zygote/app process
|
||||||
|
|
||||||
static int zygisk_log(int prio, const char *fmt, va_list ap) {
|
static void zygisk_log(int prio, const char *fmt, va_list ap) {
|
||||||
// If we don't have log pipe set, ask magiskd for it
|
// If we don't have log pipe set, ask magiskd for it
|
||||||
// This could happen multiple times in zygote because it was closed to prevent crashing
|
// This could happen multiple times in zygote because it was closed to prevent crashing
|
||||||
if (logd_fd < 0) {
|
if (logd_fd < 0) {
|
||||||
@ -139,13 +139,12 @@ static int zygisk_log(int prio, const char *fmt, va_list ap) {
|
|||||||
sigaddset(&mask, SIGPIPE);
|
sigaddset(&mask, SIGPIPE);
|
||||||
pthread_sigmask(SIG_BLOCK, &mask, &orig_mask);
|
pthread_sigmask(SIG_BLOCK, &mask, &orig_mask);
|
||||||
}
|
}
|
||||||
int ret = magisk_log(prio, fmt, ap);
|
magisk_log(prio, fmt, ap);
|
||||||
if (sig) {
|
if (sig) {
|
||||||
timespec ts{};
|
timespec ts{};
|
||||||
sigtimedwait(&mask, nullptr, &ts);
|
sigtimedwait(&mask, nullptr, &ts);
|
||||||
pthread_sigmask(SIG_SETMASK, &orig_mask, nullptr);
|
pthread_sigmask(SIG_SETMASK, &orig_mask, nullptr);
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool should_load_modules(uint32_t flags) {
|
static inline bool should_load_modules(uint32_t flags) {
|
||||||
|
3
native/rust/Cargo.lock
generated
3
native/rust/Cargo.lock
generated
@ -5,6 +5,9 @@ version = 3
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "base"
|
name = "base"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"cxx",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
|
@ -4,3 +4,4 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
cxx = "1.0.69"
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
pub use logging::*;
|
||||||
|
|
||||||
|
mod logging;
|
||||||
|
|
||||||
|
#[cxx::bridge]
|
||||||
|
pub mod ffi {
|
||||||
|
pub enum LogLevel {
|
||||||
|
Error,
|
||||||
|
Warn,
|
||||||
|
Info,
|
||||||
|
Debug,
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "Rust" {
|
||||||
|
fn log_with_rs(level: LogLevel, msg: &str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cxx::bridge(namespace = "rs::logging")]
|
||||||
|
pub mod ffi2 {
|
||||||
|
extern "Rust" {
|
||||||
|
fn cmdline_logging();
|
||||||
|
fn exit_on_error(b: bool);
|
||||||
|
}
|
||||||
|
}
|
91
native/rust/base/src/logging.rs
Normal file
91
native/rust/base/src/logging.rs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
use std::fmt::Arguments;
|
||||||
|
use std::process::exit;
|
||||||
|
|
||||||
|
use crate::ffi::LogLevel;
|
||||||
|
|
||||||
|
// We don't need to care about thread safety, because all
|
||||||
|
// logger changes will only happen on the main thread.
|
||||||
|
pub static mut LOGGER: Logger = Logger {
|
||||||
|
d: nop_log,
|
||||||
|
i: nop_log,
|
||||||
|
w: nop_log,
|
||||||
|
e: nop_log,
|
||||||
|
};
|
||||||
|
static mut EXIT_ON_ERROR: bool = false;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Logger {
|
||||||
|
pub d: fn(args: Arguments),
|
||||||
|
pub i: fn(args: Arguments),
|
||||||
|
pub w: fn(args: Arguments),
|
||||||
|
pub e: fn(args: Arguments),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nop_log(_: Arguments) {}
|
||||||
|
|
||||||
|
fn println(args: Arguments) { println!("{}", args); }
|
||||||
|
|
||||||
|
fn eprintln(args: Arguments) { eprintln!("{}", args); }
|
||||||
|
|
||||||
|
pub fn log_with_rs(level: LogLevel, msg: &str) {
|
||||||
|
log_impl(level, format_args!("{}", msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exit_on_error(b: bool) {
|
||||||
|
unsafe { EXIT_ON_ERROR = b; }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cmdline_logging() {
|
||||||
|
let logger = Logger {
|
||||||
|
d: eprintln,
|
||||||
|
i: println,
|
||||||
|
w: eprintln,
|
||||||
|
e: eprintln,
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
LOGGER = logger;
|
||||||
|
EXIT_ON_ERROR = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn log_impl(level: LogLevel, args: Arguments) {
|
||||||
|
let logger = unsafe { LOGGER };
|
||||||
|
let aoe = unsafe { EXIT_ON_ERROR };
|
||||||
|
match level {
|
||||||
|
LogLevel::Error => {
|
||||||
|
(logger.e)(args);
|
||||||
|
if aoe { exit(1); }
|
||||||
|
}
|
||||||
|
LogLevel::Warn => (logger.w)(args),
|
||||||
|
LogLevel::Info => (logger.i)(args),
|
||||||
|
LogLevel::Debug => (logger.d)(args),
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! error {
|
||||||
|
($($arg:tt)+) => ($crate::log_impl($crate::ffi::LogLevel::Error, format_args!($($arg)+)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! warn {
|
||||||
|
($($arg:tt)+) => ($crate::log_impl($crate::ffi::LogLevel::Warn, format_args!($($arg)+)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! info {
|
||||||
|
($($arg:tt)+) => ($crate::log_impl($crate::ffi::LogLevel::Info, format_args!($($arg)+)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! debug {
|
||||||
|
($($arg:tt)+) => ($crate::log_impl($crate::ffi::LogLevel::Debug, format_args!($($arg)+)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! debug {
|
||||||
|
($($arg:tt)+) => ()
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
pub use base;
|
@ -0,0 +1,10 @@
|
|||||||
|
pub use base;
|
||||||
|
|
||||||
|
#[cxx::bridge]
|
||||||
|
pub mod ffi {
|
||||||
|
extern "Rust" {
|
||||||
|
fn rust_test_entry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rust_test_entry() {}
|
@ -0,0 +1 @@
|
|||||||
|
pub use base;
|
@ -0,0 +1 @@
|
|||||||
|
pub use base;
|
Loading…
x
Reference in New Issue
Block a user