mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-22 16:07:39 +00:00
Fix error logging on the C++ side
This commit is contained in:
parent
51e37880c6
commit
36de62873a
1
native/src/Cargo.lock
generated
1
native/src/Cargo.lock
generated
@ -75,6 +75,7 @@ dependencies = [
|
|||||||
"cxx",
|
"cxx",
|
||||||
"cxx-gen",
|
"cxx-gen",
|
||||||
"libc",
|
"libc",
|
||||||
|
"num-derive",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
@ -17,3 +17,4 @@ thiserror = { workspace = true }
|
|||||||
argh = { workspace = true }
|
argh = { workspace = true }
|
||||||
bytemuck = { workspace = true }
|
bytemuck = { workspace = true }
|
||||||
num-traits = { workspace = true }
|
num-traits = { workspace = true }
|
||||||
|
num-derive = { workspace = true }
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#![feature(utf8_chunks)]
|
#![feature(utf8_chunks)]
|
||||||
|
|
||||||
pub use libc;
|
pub use libc;
|
||||||
|
use num_traits::FromPrimitive;
|
||||||
|
|
||||||
pub use cstr::*;
|
pub use cstr::*;
|
||||||
use cxx_extern::*;
|
use cxx_extern::*;
|
||||||
@ -21,7 +22,9 @@ mod xwrap;
|
|||||||
#[cxx::bridge]
|
#[cxx::bridge]
|
||||||
pub mod ffi {
|
pub mod ffi {
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum LogLevel {
|
#[repr(i32)]
|
||||||
|
#[cxx_name = "LogLevel"]
|
||||||
|
pub(crate) enum LogLevelCxx {
|
||||||
ErrorCxx,
|
ErrorCxx,
|
||||||
Error,
|
Error,
|
||||||
Warn,
|
Warn,
|
||||||
@ -36,9 +39,10 @@ pub mod ffi {
|
|||||||
|
|
||||||
extern "Rust" {
|
extern "Rust" {
|
||||||
#[cxx_name = "log_with_rs"]
|
#[cxx_name = "log_with_rs"]
|
||||||
fn log_from_cxx(level: LogLevel, msg: &[u8]);
|
fn log_from_cxx(level: LogLevelCxx, msg: &[u8]);
|
||||||
|
#[cxx_name = "set_log_level_state"]
|
||||||
|
fn set_log_level_state_cxx(level: LogLevelCxx, enabled: bool);
|
||||||
fn exit_on_error(b: bool);
|
fn exit_on_error(b: bool);
|
||||||
fn set_log_level_state(level: LogLevel, enabled: bool);
|
|
||||||
fn cmdline_logging();
|
fn cmdline_logging();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,3 +58,9 @@ pub mod ffi {
|
|||||||
fn enable_selinux();
|
fn enable_selinux();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_log_level_state_cxx(level: ffi::LogLevelCxx, enabled: bool) {
|
||||||
|
if let Some(level) = LogLevel::from_i32(level.repr) {
|
||||||
|
set_log_level_state(level, enabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
|
use num_derive::{FromPrimitive, ToPrimitive};
|
||||||
|
use num_traits::FromPrimitive;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::{Arguments, Display};
|
use std::fmt::{Arguments, Display};
|
||||||
use std::io::{stderr, stdout, Write};
|
use std::io::{stderr, stdout, Write};
|
||||||
use std::panic::Location;
|
use std::panic::Location;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
|
||||||
use crate::ffi::LogLevel;
|
use crate::ffi::LogLevelCxx;
|
||||||
use crate::{Utf8CStr, Utf8CStrBufArr};
|
use crate::{Utf8CStr, Utf8CStrBufArr};
|
||||||
|
|
||||||
// Error handling and logging throughout the Rust codebase in Magisk:
|
// Error handling and logging throughout the Rust codebase in Magisk:
|
||||||
@ -30,6 +32,16 @@ mod LogFlag {
|
|||||||
pub const ExitOnError: u32 = 1 << 4;
|
pub const ExitOnError: u32 = 1 << 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, FromPrimitive, ToPrimitive)]
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum LogLevel {
|
||||||
|
ErrorCxx = LogLevelCxx::ErrorCxx.repr,
|
||||||
|
Error = LogLevelCxx::Error.repr,
|
||||||
|
Warn = LogLevelCxx::Warn.repr,
|
||||||
|
Info = LogLevelCxx::Info.repr,
|
||||||
|
Debug = LogLevelCxx::Debug.repr,
|
||||||
|
}
|
||||||
|
|
||||||
// We don't need to care about thread safety, because all
|
// We don't need to care about thread safety, because all
|
||||||
// logger changes will only happen on the main thread.
|
// logger changes will only happen on the main thread.
|
||||||
pub static mut LOGGER: Logger = Logger {
|
pub static mut LOGGER: Logger = Logger {
|
||||||
@ -63,7 +75,6 @@ impl LogLevel {
|
|||||||
LogLevel::Warn => LogFlag::DisableWarn,
|
LogLevel::Warn => LogFlag::DisableWarn,
|
||||||
LogLevel::Info => LogFlag::DisableInfo,
|
LogLevel::Info => LogFlag::DisableInfo,
|
||||||
LogLevel::Debug => LogFlag::DisableDebug,
|
LogLevel::Debug => LogFlag::DisableDebug,
|
||||||
_ => 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,16 +96,18 @@ fn log_with_writer<F: FnOnce(LogWriter)>(level: LogLevel, f: F) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
f(logger.write);
|
f(logger.write);
|
||||||
if level == LogLevel::ErrorCxx && (logger.flags & LogFlag::ExitOnError) != 0 {
|
if matches!(level, LogLevel::ErrorCxx) && (logger.flags & LogFlag::ExitOnError) != 0 {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log_from_cxx(level: LogLevel, msg: &[u8]) {
|
pub fn log_from_cxx(level: LogLevelCxx, msg: &[u8]) {
|
||||||
|
if let Some(level) = LogLevel::from_i32(level.repr) {
|
||||||
// SAFETY: The null termination is handled on the C++ side
|
// SAFETY: The null termination is handled on the C++ side
|
||||||
let msg = unsafe { Utf8CStr::from_bytes_unchecked(msg) };
|
let msg = unsafe { Utf8CStr::from_bytes_unchecked(msg) };
|
||||||
log_with_writer(level, |write| write(level, msg));
|
log_with_writer(level, |write| write(level, msg));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn log_with_formatter<F: FnOnce(Formatter) -> fmt::Result>(level: LogLevel, f: F) {
|
pub fn log_with_formatter<F: FnOnce(Formatter) -> fmt::Result>(level: LogLevel, f: F) {
|
||||||
log_with_writer(level, |write| {
|
log_with_writer(level, |write| {
|
||||||
@ -110,7 +123,7 @@ pub fn log_with_args(level: LogLevel, args: Arguments) {
|
|||||||
|
|
||||||
pub fn cmdline_logging() {
|
pub fn cmdline_logging() {
|
||||||
fn cmdline_write(level: LogLevel, msg: &Utf8CStr) {
|
fn cmdline_write(level: LogLevel, msg: &Utf8CStr) {
|
||||||
if level == LogLevel::Info {
|
if matches!(level, LogLevel::Info) {
|
||||||
stdout().write_all(msg.as_bytes()).ok();
|
stdout().write_all(msg.as_bytes()).ok();
|
||||||
} else {
|
} else {
|
||||||
stderr().write_all(msg.as_bytes()).ok();
|
stderr().write_all(msg.as_bytes()).ok();
|
||||||
@ -129,21 +142,21 @@ pub fn cmdline_logging() {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! error {
|
macro_rules! error {
|
||||||
($($args:tt)+) => {
|
($($args:tt)+) => {
|
||||||
$crate::log_with_args($crate::ffi::LogLevel::Error, format_args_nl!($($args)+))
|
$crate::log_with_args($crate::LogLevel::Error, format_args_nl!($($args)+))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! warn {
|
macro_rules! warn {
|
||||||
($($args:tt)+) => {
|
($($args:tt)+) => {
|
||||||
$crate::log_with_args($crate::ffi::LogLevel::Warn, format_args_nl!($($args)+))
|
$crate::log_with_args($crate::LogLevel::Warn, format_args_nl!($($args)+))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! info {
|
macro_rules! info {
|
||||||
($($args:tt)+) => {
|
($($args:tt)+) => {
|
||||||
$crate::log_with_args($crate::ffi::LogLevel::Info, format_args_nl!($($args)+))
|
$crate::log_with_args($crate::LogLevel::Info, format_args_nl!($($args)+))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +164,7 @@ macro_rules! info {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! debug {
|
macro_rules! debug {
|
||||||
($($args:tt)+) => {
|
($($args:tt)+) => {
|
||||||
$crate::log_with_args($crate::ffi::LogLevel::Debug, format_args_nl!($($args)+))
|
$crate::log_with_args($crate::LogLevel::Debug, format_args_nl!($($args)+))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,15 +202,15 @@ pub type LoggedResult<T> = Result<T, LoggedError>;
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! log_err {
|
macro_rules! log_err {
|
||||||
($msg:literal $(,)?) => {{
|
($msg:literal $(,)?) => {{
|
||||||
$crate::log_with_args($crate::ffi::LogLevel::Error, format_args_nl!($msg));
|
$crate::log_with_args($crate::LogLevel::Error, format_args_nl!($msg));
|
||||||
$crate::LoggedError::default()
|
$crate::LoggedError::default()
|
||||||
}};
|
}};
|
||||||
($err:expr $(,)?) => {{
|
($err:expr $(,)?) => {{
|
||||||
$crate::log_with_args($crate::ffi::LogLevel::Error, format_args_nl!("{}", $err));
|
$crate::log_with_args($crate::LogLevel::Error, format_args_nl!("{}", $err));
|
||||||
$crate::LoggedError::default()
|
$crate::LoggedError::default()
|
||||||
}};
|
}};
|
||||||
($($args:tt)+) => {{
|
($($args:tt)+) => {{
|
||||||
$crate::log_with_args($crate::ffi::LogLevel::Error, format_args_nl!($($args)+));
|
$crate::log_with_args($crate::LogLevel::Error, format_args_nl!($($args)+));
|
||||||
$crate::LoggedError::default()
|
$crate::LoggedError::default()
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
@ -26,19 +26,19 @@ fn error_str() -> &'static str {
|
|||||||
|
|
||||||
macro_rules! error_cxx {
|
macro_rules! error_cxx {
|
||||||
($($args:tt)+) => {
|
($($args:tt)+) => {
|
||||||
($crate::log_with_args($crate::ffi::LogLevel::ErrorCxx, format_args_nl!($($args)+)))
|
($crate::log_with_args($crate::LogLevel::ErrorCxx, format_args_nl!($($args)+)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! perror {
|
macro_rules! perror {
|
||||||
($fmt:expr) => {
|
($fmt:expr) => {
|
||||||
$crate::log_with_formatter($crate::ffi::LogLevel::ErrorCxx, |w| {
|
$crate::log_with_formatter($crate::LogLevel::ErrorCxx, |w| {
|
||||||
w.write_str($fmt)?;
|
w.write_str($fmt)?;
|
||||||
w.write_fmt(format_args_nl!(" failed with {}: {}", $crate::errno(), error_str()))
|
w.write_fmt(format_args_nl!(" failed with {}: {}", $crate::errno(), error_str()))
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($fmt:expr, $($args:tt)*) => {
|
($fmt:expr, $($args:tt)*) => {
|
||||||
$crate::log_with_formatter($crate::ffi::LogLevel::ErrorCxx, |w| {
|
$crate::log_with_formatter($crate::LogLevel::ErrorCxx, |w| {
|
||||||
w.write_fmt(format_args!($fmt, $($args)*))?;
|
w.write_fmt(format_args!($fmt, $($args)*))?;
|
||||||
w.write_fmt(format_args_nl!(" failed with {}: {}", $crate::errno(), error_str()))
|
w.write_fmt(format_args_nl!(" failed with {}: {}", $crate::errno(), error_str()))
|
||||||
})
|
})
|
||||||
|
@ -11,7 +11,6 @@ use bytemuck::{bytes_of, bytes_of_mut, write_zeroes, Pod, Zeroable};
|
|||||||
use num_derive::{FromPrimitive, ToPrimitive};
|
use num_derive::{FromPrimitive, ToPrimitive};
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
|
|
||||||
use base::ffi::LogLevel;
|
|
||||||
use base::libc::{
|
use base::libc::{
|
||||||
clock_gettime, getpid, gettid, localtime_r, pipe2, pthread_sigmask, sigaddset, sigset_t,
|
clock_gettime, getpid, gettid, localtime_r, pipe2, pthread_sigmask, sigaddset, sigset_t,
|
||||||
sigtimedwait, timespec, tm, CLOCK_REALTIME, O_CLOEXEC, PIPE_BUF, SIGPIPE, SIG_BLOCK,
|
sigtimedwait, timespec, tm, CLOCK_REALTIME, O_CLOEXEC, PIPE_BUF, SIGPIPE, SIG_BLOCK,
|
||||||
@ -50,11 +49,10 @@ extern "C" {
|
|||||||
|
|
||||||
fn level_to_prio(level: LogLevel) -> i32 {
|
fn level_to_prio(level: LogLevel) -> i32 {
|
||||||
match level {
|
match level {
|
||||||
LogLevel::Error => ALogPriority::ANDROID_LOG_ERROR as i32,
|
LogLevel::Error | LogLevel::ErrorCxx => ALogPriority::ANDROID_LOG_ERROR as i32,
|
||||||
LogLevel::Warn => ALogPriority::ANDROID_LOG_WARN as i32,
|
LogLevel::Warn => ALogPriority::ANDROID_LOG_WARN as i32,
|
||||||
LogLevel::Info => ALogPriority::ANDROID_LOG_INFO as i32,
|
LogLevel::Info => ALogPriority::ANDROID_LOG_INFO as i32,
|
||||||
LogLevel::Debug => ALogPriority::ANDROID_LOG_DEBUG as i32,
|
LogLevel::Debug => ALogPriority::ANDROID_LOG_DEBUG as i32,
|
||||||
_ => 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,12 +3,11 @@ use std::fs::File;
|
|||||||
use std::io::{IoSlice, Write};
|
use std::io::{IoSlice, Write};
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
use base::ffi::LogLevel;
|
|
||||||
use base::libc::{
|
use base::libc::{
|
||||||
close, makedev, mknod, open, syscall, unlink, SYS_dup3, O_CLOEXEC, O_RDWR, STDERR_FILENO,
|
close, makedev, mknod, open, syscall, unlink, SYS_dup3, O_CLOEXEC, O_RDWR, STDERR_FILENO,
|
||||||
STDIN_FILENO, STDOUT_FILENO, S_IFCHR,
|
STDIN_FILENO, STDOUT_FILENO, S_IFCHR,
|
||||||
};
|
};
|
||||||
use base::{cstr, exit_on_error, raw_cstr, Logger, Utf8CStr, LOGGER};
|
use base::{cstr, exit_on_error, raw_cstr, LogLevel, Logger, Utf8CStr, LOGGER};
|
||||||
|
|
||||||
static KMSG: OnceLock<File> = OnceLock::new();
|
static KMSG: OnceLock<File> = OnceLock::new();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user