nextpnr 段错误崩溃速查:Segmentation fault 与 Aborted 怎么办
更新时间:2026-10-23。FAQ 速查页,属于 FPGA 开源工具链报错排错系列。nextpnr 崩溃和商业工具不同:没有 Internal Error 横幅,往往只有 shell 一行
Segmentation fault (core dumped),外加dmesg里一条 segfault 记录,线索全靠自己挖。开源栈崩溃最常见的根子不是设计本身,而是工具链三件(yosys / nextpnr / chipdb 数据库)版本没对齐。同属崩溃类的上游问题见 Yosys 段错误崩溃速查,商业侧对照见 Quartus 崩溃/段错误速查。
本文要回答的问题
Segmentation fault和Aborted(assert 触发)怎么区分、各指向什么?- chipdb 与二进制版本不匹配为什么在跑了一半时才崩?
- yosys 输出的
.json里哪些结构会让 nextpnr 空指针崩溃? - 怀疑是
--placer heap/--router router2的老 bug,怎么快速验证? - 崩溃现场要留哪些信息,报 issue 才有人接?
一、报错原文与现象
1. shell 看到的标准场面:
nextpnr-ice40 --hx8k --package ct256 --json top.json --pcf top.pcf --asc top.asc
# ... Info: Packing constants..
# ... Info: Packing IOs..
Segmentation fault (core dumped)
echo $?
# 139 = 128+11 SIGSEGV,进程自己踩了空指针或越界2. Aborted 是另一档:nextpnr 内部 assert 或 C++ 异常没被接住。
terminate called after throwing an instance of 'nextpnr::assertion_failure'
what(): Assertion failed: bel != BelId() (chip.cc: place_error)
Aborted (core dumped)
# 退出码 134 = 128+6 SIGABRT3. 用 dmesg 拿崩溃地址,判断是工具崩还是被系统杀:
dmesg | tail -5
# nextpnr-ice40[8123]: segfault at 0 ip 0000557... sp 00007ff... error 4
# 或者:Out of memory: Killed process 8123 (nextpnr-ice40) —— 这是 OOM,不是段错误三行信息就能分流:退出码 137 或 dmesg 有 OOM 行是内存通道,先不用怀疑代码;139 是空指针/越界,进入版本对齐与输入合法性排查;134(Aborted)多半撞上了 nextpnr 内部断言,assert 消息里往往直接带源码文件名,这是查 issue 的黄金坐标。
二、现象 → 病因 → 处置速查表
| 现象 | 最常见病因 | 处置 |
|---|---|---|
| 刚升级了 yosys 或 nextpnr 其中一个就开始崩 | chipdb 与二进制版本不匹配:yosys 新版输出的 json 字段,旧 nextpnr 读不懂越界 | yosys、nextpnr 重新同一次构建同一份源码树;或整套回退到同一发布日快照 |
| 退出码 137,dmesg 有 OOM killed | 超大设计把 placer/router 的堆撑爆,或 WSL/容器限额太小 | 加内存/提限额;先用小设计验证;大设计考虑 --parallel-refine 之外的手工拆分 |
崩在 Packing 或 Placing 早期、assert 报 bel/cell 相关 | yosys 输出的 json 有非法结构:未例化黑盒、空模块、参数传歪 | yosys -p "read_verilog ...; hierarchy -check -top top" 先查黑盒;synth_ice40 重跑确认无 warning 升级 |
崩在 Constraining / 解析 pcf/lpf 阶段 | 约束文件引用了不存在的引脚名或拼错 package,映射越界 | 对照器件 pinout 表逐行核对 pcf/lpf;先注释一半约束二分定位 |
换 --router router2 就崩、默认 router1 正常 | 特定 pass 的已知缺陷(router2/heap placer 历史 bug 密度高) | 回默认算法;按报错文查 GitHub issue;升最新主干构建验证 |
| 含深嵌套 generate/递归参数的设计固定崩在同一位置 | 展开后层次过深触发工具链栈/容器极限 | 拆 generate 层级、把大 case 生成改查表;yosys 侧 flatten 后再喂 |
| 任何设计都崩、空工程也崩 | 构建损坏:混合链接了不同版本的 boost/库,或本机 ABI 不一致 | 干净目录全量重新 cmake/make;或用官方 oss-cad-suite 发行包 |
| 最小用例在最新主干仍崩 | 确属 nextpnr bug | 带最小 json、约束、版本号与 assert 原文提 GitHub issue |
三、排查决策流程
分诊顺序:先看退出码与 dmesg 分流,再查版本对齐,然后校验 yosys 输出与约束合法性,最后用换算法/最小化复现确认是不是工具 bug。图中颜色含义:红=崩溃入口,蓝=排查动作,绿=验证通过,橙=修复动作,紫=防复发。
读这张图抓住主线:红色入口先按退出码三路分流——137 走内存通道直接出绿,139/134 才进入「版本对齐 → 输入合法性 → 算法二分」的主链;每个橙色修复节点做完都必须回到绿色「流程跑通」验证,不通过就继续沿链条下沉,绝不跳步。 最常见的死法是没查版本对齐就先怀疑设计,绕一大圈才发现只是 apt 装的 nextpnr 和自己编的 yosys 差了半年。
四、逐条排查展开
版本对齐是第一嫌疑,检查只要一条命令。 开源栈里 yosys 输出的 .json 网表格式和 nextpnr 内置的 chipdb(芯片数据库)是强耦合的,两者由同一份 icestorm/trellis 数据生成。apt 装的 nextpnr 配源码新编的 yosys、或者换 yosys 忘了重编 chipdb,读 json 时字段对不上就直接越界段错误——而且往往跑到 Packing 才崩,极具迷惑性。验证方法:yosys 和 nextpnr 从同一份源码树同一 commit 重新构建,或者干脆整套换 oss-cad-suite 发行包(里面三件天然对齐)。对齐后还崩,才轮到设计本身。
Aborted 的 assert 消息是查 issue 的直达票。 形如 Assertion failed: ... (chip.cc: ...) 的输出行照抄原文(连同文件名与行号)去 nextpnr GitHub issue 搜索,已知 bug 命中率很高——开源社区报障都贴这段原文,翻译或转述反而搜不到。
yosys 侧先把输入洗干净。 未例化的黑盒模块、参数传歪后展开成空模块、synth_ice40 阶段就被跳过的 warning,都可能生成 nextpnr 消化不了的结构。标准动作:综合时加 hierarchy -check -top top 确认没有未解析模块;综合输出重扫一遍 warning,凡带 is used but has no driver、replacing memory 之类字样的逐条落实。json 本身可以用 python3 -m json.tool top.json 粗查完整性,截断的 json(上次崩溃留下的半截文件)也会让 nextpnr 直接崩。
约束文件二分定位引脚名。 pcf/lpf 里引脚名拼错、package 写成另一颗料(ct256 写成 bg121)时,nextpnr 查 chipdb 找不到对应 bel,越界就崩。做法:先整份注释掉,确认无约束能跑通;再按半分法放开,崩在哪半就在哪半继续收,三五轮锁定那一行。对照官方 pinout 表改回合法引脚名即可。
算法二分:回默认 placer/router1。 --placer heap 与 --router router2 是较新的实现,历史 bug 密度明显高于默认路径。崩了先去掉这两个开关跑默认,能过就基本确认是特定 pass 的问题——先用默认算法保住交付,再拿同样的输入去最新主干验证,修了就升,没修就是现成 issue 素材。
最小化复现与提单。 从设计顶层开始二分:注释一半例化、删一半约束,看崩溃点是否移动,收到「一个空顶层加一个 IP/模块就崩」为止。提 issue 带齐四样:nextpnr 版本字符串(nextpnr-ice40 --version,commit hash 不能省)、最小 json 与约束文件、assert/segfault 原文、运行环境(发行版与内存大小)。空泛的「跑着跑着崩了」没人接得住。设计规模本身撑爆内存的情况(大阵列 chip 全占满)则先参考 nextpnr 资源放不下速查 的降占用口径。
五、防复发纪律
- 工具链三件整套锁版本:yosys、nextpnr、chipdb 同一快照构建,升级一起升,CI 里固化 commit hash,不混装发行版包与自编件。
- 崩溃现场先归档再清理:退出码、dmesg 行、assert 原文、版本号、最小用例留档后再动环境。
- 约束文件进版本管理:pcf/lpf 走 git,改动有 diff 可查,package 切换时一次性核对 pinout。
- CI 定期跑最小冒烟工程:一个几行 Verilog 的空设计走完整流程,工具链版本漂移或构建损坏在真设计撞上之前先暴露。
- 新算法先在小设计上试:换 heap placer、router2 或新 snapshot 时先跑历史工程回归,崩了立即回默认路径,不带着疑问上生产设计。
一句话总结
nextpnr 段错误崩溃先拿退出码分流:137 加 dmesg OOM 行是内存耗尽被杀,去提限额加 swap;139/134 才是工具自身崩,第一嫌疑是 yosys 与 nextpnr 的 chipdb 版本没对齐,整套重新构建或换 oss-cad-suite;对齐后仍崩就依次重跑 yosys 加 hierarchy -check 洗 json、二分 pcf 核对引脚名、回默认 placer 与 router1 排除算法 bug,最后最小化复现带 assert 原文与版本号提 issue;防复发靠工具链整套锁版本与 CI 冒烟工程。