Merge "init: reboot to bootloader on crash for development builds"
am: ac8a3bd283
Change-Id: Ieb55ec65e908410eb5dadc1cd0f25a9bbf37fd4a
diff --git a/init/Android.mk b/init/Android.mk
index 2a1ad9c..d48f152 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -5,9 +5,15 @@
# --
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-init_options += -DALLOW_LOCAL_PROP_OVERRIDE=1 -DALLOW_PERMISSIVE_SELINUX=1
+init_options += \
+ -DALLOW_LOCAL_PROP_OVERRIDE=1 \
+ -DALLOW_PERMISSIVE_SELINUX=1 \
+ -DREBOOT_BOOTLOADER_ON_PANIC=1
else
-init_options += -DALLOW_LOCAL_PROP_OVERRIDE=0 -DALLOW_PERMISSIVE_SELINUX=0
+init_options += \
+ -DALLOW_LOCAL_PROP_OVERRIDE=0 \
+ -DALLOW_PERMISSIVE_SELINUX=0 \
+ -DREBOOT_BOOTLOADER_ON_PANIC=0
endif
init_options += -DLOG_UEVENTS=0
diff --git a/init/init.cpp b/init/init.cpp
index d095685..0ce1c05 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -1099,6 +1099,31 @@
return success;
}
+static void install_reboot_signal_handlers() {
+ // Instead of panic'ing the kernel as is the default behavior when init crashes,
+ // we prefer to reboot to bootloader on development builds, as this will prevent
+ // boot looping bad configurations and allow both developers and test farms to easily
+ // recover.
+ struct sigaction action;
+ memset(&action, 0, sizeof(action));
+ sigfillset(&action.sa_mask);
+ action.sa_handler = [](int) {
+ // panic() reboots to bootloader
+ panic();
+ };
+ action.sa_flags = SA_RESTART;
+ sigaction(SIGABRT, &action, nullptr);
+ sigaction(SIGBUS, &action, nullptr);
+ sigaction(SIGFPE, &action, nullptr);
+ sigaction(SIGILL, &action, nullptr);
+ sigaction(SIGSEGV, &action, nullptr);
+#if defined(SIGSTKFLT)
+ sigaction(SIGSTKFLT, &action, nullptr);
+#endif
+ sigaction(SIGSYS, &action, nullptr);
+ sigaction(SIGTRAP, &action, nullptr);
+}
+
int main(int argc, char** argv) {
if (!strcmp(basename(argv[0]), "ueventd")) {
return ueventd_main(argc, argv);
@@ -1108,6 +1133,10 @@
return watchdogd_main(argc, argv);
}
+ if (REBOOT_BOOTLOADER_ON_PANIC) {
+ install_reboot_signal_handlers();
+ }
+
add_environment("PATH", _PATH_DEFPATH);
bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);