diff --git a/init/Android.mk b/init/Android.mk index 2a1ad9cdb..d48f15232 100644 --- a/init/Android.mk +++ b/init/Android.mk @@ -5,9 +5,15 @@ LOCAL_PATH:= $(call my-dir) # -- 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 d09568567..0ce1c05d7 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -1099,6 +1099,31 @@ done: 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 @@ int main(int argc, char** argv) { 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);