SpyGlass 文件损坏截断:unexpected end of file 速查
更新时间:2026-10-23。FAQ 速查页,属于 EDA 工具排错系列。SpyGlass 读工程、读库、加载上次 run 的产物时报「文件损坏/截断」——文件在、大小看着也不离谱,但解析到一半撞上意外结尾。这类问题几乎没有「修文件」的选项,核心是定位半截文件是谁写的、从上一个完好副本恢复。最大的上游是磁盘写满时产物写了半截,那一刻的处置见 SpyGlass 磁盘写满;同型的时序侧问题见 PrimeTime 文件损坏截断。
本文要回答的问题
- 报 unexpected end of file,文件大小正常,怎么确认它真的坏了?
- 上次 run 还好好的,这次加载就 corrupt,中间发生了什么?
- 损坏文件能不能修?什么情况下必须清工作目录重编?
- 同一个文件反复坏,是 SpyGlass 的 bug 吗?
一、报错原文与现象
Error: unexpected end of file while reading 'spyglass_work/project.db'.
Error: database corrupt: checksum mismatch in cache entry. (DB-READ-01)
Error: parse error at line 98231 in file 'libs/cells.sglib': unexpected token. (PARSE-EOF)
Warning: file 'constraints.sgdc' appears truncated; partial data loaded.先分清两种形态:截断(unexpected end of file / truncated)——文件尾部丢了,写盘或传输被中断的签名;内容损坏(checksum mismatch / 中间某行 parse error)——字节数在但内容错了,常见于并发写互相覆盖、NFS 读到缓存混合体。两者恢复路径一样(找完好副本),但防复发手段完全不同:截断防「写不完」,内容损坏防「写串了」。注意 parse error 指向固定行号且每次重新生成后行号会变,这是并发写的典型特征,要和真正的语法错误区分开——语法错误的排查口径见 SpyGlass 语法解析错误。
二、原因速查表
| 报错现象 | 可能原因 | 处置 |
|---|---|---|
| 文件尾部缺失 | 上次 run 磁盘写满,产物写了半截 | 整段产物作废,从完好检查点重跑 |
| 缓存目录文件半截 | 进程被 kill -9 时正在写数据库 | 清工作目录缓存,重新加载 |
| 报损坏伴随 stale file handle | NFS 写缓存未落盘机器就重启 | 重新挂载,服务端核对文件 |
| 库文件中间 parse error | 并发两个 run 写同一工作目录互截 | 隔离工作目录,生成侧原子写入 |
| 拷来的工程打开就坏 | scp/rsync 传输中断只拷了一半 | 校验和比对后重传 |
| 反复坏同一路径 | 文件系统错误,dmesg 有 I/O error | 换分区验证,报存储管理员 |
三、逐条排查展开
第一步:tail 看文件是不是「完整结束」。 文本类文件(sgdc、sglib、日志)直接看尾部:
tail -5 spyglass_work/project.db
ls -l spyglass_work/project.db
md5sum spyglass_work/project.db完好的文本产物尾部通常是收尾标记或空行;半截文件的尾部是「一句话写到一半」——行中断在任意字符处。二进制库文件看不了内容就比对校验和与文件大小:和源头(生成机器或同事手上的副本)对 md5,一致说明文件没坏、问题在读取侧(工具版本、NFS 缓存),不一致就坐实是写/传环节出的半截。
磁盘写满写穿的产物链整段作废。 上次 run 撞上磁盘写满那一刻,正在写的工程库、缓存、中间网表全部是不完整状态;更要命的是下游已经读过这些半成品的产物也不可信——用半截库跑出来的 lint 报告,能打开不代表结论完整。处置纪律:从「最后一个确认完好的检查点」之后全部重跑。磁盘写满那一刻的应急(怎么腾空间、怎么判断写穿范围)见 SpyGlass 磁盘写满,本篇管的是事后读回这堆半截产物怎么办。
kill -9 留下的半截缓存清掉重来。 SpyGlass 写工作目录数据库不是原子操作,进程被 kill -9(OOM、误操作、调度系统杀作业)时正在写的缓存文件就是半截。签名很明确:报错文件在缓存目录里、修改时间与上次 run 被中断的时间吻合。处置很轻——删掉该 run 的缓存目录重新加载即可,源码工程没动就不影响。这也是为什么工作目录要按 run 隔离:一个 run 的半截缓存不会污染下一个 run。
NFS 场景先怀疑落盘时机。 报损坏的同时伴随 stale file handle,或者「提交作业的机器能读、登录机不能读」,基本是 NFS 写缓存未落盘机器就重启了——客户端缓存里文件是新的,服务端磁盘上只有半截。验证:直接到存储服务端读该文件算 md5,与客户端看到的比对。处置:重新挂载刷新缓存,服务端那份如果是半截就从源头重传或重生成;日常挂载参数加上 actimeo 缩短缓存窗口能压低这类不一致的概率。
并发两个 run 写同一工作目录是「互截」。 调度系统里两个 job 共用同一个 SPYGLASS_WORK,A 在写 project.db 时 B 也在写同名文件,互相把对方的文件截短、内容交错——报错的行号每次重新跑都不一样,就是这个根因的指纹。处置:每个 run 独立工作目录(目录名带作业号);库文件这类「一次生成多方消费」的共享产物,生成侧先写临时文件再 mv 原子改名,读者要么看到旧版要么看到新版,不会看到混合体。
传输中断的半截靠校验和闭环。 scp/rsync 拷工程目录,网络抖动中断后目录看着「差不多全」,实际某个库文件只来了一半。标准动作:源端算 md5 写进交付清单,收端收到先验再用;rsync 用 -c 按校验和断点续传,不要按文件大小判断「应该拷完了」。文件系统层反复坏同一路径的(dmesg 里有 I/O error),换分区验证一次坐实后报存储管理员,别在应用层反复重跑。
颜色按语义分角色:红是报错入口与「文件确实坏了」的两类根因,蓝是排查动作,绿是「文件没坏、查读取侧」的分流,橙是三条恢复路径,紫是两条防复发线。主线是「校验和先行分流」:与源一致走读取侧(NFS 缓存、工具版本),与源不符按损坏环节分流恢复——写满或被 kill 的整段作废重跑,传输中断的重传,并发互截的隔离工作目录。
四、防复发纪律
- 每个 run 独立工作目录:目录名带作业号,杜绝并发互截与半截缓存交叉污染。
- 交付必带校验和:跨机器/跨站点的工程与库交付,清单含 md5,收端验过才入库。
- 生成侧原子写入:一律先写临时文件再 mv 改名;共享库目录加文件锁、落地后只读化。
- 写满与 kill 事故整段作废:从最后完好检查点之后全部重跑,固化进流程脚本。
- 慎用 kill -9:先给正常终止信号让工具收尾写盘,等超时再升级;NFS 挂载加 actimeo 缩短缓存窗口。
这一篇在知识体系里的位置
本篇是 EDA 排错速查簇中「数据完整性」节点的 FAQ 页,上承 SpyGlass 磁盘写满(半截文件的最大上游,两篇是因果对:那篇管写满一刻,本篇管事后读回),旁接 SpyGlass 语法解析错误(真语法错误与「并发写造成的假 parse error」的分流)与 PrimeTime 文件损坏截断(时序侧同型问题,恢复纪律互通)。
一句话总结
SpyGlass 文件损坏截断先 tail 看尾部、算校验和与源头比对分流:一致查读取侧(NFS 缓存、工具版本),不符按环节恢复——磁盘写满或 kill -9 写穿的整段产物链作废重跑,传输中断的校验和后重传,并发互截的隔离工作目录;治本靠「每 run 独立工作目录、交付带校验和、生成侧临时文件原子改名」三条纪律,让半截文件在入库前被发现而不是在流程里发作。