Calibre 退出码非零怎么办:calibre 批处理失败速查
更新时间:2026-10-22。FAQ 速查页,属于 EDA 工具排错系列。Calibre(Mentor/Siemens 的物理验证工具,批处理入口是
calibre -drc/-lvs/-pex,PEX 旧命令叫xrc,脚本壳叫calibredrv)跑完之后,make、LSF(bsub)、Jenkins/GitLab CI 只看一个数字:退出码。麻烦在于这个数字把两类完全不同的事混在了一起——rule deck 语法错、找不到版图输入、license 检不出来、超内存被杀,是运行级失败;而 DRC 报出违例、LVS 结果是 INCORRECT,是工具正常跑完给出的检查结果,本来就不该让作业变红。先分清这一层,非零码才有意义。工具本身崩溃(段错误、Aborted)的处置见 Calibre 段错误崩溃速查,资源耗尽的细节见 Calibre 资源不足/overflow 速查,deck 解析问题见 Calibre 规则语法/解析错误速查,流程背景见 Calibre 物理验证实操,全簇索引见 开源 EDA 报错排错中心。
本文要回答的问题
calibre -drc rule.svrf跑完echo $?是 1,但结果库里明明有 DRC 报告,到底算不算失败?- LVS 报告打
LVS RUN COMPLETED但结果是 INCORRECT,退出码应该是 0 还是非零? - 退出码 1、130、137、143 分别是谁给出的,怎么区分工具自杀、OOM 和调度系统杀作业?
- transcript 刷了几千行,怎么快速抓到真正致命的那一条?
- 作业包了一层 wrapper、又管道给了
tee,为什么 CI 拿到的退出码总是 0?
一、报错原文与现象
最常见的形态:transcript 末尾有明确的错误横幅,shell 拿到通用非零码。
$ calibre -drc -hier rule.svrf > run.log 2>&1
$ echo $?
1
$ tail -5 run.log
ERROR: Cannot open file "/path/to/top.gds" for reading.
Error: rule deck /path/to/rule.svrf could not be compiled.
--- EXITING due to error码 1 是最笼统的「运行级失败」:deck 没过、输入没打开、license 没检出、PEX extract 阶段没走完,最后都收敛成这个数字。数字本身不携带原因,原因在 transcript 里。
第二种形态更迷惑:报告文件都在,非零却来自外层 shell 或调度器。
$ bsub -W 120 -o lsf.out calibre -lvs -turbo rule.lvs
$ bhist -l 123456 | grep -E "Exited|TERM"
Exited with exit code 137; TERM_MEMLIMIT: job killed after reaching LSF memory limit137 不是 Calibre 自己退的——128+9 表示进程收到 SIGKILL,典型是 OOM killer 或 LSF 内存/运行时限额动手。第三种是「该红的不红」:管道吃掉了真实返回值。
calibre -drc rule.svrf 2>&1 | tee run.log
echo $? # 拿到的是 tee 的退出码,calibre 失败也显示 0二、退出码与诱因速查表
退出码的具体语义随站点封装(Calibre 本体、shell wrapper、LSF)可能不同,下表按常见 Unix/调度惯例保守表述,以本站点 transcript 与 bhist 记录为准。
| 退出码 / 现象 | 最可能原因 | 处置 |
|---|---|---|
| 1,日志有 ERROR / EXITING 横幅 | deck 编译失败、输入文件打不开、license 检出失败 | grep 致命行,按第三节目录分层定位 |
| 0,但 LVS 结果 INCORRECT | 工具跑完了,设计与版图不一致 | 这是结果不是失败,修电路或查短路/悬空 |
| 0,DRC 结果库有违例 | 检查正常执行并报出 rule violation | 按违例修版图,不要把结果当工具故障提单 |
| 127 | shell 找不到 calibre 命令或环境没加载 | 检查启动脚本 PATH/MGLS_LICENSE_FILE |
| 130(128+2) | 进程收到 SIGINT,通常是 Ctrl-C 或人工中断 | 确认是否人为停作业,重跑即可 |
| 137(128+9) | SIGKILL:OOM killer 或 LSF 内存限额杀作业 | 降线程/hier 分层,见资源 overflow 篇 |
| 143(128+15) | SIGTERM:调度器到期、bstop/brequeue 或运维回收 | bhist -l 看 TERM 原因,别当脚本 bug |
| 非零且 transcript 戛然而止 | 段错误/Aborted 一类真崩溃 | 按段错误篇收 core 与最小复现 |
管道后 $? 为 0 | tee 吃掉 calibre 返回值 | set -o pipefail 或取 PIPESTATUS |
| wrapper 返回 0 但作业实际失败 | 包装脚本没透传子进程退出码 | wrapper 末尾 exit $CAL_EXIT |
三、逐条排查展开
先抓 transcript 的致命行,再谈退出码。 码 1 不区分病因,Calibre 的习惯是在结束前打 ERROR/FATAL/EXITING due to error 一类横幅。不要从头翻几千行日志,直接从尾部和错误关键字两头夹:
grep -niE "error|fatal|exiting|cannot (open|checkout)" run.log | head -20
tail -30 run.log行号最小的那条致命信息通常就是根因,后面的报错多是连锁反应:deck 编译失败导致一个检查都没跑,PEX 没完成导致网表没写出来。deck 语法层面的细节照 Calibre 规则语法/解析错误速查 处理。
然后按码分层:运行级、信号级、环境级各走各的路。 下面这张决策图就是分诊顺序。
读图抓住颜色:红色是入口现象,蓝色两步是分诊(先取真实退出码与日志,再问有没有致命行),橙色两条是工具失败支线,绿色是最容易误判的分支——日志没有致命行、报告完整时,DRC/LVS 报出的违例是设计问题而不是作业失败;紫色收尾强调两类问题走两套修复流程,不要混修。
运行级失败按四类点杀。 deck 类:rule deck 路径错、版本与本侧 Calibre 不匹配、include 的子规则文件缺失;输入类:LAYOUT PATH/SOURCE PATH 指向的 GDS/OASIS/网表不存在或相对路径基准目录不对(批处理常见于换了提交机);license 类:transcript 里有 Unable to checkout / MGLS_LICENSE_FILE 字样,是许可证检不出来,属于环境问题不是设计问题;PEX 类:extract 阶段中断会让 .sp 网表残缺,码同样是非零,要确认摘要里 extract 是否完整走完。脚本类:calibredrv 跑 Tcl 批处理或用 calibre -run <控制文件> 驱动时,Tcl 异常未捕获、控制文件里阶段状态被标成 fail,也会以非零退出,症状是 deck 本身没问题、日志却停在某条脚本命令之后——这时查脚本最后一条回显,而不是查规则。资源类(内存/磁盘/线程)的处置见 Calibre 资源不足/overflow 速查。
信号级先问「谁杀的」,不要查脚本。 130 是 SIGINT(人工 Ctrl-C 居多),143 是 SIGTERM(调度器到期、bstop/brequeue 回收、运维批量停作业居多),137 是 SIGKILL(OOM killer 或 LSF 的 TERM_MEMLIMIT)。这三类 Calibre 都来不及打横幅,症状是 transcript 戛然而止。用 bhist -l <jobid> 看 TERM_* 原因和 elapsed 时间:撞限时提限时、降 -turbo 线程数或改 hier 分层,而不是改 rule deck。进程直接崩溃(139/134 一类)则换 Calibre 段错误崩溃速查 的流程。
最关键的认知:有违例是结果,不是工具失败。 Calibre 的退出码回答的是「我有没有正常执行完检查」,不是「设计干不干净」。DRC 结果库里有 metal spacing 违例、LVS 摘要打出 INCORRECT,只要检查流程完整跑完,退出码就是 0。CI 因此要用双条件判定:
set -o pipefail
calibre -drc -hier rule.svrf 2>&1 | tee run.log
CAL_EXIT=${PIPESTATUS[0]}
VIOL=$(grep -c "^RULECHECK " run.log || true) # 按本站点摘要格式调整
[ "$CAL_EXIT" -ne 0 ] && { echo "TOOL FAILED ($CAL_EXIT)"; exit 1; }
[ "$VIOL" -gt 0 ] && { echo "DRC RESULTS: $VIOL violations"; exit 2; }
echo "CLEAN"; exit 0退出码 1 上报工具失败,另用码 2 上报「检查通过但设计有违例」,流水线才看得出红的是哪一类;LVS 同理,判据是摘要里的 CORRECT/INCORRECT 文本而不是退出码。
wrapper 与管道要把真实码递到最外层。 批处理平台常常自带一层启动脚本,里面 source 环境、切目录、管道落日志——任何一环都可能把退出码清零。wrapper 必须显式接住并透传:
#!/bin/bash
set -o pipefail
calibre "$@" 2>&1 | tee "logs/${LSB_JOBID:-local}.log"
exit ${PIPESTATUS[0]}没有 pipefail 且不写 exit ${PIPESTATUS[0]} 时,wrapper 永远以最后一条命令的码收尾,作业全绿但报告目录是空的。Makefile 规则同理,shell 行要显式 set -o pipefail。
四、预防与纪律
- CI 判定一律双条件:退出码非零 = 工具执行失败;结果摘要里的违例计数或 LVS INCORRECT = 设计未通过,两类用不同失败码上报。
- wrapper 模板固化:
set -o pipefail+tee全程落日志 + 末尾exit ${PIPESTATUS[0]},禁止裸管道直接回 CI。 - 作业脚本先固化环境再跑:显式
source工具与 license 环境(含MGLS_LICENSE_FILE),输入路径尽量用绝对路径,避免换机后 127 或找不到文件。 - 信号杀不归脚本管:130/137/143 先
bhist -l查TERM_*与 elapsed,按资源/限时处理,别改 deck。 - transcript 随作业归档:重跑用追加方式保留历史日志,首条致命行一旦被覆盖就很难还原。
这一篇在知识体系里的位置
本篇是 EDA 排错速查簇中「Calibre 批处理/退出码」节点的 FAQ 页,与 Calibre 段错误崩溃速查(139/134 信号与崩溃分支)、Calibre 资源不足/overflow 速查(137 的根治)、Calibre 规则语法/解析错误速查(码 1 的 deck 类根因)互补;流程背景见 Calibre 物理验证实操,全簇索引见 开源 EDA 报错排错中心。
一句话总结
Calibre 退出码非零先分诊:抓 transcript 尾部致命行,码 1 按 deck、输入、license、PEX 四类点杀,130/137/143 是信号或调度系统杀作业、用 bhist -l 查 TERM 原因;最要紧的是 DRC 违例和 LVS INCORRECT 是检查结果而非工具失败,CI 要用退出码与违例计数双条件分别判定,wrapper 里开 pipefail 并 exit ${PIPESTATUS[0]} 把真实码透传到最外层。