libbase module
目录
- 概述
- 源码分析
- 1. logging模块
- 1.1 InitLogging-初始化进程的log输出
- 1.2 SetLogger-设置log回调函数__android_log_set_logger
- 1.3 SetAborter-调用liblog的__android_log_set_aborter
- 1.4 SetDefaultTag-设置log的tag格式
- 1.5 KernelLogger-打开/dev/kmsg写入log
- 1.6 GetLibLogFunctions-获得liblog中的函数
- 1.7 SetMinimumLogSeverity-设置log的最小显示级别
- 1.8 ShouldLog-根据loglevel来判断
- 1.9 LOG(INFO) << "print log";
- 1.10 LogMessage-将log打印出来
- 1.11 LogMessageData
- 1.12 stream-给buffer输入值,然后在LogMessage析构函数处打印log
- 1.13 LogMessage-析构函数
- 1.14 LogLine
- 2. logging_splitters模块
- 3. string模块
- 4. ScopeGuard类-确保无论当前作用域如何退出,都执行指定的函数
- 5. unique_fd模块
- 1. logging模块
- 补充
- 问题
- 参考
概述
android/system/core/base-log打印,字符串,文件读写
源码分析
1. logging模块
1.1 InitLogging-初始化进程的log输出
// android::base::KernelLogger和InitAborter
void InitLogging(char* argv[], LogFunction&& logger, AbortFunction&& aborter) {
// log输出的地方
SetLogger(std::forward<LogFunction>(logger));
// log fatal的时候,调用的回调
SetAborter(std::forward<AbortFunction>(aborter));
if (gInitialized) {
return;
}
// 每个进程只需要初始化一次
gInitialized = true;
// Stash the command line for later use. We can use /proc/self/cmdline on
// Linux to recover this, but we don't have that luxury on the Mac/Windows,
// and there are a couple of argv[0] variants that are commonly used.
// 根据传入的参数,设置tag的名称
if (argv != nullptr) {
SetDefaultTag(basename(argv[0]));
}
// 设置最小打印等级
const char* tags = getenv("ANDROID_LOG_TAGS");
if (tags == nullptr) {
return;
}
std::vector<std::string> specs = Split(tags, " ");
for (size_t i = 0; i < specs.size(); ++i) {
// "tag-pattern:[vdiwefs]"
// 比如vold设置:setenv("ANDROID_LOG_TAGS", "*:d", 1); // Do not submit with verbose logs enabled
std::string spec(specs[i]);
if (spec.size() == 3 && StartsWith(spec, "*:")) {
switch (spec[2]) {
case 'v':
// 设置最小打印等级
SetMinimumLogSeverity(VERBOSE);
continue;
case 'd':
SetMinimumLogSeverity(DEBUG);
continue;
case 'i':
SetMinimumLogSeverity(INFO);
continue;
case 'w':
SetMinimumLogSeverity(WARNING);
continue;
case 'e':
SetMinimumLogSeverity(ERROR);
continue;
case 'f':
SetMinimumLogSeverity(FATAL_WITHOUT_ABORT);
continue;
// liblog will even suppress FATAL if you say 's' for silent, but that's
// crazy!
case 's':
SetMinimumLogSeverity(FATAL_WITHOUT_ABORT);
continue;
}
}
LOG(FATAL) << "unsupported '" << spec << "' in ANDROID_LOG_TAGS (" << tags
<< ")";
}
}
1.2 SetLogger-设置log回调函数__android_log_set_logger
void SetLogger(LogFunction&& logger) {
Logger() = std::move(logger);
static auto& liblog_functions = GetLibLogFunctions();
if (liblog_functions) {// 设置了log的回调函数
liblog_functions->__android_log_set_logger([](const struct __android_log_message* log_message) {
auto log_id = log_id_tToLogId(log_message->buffer_id);
auto severity = PriorityToLogSeverity(log_message->priority);
Logger()(log_id, severity, log_message->tag, log_message->file, log_message->line,
log_message->message);
});
}
}
1.3 SetAborter-调用liblog的__android_log_set_aborter
void SetAborter(AbortFunction&& aborter) {
Aborter() = std::move(aborter);
static auto& liblog_functions = GetLibLogFunctions();
if (liblog_functions) {
liblog_functions->__android_log_set_aborter(// 设置了abort的回调函数
[](const char* abort_message) { Aborter()(abort_message); });
}
}
1.4 SetDefaultTag-设置log的tag格式
void SetDefaultTag(const std::string& tag) {
static auto& liblog_functions = GetLibLogFunctions();
if (liblog_functions) {
// 设置tag
liblog_functions->__android_log_set_default_tag(tag.c_str());
} else {
std::lock_guard<std::recursive_mutex> lock(TagLock());
if (gDefaultTag != nullptr) {
delete gDefaultTag;
gDefaultTag = nullptr;
}
if (!tag.empty()) {
gDefaultTag = new std::string(tag);
}
}
}
1.5 KernelLogger-打开/dev/kmsg写入log
void KernelLogger(android::base::LogId, android::base::LogSeverity severity, const char* tag,
const char*, unsigned int, const char* full_message) {
// 这里调用KernelLogLine函数
SplitByLines(full_message, KernelLogLine, severity, tag);
}
static void KernelLogLine(const char* msg, int length, android::base::LogSeverity severity,
const char* tag) {
// clang-format off
static constexpr int kLogSeverityToKernelLogLevel[] = {
[android::base::VERBOSE] = 7, // KERN_DEBUG (there is no verbose kernel log
// level)
[android::base::DEBUG] = 7, // KERN_DEBUG
[android::base::INFO] = 6, // KERN_INFO
[android::base::WARNING] = 4, // KERN_WARNING
[android::base::ERROR] = 3, // KERN_ERROR
[android::base::FATAL_WITHOUT_ABORT] = 2, // KERN_CRIT
[android::base::FATAL] = 2, // KERN_CRIT
};
// clang-format on
static_assert(arraysize(kLogSeverityToKernelLogLevel) == android::base::FATAL + 1,
"Mismatch in size of kLogSeverityToKernelLogLevel and values in LogSeverity");
// 打开/dev/kmsg文件
static int klog_fd = OpenKmsg();
if (klog_fd == -1) return;
int level = kLogSeverityToKernelLogLevel[severity];
// The kernel's printk buffer is only 1024 bytes.
// TODO: should we automatically break up long lines into multiple lines?
// Or we could log but with something like "..." at the end?
char buf[1024] __attribute__((__uninitialized__));
size_t size = snprintf(buf, sizeof(buf), "<%d>%s: %.*s\n", level, tag, length, msg);
if (size > sizeof(buf)) {
size = snprintf(buf, sizeof(buf), "<%d>%s: %zu-byte message too long for printk\n",
level, tag, size);
}
iovec iov[1];
iov[0].iov_base = buf;
iov[0].iov_len = size;
// 然后写进去
TEMP_FAILURE_RETRY(writev(klog_fd, iov, 1));
}
#if defined(__linux__)
static int OpenKmsg() {
#if defined(__ANDROID__)
// pick up 'file w /dev/kmsg' environment from daemon's init rc file
const auto val = getenv("ANDROID_FILE__dev_kmsg");
if (val != nullptr) {
int fd;
if (android::base::ParseInt(val, &fd, 0)) {
auto flags = fcntl(fd, F_GETFL);
if ((flags != -1) && ((flags & O_ACCMODE) == O_WRONLY)) return fd;
}
}
#endif
return TEMP_FAILURE_RETRY(open("/dev/kmsg", O_WRONLY | O_CLOEXEC));
}
#endif
1.6 GetLibLogFunctions-获得liblog中的函数
#ifdef USE_DLSYM
// 对于SDK版本是29的,Android10以下的,则使用动态库加载的方式
const std::optional<LibLogFunctions>& GetLibLogFunctions() {
static std::optional<LibLogFunctions> liblog_functions = []() -> std::optional<LibLogFunctions> {
void* liblog_handle = dlopen("liblog.so", RTLD_NOW);
if (liblog_handle == nullptr) {
return {};
}
LibLogFunctions real_liblog_functions = {};
#define DLSYM(name) \
real_liblog_functions.name = \
reinterpret_cast<decltype(LibLogFunctions::name)>(dlsym(liblog_handle, #name)); \
if (real_liblog_functions.name == nullptr) { \
return {}; \
}
DLSYM(__android_log_set_logger)
DLSYM(__android_log_write_log_message)
DLSYM(__android_log_logd_logger)
DLSYM(__android_log_stderr_logger)
DLSYM(__android_log_set_aborter)
DLSYM(__android_log_call_aborter)
DLSYM(__android_log_default_aborter)
DLSYM(__android_log_set_minimum_priority);
DLSYM(__android_log_get_minimum_priority);
DLSYM(__android_log_set_default_tag);
#undef DLSYM
return real_liblog_functions;
}();
return liblog_functions;
}
#else
// Android 11的,直接使用;所以libbase依赖于动态库liblog
const std::optional<LibLogFunctions>& GetLibLogFunctions() {
static std::optional<LibLogFunctions> liblog_functions = []() -> std::optional<LibLogFunctions> {
return LibLogFunctions{
.__android_log_set_logger = __android_log_set_logger,
.__android_log_write_log_message = __android_log_write_log_message,
.__android_log_logd_logger = __android_log_logd_logger,
.__android_log_stderr_logger = __android_log_stderr_logger,
.__android_log_set_aborter = __android_log_set_aborter,
.__android_log_call_aborter = __android_log_call_aborter,
.__android_log_default_aborter = __android_log_default_aborter,
.__android_log_set_minimum_priority = __android_log_set_minimum_priority,
.__android_log_get_minimum_priority = __android_log_get_minimum_priority,
.__android_log_set_default_tag = __android_log_set_default_tag,
};
}();
return liblog_functions;
}
#endif
1.7 SetMinimumLogSeverity-设置log的最小显示级别
LogSeverity SetMinimumLogSeverity(LogSeverity new_severity) {
static auto& liblog_functions = GetLibLogFunctions();
if (liblog_functions) {
// VERBOSE -> ANDROID_LOG_VERBOSE的转换
int32_t priority = LogSeverityToPriority(new_severity);
// ANDROID_LOG_VERBOSE -> VERBOSE的转换
return PriorityToLogSeverity(liblog_functions->__android_log_set_minimum_priority(priority));
} else {
LogSeverity old_severity = gMinimumLogSeverity;
gMinimumLogSeverity = new_severity;
return old_severity;
}
}
1.8 ShouldLog-根据loglevel来判断
bool ShouldLog(LogSeverity severity, const char* tag) {
static auto& liblog_functions = GetLibLogFunctions();
// Even though we're not using the R liblog functions in this function, if we're running on Q,
// we need to fall back to using gMinimumLogSeverity, since __android_log_is_loggable() will not
// take into consideration the value from SetMinimumLogSeverity().
if (liblog_functions) {
int32_t priority = LogSeverityToPriority(severity);
// 所以verbose和debug的log可能不会被打印出来
return __android_log_is_loggable(priority, tag, ANDROID_LOG_INFO);
} else {
return severity >= gMinimumLogSeverity;
}
}
1.9 LOG(INFO) << "print log";
// 如果LOGGING_PREAMBLE(severity)为true,才会将log打印出来
#define LOG(severity) LOGGING_PREAMBLE(severity) && LOG_STREAM(severity)
#define LOGGING_PREAMBLE(severity) \
(WOULD_LOG(severity) && // unlikely返回0 \
// severity为fatal则执行abort,默认返回true
ABORT_AFTER_LOG_EXPR_IF((SEVERITY_LAMBDA(severity)) == ::android::base::FATAL, true) && \
// 保存errno,默认返回true
::android::base::ErrnoRestorer())
#define WOULD_LOG(severity) \
// ShouldLog很可能返回0,大部分的log其实都不显示出来,所以这里用了UNLIKELY
// first_stage_init阶段的时候,>= INFO的就返回true
(UNLIKELY(::android::base::ShouldLog(SEVERITY_LAMBDA(severity), _LOG_TAG_INTERNAL)) || \
// 默认是false或者等于FATAL
MUST_LOG_MESSAGE(severity))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
// 将log打印出来
#define LOG_STREAM(severity) \
::android::base::LogMessage(__FILE__, __LINE__, SEVERITY_LAMBDA(severity), _LOG_TAG_INTERNAL, \
-1) \
.stream()
1.10 LogMessage-将log打印出来
LogMessage::LogMessage(const char* file, unsigned int line, LogSeverity severity, const char* tag,
int error)
: data_(new LogMessageData(file, line, severity, tag, error)) {}
1.11 LogMessageData
LogMessageData(const char* file, unsigned int line, LogSeverity severity, const char* tag,
int error)
: file_(GetFileBasename(file)),
line_number_(line),
severity_(severity),
tag_(tag),
error_(error) {}
1.12 stream-给buffer输入值,然后在LogMessage析构函数处打印log
std::ostream& LogMessage::stream() {
return data_->GetBuffer();
}
std::ostream& GetBuffer() {
return buffer_;
}
1.13 LogMessage-析构函数
LogMessage::~LogMessage() {
// Check severity again. This is duplicate work wrt/ LOG macros, but not LOG_STREAM.
if (!WOULD_LOG(data_->GetSeverity())) {
return;
}
// Finish constructing the message.
if (data_->GetError() != -1) {
data_->GetBuffer() << ": " << strerror(data_->GetError());
}
// 获得log信息
std::string msg(data_->ToString());
if (data_->GetSeverity() == FATAL) {
#ifdef __ANDROID__
// Set the bionic abort message early to avoid liblog doing it
// with the individual lines, so that we get the whole message.
android_set_abort_message(msg.c_str());
#endif
}
// 打印log信息
LogLine(data_->GetFile(), data_->GetLineNumber(), data_->GetSeverity(), data_->GetTag(),
msg.c_str());
// Abort if necessary.
if (data_->GetSeverity() == FATAL) {
static auto& liblog_functions = GetLibLogFunctions();
if (liblog_functions) {
liblog_functions->__android_log_call_aborter(msg.c_str());
} else {
Aborter()(msg.c_str());
}
}
}
1.14 LogLine
void LogMessage::LogLine(const char* file, unsigned int line, LogSeverity severity, const char* tag,
const char* message) {
static auto& liblog_functions = GetLibLogFunctions();
int32_t priority = LogSeverityToPriority(severity);
if (liblog_functions) {
__android_log_message log_message = {
sizeof(__android_log_message), LOG_ID_DEFAULT, priority, tag, file, line, message};
// 调用这个打印log,这里会跑到KernelLogger函数中
liblog_functions->__android_log_write_log_message(&log_message);
} else {
if (tag == nullptr) {
std::lock_guard<std::recursive_mutex> lock(TagLock());
if (gDefaultTag == nullptr) {
gDefaultTag = new std::string(getprogname());
}
Logger()(DEFAULT, severity, gDefaultTag->c_str(), file, line, message);
} else {
Logger()(DEFAULT, severity, tag, file, line, message);
}
}
}
2. logging_splitters模块
2.1 SplitByLines-对log信息按行分解
template <typename F, typename... Args>
static void SplitByLines(const char* msg, const F& log_function, Args&&... args) {
const char* newline = strchr(msg, '\n');
while (newline != nullptr) {
// newline - msg代表的是长度,args有优先级和tag
log_function(msg, newline - msg, args...);
msg = newline + 1;
newline = strchr(msg, '\n');
}
log_function(msg, -1, args...);
}
3. string模块
3.1 Split-找到delimiters然后把它装到容器中
#define CHECK_NE(a, b) \
if ((a) == (b)) abort();
std::vector<std::string> Split(const std::string& s,
const std::string& delimiters) {
CHECK_NE(delimiters.size(), 0U);
std::vector<std::string> result;
size_t base = 0;
size_t found;
while (true) {
// ro.boot. 所以分出来就是 ro boot 空
// ro.virtual_ab.enabled 所以分出来就是ro virtual_ab enabled
// 找不到就返回s.npos
found = s.find_first_of(delimiters, base);
result.push_back(s.substr(base, found - base));
if (found == s.npos) break;
base = found + 1;
}
return result;
}
4. ScopeGuard类-确保无论当前作用域如何退出,都执行指定的函数
template <typename F>
class ScopeGuard {
public:
ScopeGuard(F&& f) : f_(std::forward<F>(f)), active_(true) {}
ScopeGuard(ScopeGuard&& that) noexcept : f_(std::move(that.f_)), active_(that.active_) {
that.active_ = false;
}
template <typename Functor>
ScopeGuard(ScopeGuard<Functor>&& that) : f_(std::move(that.f_)), active_(that.active_) {
that.active_ = false;
}
// 关键的一句话在这里,析构的时候,会执行这个函数
~ScopeGuard() {
if (active_) f_();
}
ScopeGuard() = delete;
ScopeGuard(const ScopeGuard&) = delete;
void operator=(const ScopeGuard&) = delete;
void operator=(ScopeGuard&& that) = delete;
// 当然,也可以在退出之前,执行disable,那样就不会执行那个函数
// 相当于函数执行错误的时候,goto out
void Disable() { active_ = false; }
bool active() const { return active_; }
private:
template <typename Functor>
friend class ScopeGuard;
F f_;
bool active_;
};
template <typename F>
ScopeGuard<F> make_scope_guard(F&& f) {
return ScopeGuard<F>(std::forward<F>(f));
}
5. unique_fd模块
作用:方便管理fd
1. 析构的时候,会去close这个fd
2. 赋值的时候,也会去close掉之前那个fd
3. release的时候,需要自己close掉这个fd
5.1 unique_fd类
struct DefaultCloser {
#if defined(__BIONIC__)
static void Tag(int fd, void* old_addr, void* new_addr) {
// 如果android_fdsan_exchange_owner_tag函数存在的话
if (android_fdsan_exchange_owner_tag) {
// fdsan相关
uint64_t old_tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD,
reinterpret_cast<uint64_t>(old_addr));
uint64_t new_tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD,
reinterpret_cast<uint64_t>(new_addr));
android_fdsan_exchange_owner_tag(fd, old_tag, new_tag);
}
}
static void Close(int fd, void* addr) {
if (android_fdsan_close_with_tag) {
uint64_t tag = android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD,
reinterpret_cast<uint64_t>(addr));
android_fdsan_close_with_tag(fd, tag);
} else {
close(fd);
}
}
#else
static void Close(int fd) {
// Even if close(2) fails with EINTR, the fd will have been closed.
// Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone
// else's fd.
// http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
::close(fd);
}
#endif
};
template <typename Closer>
class unique_fd_impl final {
public:
unique_fd_impl() {}
explicit unique_fd_impl(int fd) { reset(fd); }
// 析构的时候,会去close掉这个fd
~unique_fd_impl() { reset(); }
unique_fd_impl(const unique_fd_impl&) = delete;
void operator=(const unique_fd_impl&) = delete;
unique_fd_impl(unique_fd_impl&& other) noexcept { reset(other.release()); }
unique_fd_impl& operator=(unique_fd_impl&& s) noexcept {
int fd = s.fd_;
s.fd_ = -1;
reset(fd, &s);
return *this;
}
void reset(int new_value = -1) { reset(new_value, nullptr); }
int get() const { return fd_; }
#if !defined(ANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION)
// unique_fd's operator int is dangerous, but we have way too much code that
// depends on it, so make this opt-in at first.
operator int() const { return get(); } // NOLINT
#endif
bool operator>=(int rhs) const { return get() >= rhs; }
bool operator<(int rhs) const { return get() < rhs; }
bool operator==(int rhs) const { return get() == rhs; }
bool operator!=(int rhs) const { return get() != rhs; }
bool operator==(const unique_fd_impl& rhs) const { return get() == rhs.get(); }
bool operator!=(const unique_fd_impl& rhs) const { return get() != rhs.get(); }
// Catch bogus error checks (i.e.: "!fd" instead of "fd != -1").
bool operator!() const = delete;
bool ok() const { return get() >= 0; }
int release() __attribute__((warn_unused_result)) {
tag(fd_, this, nullptr);
int ret = fd_;
fd_ = -1;
return ret;
}
private:
void reset(int new_value, void* previous_tag) {
int previous_errno = errno;
if (fd_ != -1) {
// 在这里先close掉
close(fd_, this);
}
fd_ = new_value;
if (new_value != -1) {
tag(new_value, previous_tag, this);
}
errno = previous_errno;
}
int fd_ = -1;
// Template magic to use Closer::Tag if available, and do nothing if not.
// If Closer::Tag exists, this implementation is preferred, because int is a better match.
// If not, this implementation is SFINAEd away, and the no-op below is the only one that exists.
template <typename T = Closer>
static auto tag(int fd, void* old_tag, void* new_tag)
-> decltype(T::Tag(fd, old_tag, new_tag), void()) {
T::Tag(fd, old_tag, new_tag);
}
template <typename T = Closer>
static void tag(long, void*, void*) {
// No-op.
}
// Same as above, to select between Closer::Close(int) and Closer::Close(int, void*).
template <typename T = Closer>
static auto close(int fd, void* tag_value) -> decltype(T::Close(fd, tag_value), void()) {
T::Close(fd, tag_value);
}
template <typename T = Closer>
static auto close(int fd, void*) -> decltype(T::Close(fd), void()) {
T::Close(fd);
}
};
// 用的是上面的DefaultCloser类
using unique_fd = unique_fd_impl<DefaultCloser>;
5.2 Socketpair-创建socket
template <typename Closer>
inline bool Socketpair(int domain, int type, int protocol, unique_fd_impl<Closer>* left,
unique_fd_impl<Closer>* right) {
int sockfd[2];
if (socketpair(domain, type, protocol, sockfd) != 0) {
return false;
}
left->reset(sockfd[0]);
right->reset(sockfd[1]);
return true;
}