libbase module

概述

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;
}

补充

问题

参考

posted @ 2021-06-12 21:39  pyjetson  阅读(802)  评论(0编辑  收藏  举报