monkey测试有如下FATAL log 分析

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中的线程使用。



评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值