monkey测试有如下FATAL log 分析

本文解析了一个出现在Monkey测试中的FATAL log,详细解释了导致应用崩溃的原因——即文件描述符超过FD_SETSIZE限制,并提供了相应的代码跟踪及解决思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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



<think>我们正在处理关于Android Monkey测试报告生成与查看的问题。根据引用内容,Monkey测试是Android自动化测试的一种方式,通过模拟用户随机事件来对应用进行压力测试。用户询问如何生成和查看测试报告。 关键点: 1. 执行Monkey测试时,可以通过命令行参数指定日志输出,从而生成测试报告。 2. 测试报告通常包含事件序列、异常信息等。 步骤: 生成报告:在执行Monkey命令时,使用重定向或日志参数将输出保存到文件。 查看报告:使用文本编辑器或命令行工具查看生成的日志文件。 具体操作: 1. 执行Monkey测试并生成日志文件: 例如:`adb shell monkey -p your.package.name -v 500 > monkey_log.txt` 这里将500次事件模拟的日志输出重定向到当前目录下的monkey_log.txt文件中。 2. 查看日志文件: 可以使用任何文本编辑器打开,或者使用命令行(如cat、more等)查看。 3. 日志文件分析: 在日志中,如果测试过程中出现错误(如应用崩溃、无响应等),会有明显的异常堆栈信息。常见的异常类型包括: - CRASH: 应用崩溃 - ANR: 应用无响应 另外,Monkey还提供了更详细的日志选项: 使用 `-v` 可以指定日志详细程度,可以叠加使用,如 `-v -v -v` 表示最详细的三级日志。 示例命令: `adb shell monkey -p com.example.app --throttle 100 --ignore-crashes --ignore-timeouts --ignore-security-exceptions -v -v 1000 > monkey_log.txt` 参数说明: -p: 指定测试的包名 --throttle: 事件之间的延迟(毫秒) --ignore-*: 忽略某些错误,使测试可以继续 -v: 日志详细程度 注意:测试报告(日志文件)会记录所有事件和异常,需要人工分析。 根据引用[3]中提到的Monkey程序位置,我们实际上是通过adb shell来调用monkey脚本,然后执行monkey.jar。因此日志的生成依赖于我们在命令行中的重定向操作。 另外,如果测试过程中出现ANR(Application Not Responding)错误,系统还会在设备的/data/anr/目录下生成traces.txt文件,可以通过`adb pull /data/anr/traces.txt`来获取,但这不属于Monkey测试报告本身,而是系统在发生ANR时生成的。 因此,总结如下: 生成报告:在运行Monkey命令时,使用重定向(>或>>)将控制台输出保存到文件中。 查看报告:直接打开生成的日志文件,搜索异常关键字(如CRASH, ANR, Exception等)来分析测试结果。 相关问题: 1. 如何分析Monkey测试报告中的异常? 2. Monkey测试中如何指定事件类型比例? 3. Monkey测试遇到权限问题(如需要授权)怎么办?</think>### Android Monkey测试报告生成与查看指南 #### 一、生成测试报告 在Monkey测试命令中添加日志输出参数即可生成测试报告: ```bash adb shell monkey -p <包名> --throttle 100 -v -v 10000 > monkey_report.txt ``` 关键参数说明: - `-v`:日志详细级别(可叠加使用,最多3个`-v`) - `> monkey_report.txt`:将控制台输出重定向到文本文件 - `--throttle`:事件间隔时间(毫秒) - 末尾数字:事件执行次数 #### 二、查看测试报告 1. **基本查看方法**: ```bash # Windows notepad monkey_report.txt # Mac/Linux open monkey_report.txt # 或使用vim/less等工具 ``` 2. **关键信息定位**: - 崩溃信息:搜索`CRASH`关键词 - ANR(应用无响应):搜索`ANR`关键词 - 异常堆栈:搜索`Exception`或`FATAL` - 测试摘要:查看文件末尾的`Events injected`统计 3. **日志示例解析**: ```log // 事件序列示例 :Sending Touch (ACTION_DOWN) 0:(438.0,1462.0) :Sending Key (ACTION_DOWN) 23 // KEYCODE_DPAD_CENTER // 崩溃记录示例 CRASH: com.example.app (pid 12345) Short Msg: NullPointerException Long Msg: java.lang.NullPointerException... ``` #### 三、进阶用法 1. **按类型分离日志**: ```bash adb shell monkey -p <包名> --ignore-crashes --ignore-timeouts -v 5000 2> errors.txt 1> events.txt ``` 2. **设备日志关联分析**: ```bash adb logcat -v time > logcat.txt & # 后台记录系统日志 adb shell monkey ... # 执行测试 killall adb # 结束日志记录 ``` 3. **ANR报告获取**: ```bash adb pull /data/anr/traces.txt # 获取ANR详细堆栈 ``` #### 四、注意事项 1. 测试前确保`adb`环境配置正确(参考引用[4]) 2. 大事件量测试时建议添加`--ignore-crashes`参数避免中途退出 3. 完整报告包含: - 测试设备信息 - 事件百分比分布 - 异常堆栈轨迹 - 内存/CPU使用情况(需额外监控) > 通过分析报告中的崩溃堆栈和ANR信息,开发者可精准定位稳定性问题。Monkey测试作为基础压力测试手段,能有效暴露边界情况下的程序缺陷[^2][^3]。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值