Platform: RK3288
OS: Android 6.0
Kernel: 3.10.92
背景:
遇到一台机器黑屏,无法连接adb和uart,但是工作指示灯还亮着
Log:
Logcat并未发现异常,Kernel log如下:
<4>[ 1294.653184] ^^^^^^^^^^^^^^^^^Device Mode
<4>[ 1294.653230] soft connect!!!
<4>[ 1294.773441] USB RESET
<6>[ 1294.860784] android_work: sent uevent USB_STATE=CONNECTED
<6>[ 1295.035427] android_usb gadget: high-speed config #1: android
<6>[ 1295.035833] android_work: sent uevent USB_STATE=CONFIGURED
<6>[ 1295.061410] mtp_open
<6>[ 1318.881611] SysRq : Emergency Remount R/O
分析:
最后一条Log表明系统进入了reboot和shutdown流程,但板子还处于工作状态,说明关机不正常。
需要添加Log来确定是否调用此流程了,用户空间的入口函数是android_reboot()@anroid_reboot.c
有两种方式调用:
直接包含此函数对应的库(libcutils.so)调用此接口
通过property_set()功能调用init进程的powerctrl命令间接调用此接口
因此分别在两处添加log打印调用的进程信息。
改动:
diff --git a/libcutils/android_reboot.c b/libcutils/android_reboot.c
index 6ae23c1..198f951 100644
--- a/libcutils/android_reboot.c
+++ b/libcutils/android_reboot.c
[url=home.php?mod=space&uid=1999721]@@[/url] -14,6 +14,7 @@
limitations under the License.
*/
#include <unistd.h>
#include <sys/reboot.h>
#include <sys/syscall.h>
@@ -26,6 +27,8 @@
#include <cutils/android_reboot.h>
#define UNUSED attribute((unused))
/* Check to see if /proc/mounts contains any writeable filesystems
@@ -88,11 +91,33 @@ static void remount_ro(void)
return;
}
+/Kris, 180420, add reboot log. {/
+#define LOG_TAG "android_reboot"
+#include <utils/Log.h>
+int print_current_process_info()
+{
pid_t pid = getpid();
char path[1024] = {0};
if(readlink("/proc/self/exe", path,1024) <=0)
return -1;
char *name = strrchr(path, '/');
if(name)
ALOGI("Pid: %d name:%s path:%s\n", pid, ++name, path);
return 0 ;
+}
+/Kris, 180420, add reboot log. }/
int android_reboot(int cmd, int flags UNUSED, const char *arg)
{
int ret;
/Kris, 180420, add reboot log. {/
ALOGI("android_reboot start...\n");
print_current_process_info();
/Kris, 180420, add reboot log. }/
sync();
remount_ro();
diff --git a/libcutils/properties.c b/libcutils/properties.c
index 4e46e02..cbce234 100644
--- a/libcutils/properties.c
+++ b/libcutils/properties.c
@@ -107,8 +107,19 @@ int32_t property_get_int32(const char *key, int32_t default_value) {
#define REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H
#include <sys/_system_properties.h>
+/Kris, 180420, add reboot log. {/
+extern int print_current_process_info() ;
+/Kris, 180420, add reboot log. }/
+
+
int property_set(const char *key, const char *value)
{
/Kris, 180420, add reboot log. {/
if (!strcmp(key,"sys.powerctl"))
print_current_process_info();
/Kris, 180420, add reboot log. }/
return __system_property_set(key, value);
}
注意点:
系统提供了一个reboot命令执行reboot和shutdown功能,如果调用者通过类型system()方法调用时,打印的只是reboot进程信息(因为会重新fork出一个进程出来),因此这时需要全局搜索调用的地方,不过调用处应该不多。
在调用添加Log时,注意libctuils有可能是被静态包含的,比如init就是这样,这时要编译init(对应是bootimage)而不是libcutils.so.
原作者:KrisFei