您的位置:首页 > 其它

monkey测试有如下FATAL log 分析

2017-02-04 17:57 274 查看
monkey测试有如下FATAL log

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

Build fingerprint: 'LeEco/X7_CN/le_x7:6.0/KGXCNFN5902011171S/1479358948:userdebug/test-keys'

Revision: '0'

ABI: 'arm'

pid: 32138, tid: 32144, name: JDWP  >>> com.letv.bbs <<<

signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------

Abort message: 'FORTIFY: FD_SET: file descriptor >= FD_SETSIZE'

backtrace:

    #00 pc 00041c7c  /system/lib/libc.so (tgkill+12)

    #01 pc 00040e79  /system/lib/libc.so (pthread_kill+32)

    #02 pc 0001c7ef  /system/lib/libc.so (raise+10)

    #03 pc 000199bd  /system/lib/libc.so (__libc_android_abort+34)

    #04 pc 00017570  /system/lib/libc.so (abort+4)

    #05 pc 0001b405  /system/lib/libc.so (__libc_fatal+16)

    #06 pc 0001b41b  /system/lib/libc.so (__fortify_chk_fail+18)

    #07 pc 00046fd1  /system/lib/libc.so (__FD_SET_chk+24)

    #08 pc 003e7bb3  /system/lib/libart.so (_ZN3art4JDWP12JdwpAdbState15ProcessIncomingEv+162)

    #09 pc 0025adab  /system/lib/libart.so (_ZN3art4JDWP9JdwpState3RunEv+298)

    #10 pc 0025bc17  /system/lib/libart.so (_ZN3art4JDWPL15StartJdwpThreadEPv+10)

    #11 pc 0004077b  /system/lib/libc.so (_ZL15__pthread_startPv+30)

    #12 pc 0001a041  /system/lib/libc.so (__start_thread+6)

从log上看有abort原因是:Abort message: 'FORTIFY: FD_SET: file descriptor >= FD_SETSIZE'

但这是什么意思?

从 backtrace:看 #12开启线程, #00线程被kill了。上面abort的原因就是kill的原因。

既然有Abort message提示原因,又不知道这个信息在哪里打印的,只好在Android所有源码搜索(相当耗时,几个小时)。

最终搜到在bionic/libc/bionic/__FD_chk.cpp搜到 如下:

 59 extern "C" void __FD_SET_chk(int fd, fd_set* set, size_t set_size) {

 60   if (__predict_false(fd < 0)) {

 61     __fortify_chk_fail("FD_SET: file descriptor < 0", 0);

 62   }

 63   if (__predict_false(fd >= FD_SETSIZE)) {

 64     __fortify_chk_fail("FD_SET: file descriptor >= FD_SETSIZE", 0);

 65   }

 66   if (__predict_false(set_size < sizeof(fd_set))) {

 67     __fortify_chk_fail("FD_SET: set is too small", 0);

 68   }

 69   FD_SET(fd, set); //这里的FD_SET 是 70 #define FD_SET(fd, set) (__FDS_BITS(set)[__FDELT(fd)] |= __FDMASK(fd))

      因为这时的(__BIONIC_FORTIFY)定义已经取消定义了

 70 } 

bionic/libc/include/sys/select.h 中定义了FD_SETSIZE = 1024 和FD_SET

 39 #define FD_SETSIZE 1024

 60 extern void __FD_CLR_chk(int, fd_set*, size_t);

 61 extern void __FD_SET_chk(int, fd_set*, size_t);

 62 extern int  __FD_ISSET_chk(int, fd_set*, size_t);

 63 

 64 #if defined(__BIONIC_FORTIFY)

 65 #define FD_CLR(fd, set) __FD_CLR_chk(fd, set, __bos(set))

 66 #define FD_SET(fd, set) __FD_SET_chk(fd, set, __bos(set))

 67 #define FD_ISSET(fd, set) __FD_ISSET_chk(fd, set, __bos(set))

 68 #else

 69 #define FD_CLR(fd, set) (__FDS_BITS(set)[__FDELT(fd)] &= ~__FDMASK(fd))

 70 #define FD_SET(fd, set) (__FDS_BITS(set)[__FDELT(fd)] |= __FDMASK(fd))

 71 #define FD_ISSET(fd, set) ((__FDS_BITS(set)[__FDELT(fd)] & __FDMASK(fd)) != 0)

 72 #endif /* defined(__BIONIC_FORTIFY) */

上面代码通过(__BIONIC_FORTIFY)宏动态的切换了FD_SET执行路径。

分析到这里发现整个实现,实际是select的实现,在使用select时,abort并提示了原因。

从backtrace的#07 #12看是libc.so调用libart.so再调用ProcessIncoming函数调用FD_SET了。

对应代码:

art/runtime/jdwp/jdwp_adb.cc

297 bool JdwpAdbState::ProcessIncoming() {                                                                                                                                     

314       fd = control_sock_;

315       if (fd >= 0) {

316         FD_SET(fd, &readfds);

317         if (maxfd < fd) {

318           maxfd = fd;

319         }

320       }

321       fd = clientSock;

322       if (fd >= 0) {

323         FD_SET(fd, &readfds);

324         if (maxfd < fd) {

325           maxfd = fd;

326         }

327       }

328       fd = wake_pipe_[0];

329       if (fd >= 0) {

330         FD_SET(fd, &readfds);

331         if (maxfd < fd) {

332           maxfd = fd;

333         }

334       }

从#12到#00可以看到处是,创建线程没法再创建了,因数量超过了文件句柄最大值FD_SETSIZE。

简单说就是,应用app开启线程之类的太多了,没有复用。需要重新检查app中的线程使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Fatal Crash FD_SETSIZE