Repository navigation
7.0.1:嵌套值类型在 Task.detached 默认后台栈中解码溢出(Debug / Release,附独立复现) #140
Unanswered
chen0807130004
asked this question in
Q&A
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
问题描述
将自动模型解析放到 Swift Concurrency 后台执行时,嵌套值类型可以触发线程栈溢出。已经将业务 App、网络、AES 解密和 UI 全部移除,整理成只依赖 Foundation / Darwin / SmartCodable 的 SwiftPM 可执行程序。
同一份模型、同一份完整 JSON、同一默认后台线程栈下:
这里报告的是栈空间问题,不是已确认的数据竞争或内存泄漏;暂不预判是库内部泛型临时值、Swift 自动生成的 Decodable,还是两者共同造成。想请教是否属于已知限制,以及是否有保留自动解析的解决方向。
环境
bc1522f6b635128ea992331867fe65f231492dc0pthread_get_stacksize_np:536576 bytesMemoryLayout<Big>.size:24584 bytes验证范围说明:下面的 7.0.1 结果来自独立 macOS 程序。业务 iOS App 中也有类似问题,但不把旧版本的 iOS 结果当成 7.0.1 已完成真机验证的证据。
最小复现
新建目录,放置以下两个文件。全部模型使用自动合成 Codable,没有手写
init(from:),也没有引用环。Package.swift
Sources/Probe/main.swift
JSONEncoder在进入后台任务之前生成完整 JSON;原生与 SmartCodable 读取的是同一份 Data。后台仅有一个Task.detached,内部连续解码,不启动多个并发解析,也不调整线程栈。两个解析入口分别放在
@inline(never)函数中,避免把两套解析结果的大值临时对象堆在同一个分支函数栈帧上。返回Any仅用于保持结果存活;后台不做重新编码校验。运行步骤
在上述 Package.swift 所在目录,逐条运行:
不需要连接后端、登录 App 或准备业务数据。若从 Xcode 调试,需要移除已有异常断点对执行流程的干扰;命令行即可观察正常退出或信号退出。
预期结果
后台正常完成解析并打印
PASSED。如果这类值类型布局超出库的支持边界,希望有明确说明,而不是依赖线程碰巧有更大的栈。实际结果
SmartCodable 两种构建都只输出:
原生两种构建输出:
关键崩溃栈
Debug 的代表性调用链如下(完整系统日志显示访问了 Stack Guard 区域):
Release 的最顶层停在 Swift 类型元数据解析附近,但系统日志同样指向 Stack Guard;其下仍经过
specialized Big.init(from:)、JSONDecoderImpl.unwrap<A>(as:)与泛型 keyed decode 链路。没有把顶层元数据函数直接判定为根因。已排除 / 尚未确认
想请教
T/T?的中间值,是否可能与自动生成的init(from:)叠加出较高栈占用?谢谢,愿意继续协助验证修复分支。
SmartCodable-7.0.1-stack-overflow-repro.zip
All reactions