Android 4.3 Monkey自动化测试工具被killed的原因分析

本文记录了一次使用Monkey工具进行自动化测试时遇到的问题及解决过程。问题表现为Monkey启动后导致Activity Manager异常终止,通过分析日志和源代码定位到空指针异常,并给出了修复方案。

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

原创链接:http://blog.youkuaiyun.com/zhao_3546/article/details/19193277,转载,请注明。


测试组使用Monkey在Android上想对APK进行自动化测试,但在启动Monkey测试工具时,一直无法正常启动,

shell@android:/ $ monkey -p com.android.calculator2 -v 100
monkey -p com.android.calculator2 -v 100
:Monkey: seed=1393356259515 count=100
:AllowPackage: com.android.calculator2
:IncludeCategory: android.intent.category.LAUNCHER
:IncludeCategory: android.intent.category.MONKEY
Killed

一执行就会被killed,无意间测试说起这个问题,说是因为这个系统我们定制过,应该是定制的原因导致的问题。

我较真了,怎么可能是我们定制的原因呢?一般的APK在这个系统上都是可以正常运行的,并且也没有出过问题,所以我对定制这个说法完全不认同。

让相关人员重新执行后,让他同时提供相应的logcat的日志。

 

日志如下: 

02-13 10:02:24.604 D/AndroidRuntime(14430): Calling main entry com.android.commands.monkey.Monkey
02-13 10:02:24.614 D/dalvikvm(14430): Note: class Landroid/app/ActivityManagerNative; has 168 unimplemented (abstract) methods
02-13 10:02:24.614 D/AndroidRuntime(14430): Shutting down VM
02-13 10:02:24.614 W/dalvikvm(14430): threadid=1: thread exiting with uncaught exception (group=0x416a5700)
02-13 10:02:24.614 E/ActivityManager(  605): Activity Manager Crash
02-13 10:02:24.614 E/ActivityManager(  605): java.lang.NullPointerException
02-13 10:02:24.614 E/ActivityManager(  605):     at com.android.server.am.ActivityManagerService.registerReceiver(ActivityManagerService.java:11867)
02-13 10:02:24.614 E/ActivityManager(  605):     at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:308)
02-13 10:02:24.614 E/ActivityManager(  605):     at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:1809)
02-13 10:02:24.614 E/ActivityManager(  605):     at android.os.Binder.execTransact(Binder.java:388)
02-13 10:02:24.614 E/ActivityManager(  605):     at dalvik.system.NativeStart.run(Native Method)
02-13 10:02:24.624 E/JavaBinder(14430): Unknown binder error code. 0xfffffff7
02-13 10:02:24.624 I/Process (14430): Sending signal. PID: 14430 SIG: 9
02-13 10:02:24.624 E/AndroidRuntime(14430): *** FATAL EXCEPTION IN SYSTEM PROCESS: main
02-13 10:02:24.624 E/AndroidRuntime(14430): java.lang.NullPointerException
02-13 10:02:24.624 E/AndroidRuntime(14430):     at android.os.Parcel.readException(Parcel.java:1437)
02-13 10:02:24.624 E/AndroidRuntime(14430):     at android.os.Parcel.readException(Parcel.java:1385)
02-13 10:02:24.624 E/AndroidRuntime(14430):     at android.app.ActivityManagerProxy.registerReceiver(ActivityManagerNative.java:2237)
02-13 10:02:24.624 E/AndroidRuntime(14430):     at com.android.commands.monkey.MonkeyNetworkMonitor.register(MonkeyNetworkMonitor.java:88)
02-13 10:02:24.624 E/AndroidRuntime(14430):     at com.android.commands.monkey.Monkey.getSystemInterfaces(Monkey.java:979)
02-13 10:02:24.624 E/AndroidRuntime(14430):     at com.android.commands.monkey.Monkey.run(Monkey.java:586)
02-13 10:02:24.624 E/AndroidRuntime(14430):     at com.android.commands.monkey.Monkey.main(Monkey.java:509)
02-13 10:02:24.624 E/AndroidRuntime(14430):     at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
02-13 10:02:24.624 E/AndroidRuntime(14430):     at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:235)
02-13 10:02:24.624 E/AndroidRuntime(14430):     at dalvik.system.NativeStart.main(Native Method)
02-13 10:02:24.624 E/AndroidRuntime(14430): Error reporting crash
02-13 10:02:24.624 E/AndroidRuntime(14430): android.os.RemoteException: Unknown binder error code. 0xfffffff7
02-13 10:02:24.624 E/AndroidRuntime(14430):     at android.os.BinderProxy.transact(Native Method)
02-13 10:02:24.624 E/AndroidRuntime(14430):     at android.app.ActivityManagerProxy.handleApplicationCrash(ActivityManagerNative.java:3525)
02-13 10:02:24.624 E/AndroidRuntime(14430):     at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:76)
02-13 10:02:24.624 E/AndroidRuntime(14430):     at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
02-13 10:02:24.624 E/AndroidRuntime(14430):     at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
02-13 10:02:24.624 E/AndroidRuntime(14430):     at dalvik.system.NativeStart.main(Native Method)

我了个去,这个程序一运行,居然把 Activity Manager 给搞挂了,从现象来看,应该是Framework层的bug,即使应用有问题,ActivityManger也不应该挂。

分析了一下代码,看看 com.android.server.am.ActivityManagerService.registerReceiver 的实现:

    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
        ...
        synchronized(this) {
            ProcessRecord callerApp = null;
            if (caller != null) {
                callerApp = getRecordForAppLocked(caller);
                if (callerApp == null) {
                    throw new SecurityException(
                            "Unable to find app for caller " + caller
                            + " (pid=" + Binder.getCallingPid()
                            + ") when registering receiver " + receiver);
                }
                ...
                callingUid = callerApp.info.uid;
                callingPid = callerApp.pid;
            } else {
                callerPackage = null;
                callingUid = Binder.getCallingUid();
                callingPid = Binder.getCallingPid();
            }

            ...

            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,   // 日志显示,挂在这里
                    permission, callingUid, userId, callerApp.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
            ...
    }

从代码上看,出现空指针异常的这个点,确实是有缺陷的,如果 caller 为null,则 callerApp 就是 null。

Google发布的代码,也会有bug,是人写的代码,就有缺陷啊。

修改成为如下:

            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
                    permission, callingUid, userId, 
                    (callerApp != null && (callerApp.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0));

重新编译出相应的 services.jar,替换 /system/framework/ 下的同名文件,再让测试重新验证,问题解决。

 其实在测试给我说了Monkey的作用后,我就在想Monkey的实现原理,如下纯粹个人猜想,未进一步找资料验证。

集成Android开发SDK的Eclipse中,提供了DDMS的功能,通过点击如下“红框”圈住的按钮,就可以得到右边的视图,即当前手机屏幕上显示的内容,以及View对象树,

我个人分析Monkey也是使用类似的原理,通过DDMS获取当前屏幕上显示的View对象视图,有了这个,其实也就有了哪个区域可以被点击,再通过脚本来控制相应的点击区域即可。

我经常想起我之前PL在我给他解释某问题的可能原因时他经常问我的一句话,为什么是这个原因 你有证据吗?你有重现吗?

跟着他,我也学会时常问自己或别人为什么,为什么这样,为什么那样,通过多问为什么,也让我会去不断思考一些更深层次的东西,好的习惯给我带来的帮助真的难以估量。




<think>嗯,用户的问题是关于模型训练时进程被killed的原因和解决方案。我需要先分析可能的原因,然后根据已有的引用资料给出解决方案。首先,用户提到参考了四个引用,其中涉及内存不足、OOM killer机制、分布式训练以及安装问题。 首先,进程被killed最常见的原因应该是内存不足。根据引用[3],当内存耗尽时,Linux的OOM killer会终止占用内存最多的进程。这时候需要检查内存使用情况,优化模型的内存占用。可能的方法包括减小批次大小、使用更节省内存的数据类型,或者简化模型结构。 接下来,分布式训练可能也是一个因素。引用[1]提到PyG的分布式训练方案,如果用户在使用分布式训练时配置不当,比如节点间通信问题或者资源分配不均,也可能导致进程被终止。需要检查分布式设置是否正确,是否每个节点都有足够资源。 然后,安装问题也可能导致问题。引用[4]提到在安装特定版本的torch时被killed,可能因为安装过程中内存不足。这时候建议用户更换安装时间或镜像,或者使用conda安装,因为conda可能更高效地管理依赖。 另外,用户可能没有正确监控系统资源,导致无法及时发现内存或CPU过载。建议使用nvidia-smi、htop等工具实时监控,并设置检查点防止数据丢失。 还需要考虑其他可能性,比如磁盘空间不足,或者进程被手动终止。但根据引用资料,主要问题集中在内存和资源管理上。所以解决方案应围绕优化内存使用、正确配置分布式训练、合理安装环境和监控资源展开。 总结下来,分步骤解答:首先检查内存,调整模型和数据处理;其次处理分布式训练配置;然后确保环境安装正确;最后加强资源监控和日志分析。这样用户就能系统地解决问题了。</think>### 模型训练时进程被killed的常见原因及解决方案 #### 一、内存不足(最常见原因) 1. **现象与原因** - 训练过程中内存占用超出系统限制,触发Linux的OMM(Out-of-Memory) Killer机制强制终止进程[^3]。 - 常见于大模型、大批次数据训练场景,或内存泄漏问题。 2. **解决方案** - **减小批次大小(Batch Size)**:通过调整`batch_size`降低单次计算的内存需求。 - **使用混合精度训练**:通过`torch.cuda.amp`将部分计算转换为`float16`,减少显存占用[^1]。 - **优化数据加载**:使用`DataLoader`的`pin_memory=False`,或提前缓存数据。 - **释放无用内存**:定期清理中间变量,使用`del`和`torch.cuda.empty_cache()`。 - **简化模型结构**:减少网络层数或参数规模,或使用梯度检查点(Gradient Checkpointing)。 #### 二、显存不足(GPU场景) 1. **现象与原因** - GPU显存被完全占用,导致CUDA报错或进程被终止。 2. **解决方案** - **监控显存使用**:通过`nvidia-smi`或`torch.cuda.memory_summary()`实时查看显存分配。 - **启用内存优化策略**: ```python # PyTorch示例:启用自动混合精度和内存分析 from torch.cuda.amp import autocast with autocast(): outputs = model(inputs) ``` - **分布式训练优化**:使用`torch_geometric.distributed`等工具实现显存分摊。 #### 三、系统资源限制 1. **现象与原因** - 进程因CPU过载、磁盘I/O阻塞或进程数超限被终止。 2. **解决方案** - **调整并行线程数**:限制`DataLoader`的`num_workers`(建议设为CPU核心数的50%-70%)。 - **使用轻量级数据增强**:避免复杂的实时数据预处理。 - **检查cgroup限制**:若在容器中运行,需确认内存、CPU配额是否合理[^2]。 #### 四、软件环境问题 1. **现象与原因** - 依赖库版本冲突或安装异常导致进程崩溃[^4]。 2. **解决方案** - **使用稳定环境**:通过`conda`创建独立虚拟环境,避免全局依赖冲突。 - **指定版本安装**:按框架官方文档安装对应CUDA版本的PyTorch: ```bash # 参考PyTorch官方命令,例如CUDA 11.7 pip install torch==1.13.0+cu117 --extra-index-url https://download.pytorch.org/whl/cu117 ``` - **更换镜像源**:使用阿里云、清华源等国内镜像加速下载。 #### 五、调试与日志分析 1. **定位问题根源** - 通过`dmesg | grep -i killed`查看系统日志,确认是否为OOM Killer触发。 - 使用`py-spy`或`cProfile`分析Python进程的内存和CPU使用模式。 2. **预防性措施** - **设置训练检查点**:定期保存模型状态,防止数据丢失。 - **资源预留策略**:保留10%-20%的内存/显存余量应对突发需求。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值