SpyGlass 退出码非零:sg_shell exit code nonzero 速查
更新时间:2026-10-23。FAQ 速查页,属于 EDA 工具排错系列。流水线红灯,失败摘要里只有一句
sg_shell exited with code 1,点开日志翻半天「好像也没报什么错」——这是 SpyGlass 批处理模式下最典型的迷惑现场。和综合、布局布线工具不同,SpyGlass 的退出码不只表达「跑没跑成」,还表达「检查结果过没过」:lint 违规超了阈值,分析本身完全正常,退出码照样非零。难的是分清这次非零到底是「工具死了」还是「设计没过关」。同类问题在其他工具的表现见 PrimeTime 退出码非零,跑太久被调度系统掐掉的场景见 SpyGlass 运行超时卡死。
本文要回答的问题
- 退出码非零但日志里看不到显眼 ERROR,到底失败在哪?
- 违规(violation)计数和退出码是什么关系,WARNING 会不会也让退出码非零?
- 脚本/CI 只看了退出码,怎么补出真正的第一条错误?
- timeout 的 124、并行 job 的聚合退出码,怎么和工具自身的非零分开?
一、报错原文与现象
# CI 流水线通知
stage lint: sg_shell exited with exit code 1 (failed)
# 失败摘要
(no error message captured)
# sg_shell 日志尾部(看起来一切正常)
*** SpyGlass Run Completed ***
Total violations: 3 (ERROR: 0, WARNING: 3)现场三个特征:流水线只报退出码、摘要为空、日志尾部写着 Run Completed。这三个特征凑齐,九成是「违规计数/severity 策略」问题而不是工具崩溃——SpyGlass 默认有违规即可能非零退出,WARNING 算不算致命取决于 goal 与退出码策略的配置。真正的 ERROR 如果存在,往往埋在日志中段,被后面几千行信息性输出刷掉了。
二、可能原因总览
| 现象/退出码 | 可能原因 | 处置 |
|---|---|---|
| 非零,日志有违规计数 | lint 违规超阈值(含 WARNING 被升级) | 看违规清单与 goal 阈值配置,修 RTL 或调 waiver |
| 非零,日志中段有 ERROR | 真错误被级联输出刷掉 | grep 第一条 Error,修脚本或输入 |
| 非零,Tcl 里 catch 吞错 | 包装脚本某命令失败但被捕获,exit 用了残留状态 | 逐命令检查返回值,失败即退出 |
| 124 | 回归包装脚本 timeout 到了,不是工具退出码 | 延长时限或按 超时排查 处理 |
| 137 / Killed | 内存超限被系统杀 | 加内存申请或拆设计跑 |
| 并行回归聚合非零 | 某一个 goal/job 失败拉高整体退出码 | 逐个 goal 单跑二分定位 |
| 工具成功但脚本非零 | 收尾命令(归档/通知)失败 | 检查退出码捕获的是哪条命令 |
三、逐条排查展开
第一步永远是先取日志里的第一条 Error,再决定方向。 SpyGlass 日志动辄几万行,尾部全是统计和收尾信息,真错误在中段。固定套路:
grep -n -i "error\|fatal" spyglass.log | head -20
grep -n "violation" spyglass.log | tail -10
echo "sg_shell exit code was: 对照下表"第一条 grep 取最早的 Error 而不是最晚的——一个失败会引发后面一串级联报错,根因永远是第一条。第二条看违规汇总:如果 ERROR: 0 只有 WARNING,那这次非零是策略问题而不是工具问题,方向完全不同。
分清「违规触发非零」与「真崩溃触发非零」。 SpyGlass 的退出码语义和多数 EDA 工具不一样:分析跑完、设计有违规,按退出码策略就可能返回非零。触发路径有三条:一是 goal 自带的违规阈值(某条规则计数超过容忍值即判失败);二是 severity 设置把 WARNING 升级成了 ERROR 级别的失败条件;三是项目策略文件里写了「任何未 waive 的违规即失败」。这三条的共同特征是日志尾部有正常完成标记、有违规计数表。处置不是修工具,而是看违规清单:该修 RTL 修 RTL,该加 waiver 走 waiver 流程,该调阈值改 goal 配置——别把策略失败当工具 bug 反复重跑。
Tcl 包装脚本吞错是最隐蔽的一种。 SpyGlass 流程常套一层项目自己的 Tcl 包装:逐条跑 goal、收报告。如果包装里用了 catch 兜住某条命令的失败却没处理,脚本继续往下跑,最后 exit 用的是某个残留的非零状态——表现出来就是「每一步看起来都跑了,退出码却是 1」。反过来更危险的是吞错后 exit 0:工具失败了流水线却判绿。两条都是脚本缺陷,修法一样:每个关键命令后检查返回值,失败立即带命令名与阶段名非零退出,不依赖最后的残留状态。
timeout 的 124 不是 SpyGlass 的退出码。 回归包装脚本常用 timeout 命令兜时限,超时后 timeout 自己返回 124,把工具真实的退出状态盖掉了。看到 124 不要查 SpyGlass,先查时限配置和设计规模是不是涨了——卡死与超时的完整排查见 SpyGlass 运行超时卡死。同样地,137(SIGKILL)是内存超限被系统杀,证据在系统日志不在工具日志。
并行回归的聚合退出码要拆开来验。 一次回归跑十几个 goal,包装脚本聚合出一个退出码——只要有一个 goal 非零,整体就非零。这时不要在聚合日志里乱翻,二分定位:逐个 goal 单跑,找到那个非零的,再对它单独用上文的 grep 套路。单跑还能顺便排除「并行资源竞争导致的偶发失败」——单跑通过、并行失败的,查资源配额与临时目录隔离,偶发类问题见 SpyGlass 结果不稳定。
颜色按语义分角色:红是问题入口,蓝是排查动作,绿是「拆并行聚合」这条分流,橙是修复,紫是防复发。主线是「先分工具死了还是设计没过关」:124/137 走系统与包装脚本通道,1/2 先 grep 第一条 Error 再看违规计数表——违规超阈值修设计或调策略,真 ERROR 修脚本或输入,两条路互不相通,别拿修 bug 的劲头去重跑策略失败。
四、预防与纪律
- 包装脚本逐命令错误传播:每个 goal、每条关键命令后检查返回值,失败即带阶段名退出,不靠 catch 吞。
- 失败通知附违规摘要:脚本收尾自动摘出违规计数表与全部 ERROR 行,CI 通知直接带上,省一轮翻日志。
- WARNING/ERROR 策略成文:哪些规则算致命、阈值多少、waiver 谁批,写进项目文档,不靠口传。
- timeout 与工具退出码分开记:包装脚本把 timeout 的 124 单独映射成「超时」标签再上报,不与工具非零混淆。
- 并行回归留单跑入口:聚合失败后一条命令就能逐 goal 重放,二分定位不靠手抄。
这一篇在知识体系里的位置
本篇是 SpyGlass 排错速查簇中「批处理与回归」节点的 FAQ 页,与 SpyGlass 运行超时卡死(124 退出码的深层排查)、SpyGlass 结果不稳定(并行偶发失败)、SpyGlass license 签出失败(中途退出的另一大来源)互相衔接;其他工具的退出码对照见 PrimeTime 退出码非零。
一句话总结
SpyGlass 退出码非零先做二分:看数字(124 查 timeout、137 查内存、1/2 查日志),再 grep 第一条 Error 与违规计数表——违规超阈值修 RTL 或调 waiver/goal 策略,真 ERROR 修脚本输入,并行聚合就逐 goal 单跑;治本靠包装脚本逐命令错误传播加失败通知附违规摘要,让每次红灯都能一眼看出是「工具死了」还是「设计没过关」。