Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e80f6668 authored by Josh Gao's avatar Josh Gao Committed by android-build-merger
Browse files

Merge "crash_dump: during early boot, output to kmsg on userdebug." am: 72ca48e5

am: 35b7a274

Change-Id: Idda1bf55e654dd5e1eb72248572f9352671a3745
parents c4289e6b 35b7a274
Loading
Loading
Loading
Loading
+45 −1
Original line number Diff line number Diff line
@@ -22,16 +22,22 @@
#include <signal.h>
#include <string.h>
#include <sys/ptrace.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <unistd.h>

#include <string>

#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <backtrace/Backtrace.h>
#include <log/log.h>

using android::base::unique_fd;

// Whitelist output desired in the logcat output.
bool is_allowed_in_logcat(enum logtype ltype) {
  if ((ltype == HEADER)
@@ -42,6 +48,19 @@ bool is_allowed_in_logcat(enum logtype ltype) {
  return false;
}

static bool should_write_to_kmsg() {
  // Write to kmsg if tombstoned isn't up, and we're able to do so.
  if (!android::base::GetBoolProperty("ro.debuggable", false)) {
    return false;
  }

  if (android::base::GetProperty("init.svc.tombstoned", "") == "running") {
    return false;
  }

  return true;
}

__attribute__((__weak__, visibility("default")))
void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) {
  bool write_to_tombstone = (log->tfd != -1);
@@ -49,6 +68,7 @@ void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) {
                      && log->crashed_tid != -1
                      && log->current_tid != -1
                      && (log->crashed_tid == log->current_tid);
  static bool write_to_kmsg = should_write_to_kmsg();

  char buf[512];
  va_list ap;
@@ -70,6 +90,30 @@ void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) {
    if (log->amfd_data != nullptr) {
      *log->amfd_data += buf;
    }

    if (write_to_kmsg) {
      unique_fd kmsg_fd(open("/dev/kmsg_debug", O_WRONLY | O_APPEND | O_CLOEXEC));
      if (kmsg_fd.get() >= 0) {
        // Our output might contain newlines which would otherwise be handled by the android logger.
        // Split the lines up ourselves before sending to the kernel logger.
        if (buf[len - 1] == '\n') {
          buf[len - 1] = '\0';
        }

        std::vector<std::string> fragments = android::base::Split(buf, "\n");
        for (const std::string& fragment : fragments) {
          static constexpr char prefix[] = "<3>DEBUG: ";
          struct iovec iov[3];
          iov[0].iov_base = const_cast<char*>(prefix);
          iov[0].iov_len = strlen(prefix);
          iov[1].iov_base = const_cast<char*>(fragment.c_str());
          iov[1].iov_len = fragment.length();
          iov[2].iov_base = const_cast<char*>("\n");
          iov[2].iov_len = 1;
          TEMP_FAILURE_RETRY(writev(kmsg_fd.get(), iov, 3));
        }
      }
    }
  }
}

@@ -205,7 +249,7 @@ void dump_memory(log_t* log, Backtrace* backtrace, uintptr_t addr, const char* f
}

void read_with_default(const char* path, char* buf, size_t len, const char* default_value) {
  android::base::unique_fd fd(open(path, O_RDONLY));
  unique_fd fd(open(path, O_RDONLY | O_CLOEXEC));
  if (fd != -1) {
    int rc = TEMP_FAILURE_RETRY(read(fd.get(), buf, len - 1));
    if (rc != -1) {
+4 −2
Original line number Diff line number Diff line
@@ -8,12 +8,14 @@ ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
init_options += \
    -DALLOW_LOCAL_PROP_OVERRIDE=1 \
    -DALLOW_PERMISSIVE_SELINUX=1 \
    -DREBOOT_BOOTLOADER_ON_PANIC=1
    -DREBOOT_BOOTLOADER_ON_PANIC=1 \
    -DWORLD_WRITABLE_KMSG=1
else
init_options += \
    -DALLOW_LOCAL_PROP_OVERRIDE=0 \
    -DALLOW_PERMISSIVE_SELINUX=0 \
    -DREBOOT_BOOTLOADER_ON_PANIC=0
    -DREBOOT_BOOTLOADER_ON_PANIC=0 \
    -DWORLD_WRITABLE_KMSG=0
endif

ifneq (,$(filter eng,$(TARGET_BUILD_VARIANT)))
+9 −0
Original line number Diff line number Diff line
@@ -890,6 +890,9 @@ static void selinux_restore_context() {
    LOG(INFO) << "Running restorecon...";
    restorecon("/dev");
    restorecon("/dev/kmsg");
    if constexpr (WORLD_WRITABLE_KMSG) {
      restorecon("/dev/kmsg_debug");
    }
    restorecon("/dev/socket");
    restorecon("/dev/random");
    restorecon("/dev/urandom");
@@ -1166,7 +1169,13 @@ int main(int argc, char** argv) {
        setgroups(arraysize(groups), groups);
        mount("sysfs", "/sys", "sysfs", 0, NULL);
        mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);

        mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));

        if constexpr (WORLD_WRITABLE_KMSG) {
          mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11));
        }

        mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
        mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));