1419 1.raster
SIGABRT
00 pc 00000000000525c4 /apex/com.android.runtime/lib64/bionic/libc.so (fdsan_error(char const*, ...)+584) [arm64-v8a::ccd118b72b8037094ae4d9be046a6969]
01 pc 00000000000522c4 /apex/com.android.runtime/lib64/bionic/libc.so (android_fdsan_close_with_tag+728) [arm64-v8a::ccd118b72b8037094ae4d9be046a6969]
02 pc 0000000000052a14 /apex/com.android.runtime/lib64/bionic/libc.so (close+16) [arm64-v8a::ccd118b72b8037094ae4d9be046a6969]
03 pc 0000000000066284 /system/lib64/libbinder.so [arm64-v8a::97d4a62f83074ac1734039e4b250ba46]
04 pc 000000000005c010 /system/lib64/libbinder.so (android::Parcel::freeDataNoInit()+136) [arm64-v8a::97d4a62f83074ac1734039e4b250ba46]
05 pc 000000000009923c /system/lib64/libgui.so [arm64-v8a::5a1e16d2d3bb4cd1932337d2338ba147]
06 pc 00000000000b7964 /system/lib64/libgui.so (android::Surface::queueBuffer(ANativeWindowBuffer*, int)+1140) [arm64-v8a::5a1e16d2d3bb4cd1932337d2338ba147]
07 pc 000000000002333c /system/lib64/libvulkan.so [arm64-v8a::1e2486ac51b5ae0986cf1ca8fd506c41]
08 pc 00000000007f84d8 operator() (../../../flutter/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan_funcs.hpp:9505) [arm64-v8a]
09 pc 0000000000729110 flutter::SurfaceFrame::Submit() (../../../flutter/flow/surface_frame.cc:0) [arm64-v8a]
10 pc 000000000080b464 flutter::Rasterizer::DrawToSurfacesUnsafe(flutter::FrameTimingsRecorder&, std::_fl::vector<std::_fl::unique_ptr<flutter::LayerTreeTask, std::_fl::default_delete<flutter::LayerTreeTask> >, std::_fl::allocator<std::_fl::unique_ptr<flutter::LayerTreeTask, std::_fl::default_delete<flutter::LayerTreeTask> > > >) (../../../flutter/shell/common/rasterizer.cc:803) [arm64-v8a]
11 pc 000000000080ae34 flutter::Rasterizer::DrawToSurfaces(flutter::FrameTimingsRecorder&, std::_fl::vector<std::_fl::unique_ptr<flutter::LayerTreeTask, std::_fl::default_delete<flutter::LayerTreeTask> >, std::_fl::allocator<std::_fl::unique_ptr<flutter::LayerTreeTask, std::_fl::default_delete<flutter::LayerTreeTask> > > >) (../../../flutter/shell/common/rasterizer.cc:595) [arm64-v8a]
12 pc 000000000080c168 operator() (../../../flutter/third_party/libcxx/include/__functional/function.h:319) [arm64-v8a]
13 pc 000000000080bc68 flutter::Rasterizer::Draw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem> > const&) (../../../flutter/third_party/libcxx/include/__functional/function.h:0) [arm64-v8a]
14 pc 000000000081a4b4 operator() (../../../flutter/third_party/libcxx/include/__functional/function.h:319) [arm64-v8a]
15 pc 00000000004b7e50 RunExpiredTasksNow (../../../flutter/fml/message_loop_impl.cc:139 [Inline: FlushTasks]) [arm64-v8a]
16 pc 00000000004bbd68 __invoke (../../../flutter/fml/platform/android/message_loop_android.cc:39 [Inline: operator()]) [arm64-v8a]
17 pc 0000000000019d04 /system/lib64/libutils.so (android::Looper::pollInner(int)+912) [arm64-v8a::4868adbd42643f4c59035cf91f86828c]
18 pc 000000000001990c /system/lib64/libutils.so (android::Looper::pollOnce(int, int, int, void**)+112) [arm64-v8a::4868adbd42643f4c59035cf91f86828c]
19 pc 0000000000012c74 /system/lib64/libandroid.so (ALooper_pollOnce+100) [arm64-v8a::02775852bd95ecafbf5c09629cbea441]
20 pc 00000000004bbe6c Run (../../../flutter/fml/platform/android/message_loop_android.cc:67) [arm64-v8a]
21 pc 00000000004b9d60 operator() (../../../flutter/fml/message_loop_impl.cc:94) [arm64-v8a]
22 pc 00000000004b9b74 __invoke (../../../flutter/fml/thread.cc:73 [Inline: operator()]) [arm64-v8a]
23 pc 00000000000b0dbc /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64) [arm64-v8a::ccd118b72b8037094ae4d9be046a6969]
24 pc 00000000000500d0 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) [arm64-v8a::ccd118b72b8037094ae4d9be046a6969]
这是崩溃日志:
--------- beginning of crash
16604-08 07:31:49.181 1348 1419 F libc : fdsan: attempted to close file descriptor 160, expected to be unowned, actually owned by FILE* 0x7840fd40c0
核心问题:fdsan 文件描述符双重关闭
崩溃的直接原因来自这条日志:
fdsan: attempted to close file descriptor 160, expected to be unowned,
actually owned by FILE* 0x7840fd40c0
fdsan(File Descriptor Sanitizer) 是 Android 的 FD 安全机制,检测到有人试图 close() 一个已经被 FILE* 持有的文件描述符,这是典型的 double-close / use-after-close 问题。
调用栈解读
00 fdsan_error ← fdsan 检测到非法关闭,触发 SIGABRT
01 android_fdsan_close_with_tag
02 close() ← 某处调用了 close(fd)
03-#04 libbinder ← Parcel 在释放时关闭 FD(通常是 native fd)
05-#06 libgui ← Surface::queueBuffer 提交帧缓冲
07 libvulkan ← Vulkan 层呈现
08-#09 flutter::SurfaceFrame::Submit() ← Flutter 提交渲染帧
10-#13 flutter::Rasterizer::Draw() ← Flutter raster 线程绘制
问题发生的链路:Flutter raster 线程在提交帧(queueBuffer)后,Parcel 析构时尝试关闭一个 FD,而该 FD 此时已经被 FILE* 封装持有(或已经被关闭过一次)。
为什么升级 Flutter 3.24 → 3.38 会引入此问题?
有几个可能方向:
- Vulkan 后端的变化(最可能)
Flutter 3.x 后续版本默认更激进地启用 Vulkan 渲染路径。步步高学习机使用的 Android 系统(surfaceflinger)对 APK 文件的 FD 传递有 SELinux 限制:
avc: denied { read } for path=".../base.apk"
scontext=u:r:surfaceflinger:s0 ← surfaceflinger 进程
tclass=file permissive=0 ← 严格模式,拒绝访问
这说明新版 Flutter 的 Vulkan/Surface 路径在提交帧时,让 surfaceflinger 尝试直接读取 APK(可能用于 shader 或资源加载),被 SELinux 拒绝后触发了异常的 FD 状态。 - Parcel 传递 FD 的生命周期管理变化
新版 Flutter 在 queueBuffer 时通过 Parcel 传递 native FD(如 fence fd、buffer fd),若 Flutter 侧和 Android 系统侧对 FD ownership 的理解不一致,就会产生 double-close。 - 步步高设备的系统版本与新 Flutter 的兼容性
步步高学习机通常使用定制 Android,其 libbinder / libgui 版本可能与新 Flutter 预期的行为有差异。
排查建议
优先级措施🔴 高检查新版 Flutter 是否默认开启了 Vulkan,尝试强制使用 OpenGL ES:--enable-software-rendering 或在 AndroidManifest.xml 中设置 <meta-data android:name="io.flutter.embedding.android.EnableVulkanBackend" android:value="false"/>🔴 高确认步步高设备 Android 版本,看是否有专属的 Flutter 兼容性 issue🟡 中在 Flutter 的 issue tracker 搜索 fdsan queueBuffer 相关 bug🟡 中尝试在两个版本之间二分法定位具体是哪个小版本引入的🟢 低向步步高反馈 SELinux 策略问题(surfaceflinger 无法读取 APK)
关键结论
这个崩溃本质是 Flutter 新版本在特定 Android 设备上的 Vulkan/Surface 渲染路径与系统 FD 所有权管理不兼容,叠加了步步高定制系统的 SELinux 限制,属于设备兼容性问题而非业务代码 bug。优先尝试禁用 Vulkan 后端验证是否能消除崩溃。