Loading bootstat/bootstat.cpp +65 −43 Original line number Diff line number Diff line Loading @@ -291,6 +291,32 @@ bool isBluntRebootReason(const std::string& r) { return true; } bool readPstoreConsole(std::string& console) { if (android::base::ReadFileToString("/sys/fs/pstore/console-ramoops-0", &console)) { return true; } return android::base::ReadFileToString("/sys/fs/pstore/console-ramoops", &console); } bool addKernelPanicSubReason(const std::string& console, std::string& ret) { // Check for kernel panic types to refine information if (console.rfind("SysRq : Trigger a crash") != std::string::npos) { // Can not happen, except on userdebug, during testing/debugging. ret = "kernel_panic,sysrq"; return true; } if (console.rfind("Unable to handle kernel NULL pointer dereference at virtual address") != std::string::npos) { ret = "kernel_panic,NULL"; return true; } if (console.rfind("Kernel BUG at ") != std::string::npos) { ret = "kernel_panic,BUG"; return true; } return false; } // std::transform Helper callback functions: // Converts a string value representing the reason the system booted to a // string complying with Android system standard reason. Loading Loading @@ -371,18 +397,20 @@ std::string BootReasonStrToReason(const std::string& boot_reason) { } } // Check the other reason resources if the reason is still blunt. if (isBluntRebootReason(ret)) { if (ret == "kernel_panic") { // Check to see if last klog has some refinement hints. std::string content; if (!android::base::ReadFileToString("/sys/fs/pstore/console-ramoops-0", &content)) { android::base::ReadFileToString("/sys/fs/pstore/console-ramoops", &content); if (readPstoreConsole(content)) { addKernelPanicSubReason(content, ret); } } else if (isBluntRebootReason(ret)) { // Check the other available reason resources if the reason is still blunt. // Check to see if last klog has some refinement hints. std::string content; if (readPstoreConsole(content)) { // The toybox reboot command used directly (unlikely)? But also // catches init's response to the Android's more controlled reboot command. // catches init's response to Android's more controlled reboot command. if (content.rfind("reboot: Power down") != std::string::npos) { ret = "shutdown"; // Still too blunt, but more accurate. // ToDo: init should record the shutdown reason to kernel messages ala: Loading @@ -407,20 +435,14 @@ std::string BootReasonStrToReason(const std::string& boot_reason) { } } // Check for kernel panics, but allowed to override reboot command. if (content.rfind("sysrq: SysRq : Trigger a crash") != std::string::npos) { // Can not happen, except on userdebug, during testing/debugging. ret = "kernel_panic,sysrq"; } else if (content.rfind( "Unable to handle kernel NULL pointer dereference at virtual address") != std::string::npos) { ret = "kernel_panic,NULL"; } else if (content.rfind("Kernel BUG at ") != std::string::npos) { ret = "kernel_panic,BUG"; } else if ((content.rfind("Power held for ") != std::string::npos) || (content.rfind("charger: [") != std::string::npos)) { // Check for kernel panics, allowed to override reboot command. if (!addKernelPanicSubReason(content, ret) && // check for long-press power down ((content.rfind("Power held for ") != std::string::npos) || (content.rfind("charger: [") != std::string::npos))) { ret = "cold"; } } // The following battery test should migrate to a default system health HAL Loading @@ -433,7 +455,7 @@ std::string BootReasonStrToReason(const std::string& boot_reason) { // Really a hail-mary pass to find it in last klog content ... static const int battery_dead_threshold = 2; // percent static const char battery[] = "healthd: battery l="; pos = content.rfind(battery); // last one size_t pos = content.rfind(battery); // last one if (pos != std::string::npos) { int level = atoi(content.substr(pos + strlen(battery)).c_str()); LOG(INFO) << "Battery level at shutdown " << level << "%"; Loading Loading @@ -497,7 +519,7 @@ std::string BootReasonStrToReason(const std::string& boot_reason) { if ((android::base::StartsWith(content, ret.c_str()) && (content[ret.length()] == ',')) || !isBluntRebootReason(content)) { // Ok, we want it, let's squash it if secondReason is known. pos = content.find(','); size_t pos = content.find(','); if (pos != std::string::npos) { ++pos; std::string secondReason(content.substr(pos)); Loading Loading
bootstat/bootstat.cpp +65 −43 Original line number Diff line number Diff line Loading @@ -291,6 +291,32 @@ bool isBluntRebootReason(const std::string& r) { return true; } bool readPstoreConsole(std::string& console) { if (android::base::ReadFileToString("/sys/fs/pstore/console-ramoops-0", &console)) { return true; } return android::base::ReadFileToString("/sys/fs/pstore/console-ramoops", &console); } bool addKernelPanicSubReason(const std::string& console, std::string& ret) { // Check for kernel panic types to refine information if (console.rfind("SysRq : Trigger a crash") != std::string::npos) { // Can not happen, except on userdebug, during testing/debugging. ret = "kernel_panic,sysrq"; return true; } if (console.rfind("Unable to handle kernel NULL pointer dereference at virtual address") != std::string::npos) { ret = "kernel_panic,NULL"; return true; } if (console.rfind("Kernel BUG at ") != std::string::npos) { ret = "kernel_panic,BUG"; return true; } return false; } // std::transform Helper callback functions: // Converts a string value representing the reason the system booted to a // string complying with Android system standard reason. Loading Loading @@ -371,18 +397,20 @@ std::string BootReasonStrToReason(const std::string& boot_reason) { } } // Check the other reason resources if the reason is still blunt. if (isBluntRebootReason(ret)) { if (ret == "kernel_panic") { // Check to see if last klog has some refinement hints. std::string content; if (!android::base::ReadFileToString("/sys/fs/pstore/console-ramoops-0", &content)) { android::base::ReadFileToString("/sys/fs/pstore/console-ramoops", &content); if (readPstoreConsole(content)) { addKernelPanicSubReason(content, ret); } } else if (isBluntRebootReason(ret)) { // Check the other available reason resources if the reason is still blunt. // Check to see if last klog has some refinement hints. std::string content; if (readPstoreConsole(content)) { // The toybox reboot command used directly (unlikely)? But also // catches init's response to the Android's more controlled reboot command. // catches init's response to Android's more controlled reboot command. if (content.rfind("reboot: Power down") != std::string::npos) { ret = "shutdown"; // Still too blunt, but more accurate. // ToDo: init should record the shutdown reason to kernel messages ala: Loading @@ -407,20 +435,14 @@ std::string BootReasonStrToReason(const std::string& boot_reason) { } } // Check for kernel panics, but allowed to override reboot command. if (content.rfind("sysrq: SysRq : Trigger a crash") != std::string::npos) { // Can not happen, except on userdebug, during testing/debugging. ret = "kernel_panic,sysrq"; } else if (content.rfind( "Unable to handle kernel NULL pointer dereference at virtual address") != std::string::npos) { ret = "kernel_panic,NULL"; } else if (content.rfind("Kernel BUG at ") != std::string::npos) { ret = "kernel_panic,BUG"; } else if ((content.rfind("Power held for ") != std::string::npos) || (content.rfind("charger: [") != std::string::npos)) { // Check for kernel panics, allowed to override reboot command. if (!addKernelPanicSubReason(content, ret) && // check for long-press power down ((content.rfind("Power held for ") != std::string::npos) || (content.rfind("charger: [") != std::string::npos))) { ret = "cold"; } } // The following battery test should migrate to a default system health HAL Loading @@ -433,7 +455,7 @@ std::string BootReasonStrToReason(const std::string& boot_reason) { // Really a hail-mary pass to find it in last klog content ... static const int battery_dead_threshold = 2; // percent static const char battery[] = "healthd: battery l="; pos = content.rfind(battery); // last one size_t pos = content.rfind(battery); // last one if (pos != std::string::npos) { int level = atoi(content.substr(pos + strlen(battery)).c_str()); LOG(INFO) << "Battery level at shutdown " << level << "%"; Loading Loading @@ -497,7 +519,7 @@ std::string BootReasonStrToReason(const std::string& boot_reason) { if ((android::base::StartsWith(content, ret.c_str()) && (content[ret.length()] == ',')) || !isBluntRebootReason(content)) { // Ok, we want it, let's squash it if secondReason is known. pos = content.find(','); size_t pos = content.find(','); if (pos != std::string::npos) { ++pos; std::string secondReason(content.substr(pos)); Loading