DJI Assistant 2 在新版 macOS 上一直轉圈:兩個睡了好幾年的 bug

DJI Assistant 2 在新版 macOS 上一直轉圈:兩個睡了好幾年的 bug

💡 原文中文,约6300字,阅读约需15分钟。
📝

内容提要

作者发现DJI Assistant 2在macOS 26/27上连接飞机后一直转圈,原因是DJIService崩溃。根源是Qt 5.6误判新系统版本号,未加RTLD_LOCAL,导致四个插件同名weak符号被合并,飞机通道误用基地台版本而空指针崩溃。作者提供脚本修改QtCore两个字节修复,并说明视觉校正需单屏、原生分辨率等条件。

🔎

延伸解读

旧版软件在新系统上的兼容性陷阱

DJI Assistant 2 自 2020 年后未更新,其内置的 Qt 5.6 在 macOS 27 上误判系统版本,导致动态库加载时缺少 RTLD_LOCAL 标志,进而触发符号合并崩溃。这提醒用户:停止维护的软件可能因系统底层变化而突然失效,即使界面看似正常,核心服务也可能在后台崩溃。

修复脚本的适用边界与风险

作者提供的脚本仅针对 DJI Assistant 2 For Phantom 2.0.10.4,通过修改 QtCore 的两个字节强制启用 RTLD_LOCAL。脚本会校验 sha256 并备份原文件,但用户需自行承担修改二进制文件的风险。若版本不符,脚本会拒绝执行,此时可参考文中给 AI agent 的 prompt 进行诊断。

视觉校正的额外条件

即使修复了崩溃问题,视觉校正仍要求单屏幕连接和原生分辨率(如 15 吋 MacBook Air 需设为 2880×1800 1x)。多屏或缩放分辨率会导致校正图案尺寸计算错误或反复弹出输入框。此外,每次重启 DJI Assistant 后需重新开关飞机,否则校正程序无法打开视觉镜头。

问题影响范围与系统版本

该崩溃与 CPU 架构无关,Intel 和 Apple Silicon 均受影响。macOS 10.15 及更早版本不会出现,macOS 11–12 因系统版本兼容机制返回 10.16 而幸免,macOS 13–15 情况不确定,macOS 26 很可能出现,macOS 27 已实测确认。Windows 版因 DLL 导入机制不同,推测不会触发此问题。

❓

Q&A

DJI Assistant 2 在 macOS 26/27 上连接飞机后一直转圈,是什么原因?

原因是后台的 DJIService 崩溃。DJIService 负责与飞机通信,它崩溃后 UI 只能一直等待。崩溃的根源是 Qt 5.6 误判新系统版本号,未加 RTLD_LOCAL,导致四个插件中同名的 weak 符号被合并,飞机通道误用了基地台版本的代码,访问空指针而崩溃。

如何判断我的 DJI Assistant 2 是否遇到了这个崩溃问题?

可以检查以下几点:用 USB 接上飞机后,Calibrate Now 一直 loading,固件页或 Fly Safe 数据库更新无反应;~/Library/Logs/DiagnosticReports/ 里有 DJIService-<日期>.ips 崩溃报告,时间点在飞机接上后几秒;ui_ass2.log 一直重复 ws://localhost:19870/general2connection error;macOS 是 26 以后版本,Intel 和 Apple Silicon 都一样。

有没有简单的修复方法让 DJI Assistant 2 不再崩溃?

有。作者提供了修复脚本,仅适用于 DJI Assistant 2 For Phantom 2.0.10.4。步骤:完全关闭 DJI Assistant;下载脚本并检查内容;在终端执行 `bash ~/Downloads/dji-assistant2-mac-fix.sh status` 和 `apply`;如果飞机开着,先关机再开机,再打开 DJI Assistant。脚本会修改 QtCore 的两个字节,修改前会比对 sha256 并备份原文件。还原可执行 `restore`。

修复后视觉校正还是无法进行,有什么其他条件?

视觉校正还有两个与崩溃无关的条件:只接一台屏幕,接两台时校正图案大小会算成 0,窗口空白;分辨率要设成屏幕原生且不缩放,例如 15 吋 MacBook Air 要切到 2880 × 1800(1x),需在系统设置中开启“Show resolutions as list”和“Show all resolutions”才能选到。另外,每次重开 DJI Assistant 都要把飞机关机再开机,否则校正程序打不开视觉镜头。

哪些 macOS 版本会遇到这个 DJI Assistant 2 崩溃问题?

macOS 10.15 以前不会,因为主版本号是 10,Qt 会加上 RTLD_LOCAL;macOS 11–12 不会,旧 SDK 的 app 拿到的是 10.16;macOS 13–15 不确定;macOS 26 很可能会,作者在 26 时出现过同样症状但没留下崩溃报告;macOS 27 会,已实测。Windows 不会,因为 DLL 导入绑定到指定 DLL,没有跨 DLL 的 weak 合并。与 CPU 无关,Intel Mac 一样会遇到。

修复脚本具体修改了 QtCore 的什么内容?原理是什么?

脚本将 QtCore 中 QLibraryPrivate::load_sys 里比较 QSysInfo::MacintoshVersion 的指令 `jle`(7e 0a)替换为两个 `nop`(90 90),使 Qt 一律带上 RTLD_LOCAL。这样四个插件都以 RTLD_LOCAL 加载,dyld 不会合并它们的 weak 符号,每个插件绑定回自己的那份,飞机通道不再误用基地台版本,从而避免崩溃。

🏷️

标签

➡️

继续阅读