android 仿真器在容器中运行时崩溃

ulydmbyx  于 2023-04-04  发布在  Android
关注(0)|答案(1)|浏览(159)

我有一个Flutter应用程序,我想从各种设备中获取截图。
我有一个运行GitLab的CI服务器。
我的程序是

  • 启动模拟器(手机,小型平板电脑,大型平板电脑)
  • 构建APK
  • 安装APK
  • 使用Intent Extra启动Activity以显示应用程序的特定部分
  • 截图
  • 冲洗并重复所有我想要的截图
  • 将图像另存为人工贴图

这可以工作,但这在服务器上有点重。我必须在服务器上维护和使用3个模拟器,它使用了大量的CPU和RAM,在CI构建之外什么都没有。
我尝试将上面的列表嵌入到cirrusci/flutter容器中。这可以工作,但现在模拟器崩溃了,没有明显的原因。
我抛弃了logcat,似乎在崩溃之前它与OpenGL有关,但这可能只是一个巧合。
我启用了核心转储,模拟器停止与SIGSEGV。
所有的模拟器、镜像、SDK等都是最新的。我在HP DL 380上的Debian 11(靶心)上运行这个(没有图形卡,但KVM和GPU驱动程序是最新的)。
没有RAM问题,因为服务器有10 GB的RAM和30 GB的交换(NVMe)空闲(或由内核缓存)。磁盘也是如此。
我用以下命令启动模拟器:

emulator "@$dev" -no-boot-anim -no-window -no-audio -no-snapshot -read-only &

$dev是我的模拟器的名称。GitLab runner有$HOME/.android目录和Android SDK目录的卷挂载(两者都安装在主机上,以避免每次构建时重新下载)。
这是可重现的:

docker run --rm -ti -v /opt/gradle-caches:/root/.gradle/caches -v $HOME/.android:/root/.android -v /opt/android:/opt/android-sdk-linux --privileged cirrusci/flutter bash

为什么它会在容器内崩溃而不是在主机上?
导致它崩溃的原因几乎总是(但不是100%):adb exec-out screencap -p。我也尝试了常规的adb screencap -p /sdcard/img.png,但结果是一样的。
编辑以添加另一个示例(在模拟器SIGSEGV'd之后发生设备离线):

adb -H 192.168.0.14 -P 5038 -s emulator-5554 shell am force-stop my.app.pkg
adb: device offline

它可以管理,使1或2截图,但崩溃迅速。我想有5-7每个模拟器截图。
编辑以添加emulator ... -verbose死亡时的输出:

VERBOSE | Data frame has invalid ether type 0
VERBOSE | Unexpected ether type: 0. Dump frame: Data (Data)
    :

编辑:退出代码是139(不知道是操作系统还是qemu。
我切换回主机上运行的模拟器和通过TCP(adb)与它们接口的容器,但现在即使主机模拟器也会崩溃。我不明白。可能需要重新启动...:-/
编辑:尝试https://github.com/google/android-emulator-container-scripts-相同的错误,但更多的日志:

logcat: 03-30 02:28:07.231  2267  2629 I OpaEligibilityChecker: send OpaEligibilityChange broadcast to CommonBroadcastReceiver
2023/03/30 02:28:56 socat[135] W read(5, 0x55847839d8a0, 8192): Connection reset by peer
2023/03/30 02:28:57 socat[715] E connect(5, AF=2 127.0.0.1:5557, 16): Connection refused
2023/03/30 02:28:57 socat[716] E connect(5, AF=2 127.0.0.1:5557, 16): Connection refused
2023/03/30 02:28:57 socat[717] E connect(5, AF=2 127.0.0.1:5557, 16): Connection refused
2023/03/30 02:28:57 socat[718] E connect(5, AF=2 127.0.0.1:5557, 16): Connection refused
eivgtgni

eivgtgni1#

在尝试旧版本并使用二分法向上移动git树后,我能够找到具有破坏性更改的提交。这是由下载期间使用 backbone 的flutter网络映像引起的。将其恢复为圆形进度指示器解决了这个问题:

class MyNetworkImageWrapper extends CachedNetworkImage {
   MyNetworkImageWrapper(String imageUrl, {super.key, bool isThumbnail = false})
       : super(
           imageUrl: getImage(imageUrl, isThumbnail),
-          placeholder: (context, url) => SkeletonAvatar(
-            style: SkeletonAvatarStyle(
-              width: double.infinity,
-              minHeight: MediaQuery.of(context).size.height / 8,
-              maxHeight: MediaQuery.of(context).size.height / 3,
-            ),
-          ),
-        );
+          placeholder: (context, url) => const SizedBox(
+                height: 32.0,
+                width: 32.0,
+                child: CircularProgressIndicator(color: Colors.tealAccent),
+              ));
 }

我不能相信这个 backbone 的东西导致Flutter崩溃,杀死了动车组。我猜,因为Flutter绘制每一个像素,他们使用本机代码这样做,并说本机错误有一个崩溃,SIGSEGV,并导致动车组崩溃。我不明白这是怎么可能的,Flutter本机代码是用户态,所以崩溃应该只是崩溃的应用程序。它感觉就像它崩溃的PID 1或内核的模拟器完全停止突然。
我不认为这是固定的,但至少我有一个变通办法。奇怪的是,在我的设备上,它工作正常(与 backbone )。

相关问题