下载完成提示音路径经 toLatin1 损坏 → NSSound nil 路径 → 未捕获 NSException(主线程崩溃)

证据链

1. dump 内嵌异常消息(3/3 个抽检 dump 一致):

`*** Terminating app due to uncaught exception 'NSInvalidArgumentException',

reason: '*** -[NSURL initFileURLWithPath:]: nil string parameter'`

2. 本机 macOS 26.5.1 的 AppKit build(2685.60.104)与 dump 完全一致,用 lldb

对 shared cache 符号化关键帧:

3. 栈:QObject::event(QTimerEvent,qobject.cpp:1369)→ app 帧 → NSSound init

→ NSURL fileURLWithPath: nil → 抛异常 → 未捕获 → _crashOnException 主动断点。

与 TaskQueueManager.cpp:1587/1931 的

QTimer::singleShot(0, this, [this,…]{ playSound(…); }) 吻合。

4. 反汇编 appdepends/lib/common/mac/Release/libutilosm_u.a 中

sndPlaySound(const char*, uint)(MacAPIUse.o):

[[NSSound alloc] initWithContentsOfFile:… byReference:YES],无 nil 检查。

根因

TaskQueueManager::playSoundFile(TaskQueueManager.cpp:2185-2206)mac 分支:


QByteArray ba = filePath.toLatin1();   // ← line 2188,mac 上错误的编码
lpszFile = ba.data();
...
sndPlaySound(lpszFile, bLoop);          // mac 实现按 UTF-8 解码

音频路径含 Latin-1 高位字符(é、ü、ñ 等,欧洲用户名/安装路径常见)时,

toLatin1() 输出 0x80-0xFF 单字节,不是合法 UTF-8,

stringWithUTF8String: 返回 nil → initWithContentsOfFile:nil →

+[NSURL fileURLWithPath:nil] 抛 NSException。Qt 事件循环内无 ObjC 捕获 → 必崩。

放大因素:下载完成提示音默认开启(GetSoundDownloadFinishState() 默认 true,

appconfig.cpp:1196-1206),默认音频路径 = g_GetResourcesDir() + "/succ.wav"

随安装路径继承非 ASCII 字符 → 命中用户每次下载完成必崩。

修复建议(Fix Scope 内,低风险,MR 候选)

utility_tool @ dev_vs2019,TaskQueueManager::playSoundFile:

1. mac 分支改用 filePath.toUtf8()(sndPlaySound 底层按 UTF-8 解码);

2. 与 Windows 分支对齐,增加空串/文件存在检查后再调用。

单函数局部修改,不影响 Windows 路径(#ifdef OS_WIN 分支不动)。

关联

见 daily summary 的 deferred 项,机制不同,另行分析。