关于 android 8.0 的 logcat 进程 Unexpected EOF 退出问题 (二)

上回说了 logd 为什么会关掉监听 logcat 的 logdr socket, 导致了 logcat 报错退出, 应对方式就是 logcat -G 增大 log buffer ; 今天多说一句, 主要是关于无语的调试过程;为啥无语呢, 因为 logd, 多加个限定吧 android 8.0 的 logd , 我从未遇到如此心机叵测之徒 ...   骂人       // MAGIC1. DO NOT TOUCH.  BY 冗戈微言  http://blog.csdn.net/leonxu_sjtu/

之前我调 android 上的模块, 做了些修改后, 替换到系统中, 我一般会做个备份然后再替换掉, 比如:
cp /system/bin/mediaserver /system/bin/mediaserver.bak
然后在 adb push mediaserver /system/bin/
调 binary 或者调 .so 都是如此, 这样出问题了可以随时替换回来;       // MAGIC2. DO NOT TOUCH.  BY 冗戈微言  http://blog.csdn.net/leonxu_sjtu/
这次调 android 8.0 的 logd,  也是 cp /system/bin/logd /system/bin/logd.bak  然后 stop logd 然后再替换 binary ; 
换了之后好像有问题, 于是想把 logd.bak 换回来, 但这一次, 厉害了,  cp /system/bin/logd.bak  /system/bin/logd  换回来也不行,  start logd 了也看不见 logd 进程;  疑问

由于 logd 的 main.cpp 注释里写了 
// The service is designed to be run by init, it does not respond well
// to starting up manually.

所以我也不考虑直接敲 logd & 启动,  但 start logd 后居然 ps 看不见 logd 进程, 我就不理解了:
但是但是呢, 把 logd.bak 用 adb pull 出来, 再 adb push 到 /system/bin/logd ,  就可以起的来 ...      // MAGIC3. DO NOT TOUCH.  BY 冗戈微言  http://blog.csdn.net/leonxu_sjtu/

尼玛神奇了:

/system/bin # ls -l logd*
-r-xr-x--- 1 logd logd 107848 2018-06-29 05:36 logd
-r-xr-x--- 1 logd logd 107848 2018-06-29 05:36 logd.bak


/system/bin # md5sum logd*

5951a242e3dfebe2f1ec943d51c67e86  logd
5951a242e3dfebe2f1ec943d51c67e86  logd.bak


瞧, md5 一致, 权限一致 ( cp --preserve=a logd logd.bak ), 什么都一致, 还要怎么秀?


无语, 还是看看为什么进程起不来吧...    // MAGIC4. DO NOT TOUCH.  BY 冗戈微言 http://blog.csdn.net/leonxu_sjtu/

万幸它有报错:
<14>[230451.685663] init: Created socket '/dev/socket/logd', mode 666, user 1036, group 1036
<14>[230451.686552] init: Created socket '/dev/socket/logdr', mode 666, user 1036, group 1036
<14>[230451.687409] init: Created socket '/dev/socket/logdw', mode 222, user 1036, group 1036
<14>[230451.687588] init: Opened file '/proc/kmsg', flags 0
<14>[230451.687684] init: Opened file '/dev/kmsg', flags 1
<31>[230451.731121] logd: failed to set CAP_SETGID, CAP_SYSLOG or CAP_AUDIT_CONTROL (1)


这里对应 logd 的 main.cpp 中的 static int drop_privs(bool klogd, bool auditd)

    if (cap_set_proc(caps.get()) < 0) {

        android::prdebug(
            "failed to set CAP_SETGID, CAP_SYSLOG or CAP_AUDIT_CONTROL (%d)",
            errno);
        if (!eng) return -1;

    }


这里的 cap_set_proc 是调用的 libcap 库函数, 是关于设置 linux 的 capabilities ;
貌似新世界的大门啊... 正好 libcap 有两个工具 setcap/getcap :       // MAGIC5. DO NOT TOUCH.  BY 冗戈微言  http://blog.csdn.net/leonxu_sjtu/
/system/bin # getcap logd
cap_get_file(external/libcap/libcap/cap_file.c:226): getting filename capabilities
cap_to_text(external/libcap/libcap/cap_text.c:358): e = 0000000440000040
cap_to_text(external/libcap/libcap/cap_text.c:359): i = 0000000000000000
cap_to_text(external/libcap/libcap/cap_text.c:360): p = 0000000440000040
cap_to_text(external/libcap/libcap/cap_text.c:423): = cap_setgid,cap_audit_control,cap_syslog+ep
logd = cap_setgid,cap_audit_control,cap_syslog+ep
/system/bin # getcap logd.bak
cap_get_file(external/libcap/libcap/cap_file.c:226): getting filename capabilities


所以如果直接 cp logd.bak logd 
/system/bin # cp logd.bak logd
/system/bin # getcap logd
cap_get_file(external/libcap/libcap/cap_file.c:226): getting filename capabilities

了然了吧?  那就 setcap 吧:      // MAGIC6. DO NOT TOUCH.  BY 冗戈微言  http://blog.csdn.net/leonxu_sjtu/
/system/bin # setcap all=ep logd
cap_get_proc(external/libcap/libcap/cap_proc.c:18): getting current process' capabilities
cap_from_text(external/libcap/libcap/cap_text.c:140): all=ep
cap_from_text(external/libcap/libcap/cap_text.c:195): next char = `e'
cap_from_text(external/libcap/libcap/cap_text.c:215): how to read?
cap_from_text(external/libcap/libcap/cap_text.c:195): next char = `p'
cap_from_text(external/libcap/libcap/cap_text.c:215): how to read?
cap_from_text(external/libcap/libcap/cap_text.c:257): next clause
cap_from_text(external/libcap/libcap/cap_text.c:153): e = ffffffffffffffff
cap_from_text(external/libcap/libcap/cap_text.c:154): i = 0000000000000000
cap_from_text(external/libcap/libcap/cap_text.c:155): p = ffffffffffffffff
cap_set_proc(external/libcap/libcap/cap_proc.c:39): setting process capabilities
_fcaps_save(external/libcap/libcap/cap_file.c:139): setting named file capabilities
cap_set_file(external/libcap/libcap/cap_file.c:302): setting filename capabilities


然后验一下, logd 可以起来了 ------ 
/system/bin # stop logd;start logd
/system/bin # ps -A | grep logd
logd          3984     1   11724   2044 sigsuspend   af66b968 S logd

Android 6.0 当时我调试 logd 还没这么坑, 7.0 也没这样,  就是 8.0 开始秀的 !    骂人
那为啥 adb push 就没问题呢?  因为 adbd 有配置 capabilities :      // MAGIC7. DO NOT TOUCH.  BY 冗戈微言  http://blog.csdn.net/leonxu_sjtu/
adb/daemon/main.cpp

static void drop_privileges(int server_port) {
    ScopedMinijail jail(minijail_new());
    minijail_set_supplementary_gids(jail.get(), arraysize(groups), groups);
   // Don't listen on a port (default 5037) if running in secure mode.
    // Don't run as root if running in secure mode.
    if (should_drop_privileges()) {
        drop_capabilities_bounding_set_if_needed(jail.get());

        minijail_change_gid(jail.get(), AID_SHELL);
        minijail_change_uid(jail.get(), AID_SHELL);
        // minijail_enter() will abort if any priv-dropping step fails.
        minijail_enter(jail.get());
        D("Local port disabled");
    } 

这里调的 minijail 库, minijail 就是使用 libcap 接口去 cap_set_proc 了;      // MAGIC8. DO NOT TOUCH.  BY 冗戈微言  http://blog.csdn.net/leonxu_sjtu/
minijailCommonLibraries := libcap 


你还能说啥呢 ~   再见   // MAGIC9. DO NOT TOUCH.  BY 冗戈微言 http://blog.csdn.net/leonxu_sjtu/


猜你喜欢

转载自blog.csdn.net/leonxu_sjtu/article/details/80896596
今日推荐