在 Innovus 多线程实现流程中,偶尔会遇到以下连续报错并伴随工具崩溃:
1
2
3
4
5
6
job list is not empty:
**ERROR: (MEMPOOL-112): Memory error: no thread specific data,
mem_thread_init should be called in mem_thread_create (0:00 line 360 EINVAL #1)
**ERROR: (MEMPOOL-112): Memory error: id number is wrong(_thread_number)
in mem_thread_create (0:00 line 371 EINVAL #2)
Innovus terminated by internal (SEGV) error/signal
本文对该错误的来源、根因及修复方向进行系统梳理。
1. MEMPOOL-112 是什么
MEMPOOL 是 Cadence 底层内存池(Memory Pool)管理子系统的消息前缀,被 Innovus、Genus、Voltus、Xcelium 等多个工具共用。该子系统负责为每个线程分配和管理线程本地存储(TLS,Thread-Local Storage)中的内存块。
MEMPOOL-112 对应两种具体场景:
| 消息 | 含义 |
|---|---|
no thread specific data, mem_thread_init should be called in mem_thread_create |
某线程已被创建,但其 TLS 内存池从未初始化(缺少 mem_thread_init 调用) |
id number is wrong(_thread_number) in mem_thread_create |
线程编号无效,内存池无法找到对应的 TLS 槽位 |
两条错误接连出现,意味着线程池内部状态已经不一致,后续任何内存访问都可能触发 SEGV。
2. 根本原因分析
2.1 前置信号:job list is not empty
job list is not empty 是触发崩溃前的关键前置日志。它表明:上一个多线程命令(如 place_opt_design、optDesign 等)的工作线程池尚未全部回收,新的命令又尝试重建线程池,导致线程生命周期管理出现竞争。
2.2 MEMPOOL-112 的触发机制
Innovus 在多 CPU 模式下(由 setMultiCpuUsage 控制)会复用一个工作线程池。正常流程:
1
2
3
4
pthread_create(new_thread)
└─> mem_thread_init() ← 初始化该线程的 TLS 内存池
└─> 线程开始执行任务
└─> 任务结束,mem_thread_destroy() 释放 TLS
当线程池状态异常时(前一批任务未收尾、线程编号计数器溢出、或工具内部 bug),新创建的线程没有经过 mem_thread_init 就尝试使用内存池,立即报 MEMPOOL-112,随后 SEGV。
2.3 已知 Cadence Bug
在 Cadence ASK 的 INNOVUS21.17 Hotfix(Article 20498262)中,明确列有:
CCMPR02575911—place_opt_designrun aborts with ERROR MEMPOOL-112 using 64CPUs
该 CCR 已在 INNOVUS 21.1 ISR4 中修复。其触发条件与本文所描述的错误完全吻合:使用 setMultiCpuUsage -localCpu 64 时,place_opt_design 执行期间线程池状态异常,触发 MEMPOOL-112 并随即 SEGV。
此外,同类 SEGV 崩溃还包括:
CCMPR02300016—optDesign -postRoute -setup -hold期间 SEGV(INNOVUS21 早期版本)CCMPR02592614— Crash observed duringccopt_designCCMPR02431543—routeDesignSEGV due to poorly defined rc_cornerCCMPR02474522— SEGV on sroute for padPin
3. 排查与修复步骤
步骤 1:确认 Innovus 版本,优先升级
1
innovus -version
若版本低于 INNOVUS 21.1 ISR4,强烈建议升级。CCMPR02575911(place_opt_design 64 CPU MEMPOOL-112 崩溃)已在该版本中修复。升级后验证方式:重跑出错的 place_opt_design 步骤,确认不再出现 job list is not empty 前置日志。
步骤 2:降低并发线程数,隔离问题
1
2
# 从当前值逐步减少,定位是否为多线程竞争引起
setMultiCpuUsage -localCpu 2
若单线程或少线程下问题消失,基本确认为多线程竞争 bug,需要 hotfix。
步骤 3:检查系统进程资源限制
1
2
3
ulimit -u # 最大用户进程数,建议 >= 4096
ulimit -s # 栈大小,建议 unlimited
ulimit -a # 查看所有限制
若 ulimit -u 过小,操作系统会拒绝创建新线程,导致线程池状态异常。
步骤 4:排查 LD_PRELOAD 冲突
第三方内存分配器(如 tcmalloc、jemalloc)与 Cadence 内部 MEMPOOL 可能发生冲突:
1
2
3
4
env | grep LD_PRELOAD
# 若有自定义分配器,尝试临时取消
unset LD_PRELOAD
innovus -batch -files run.tcl
步骤 5:避免在任务列表非空时继续执行
job list is not empty 出现后不要强行继续。确认上一个命令是否有异步子任务(如分布式任务、-parallel 选项),等待其完成后再执行下一步。
步骤 6:提交 Cadence SR
若以上措施均无法解决,准备以下信息提交 Cadence 支持请求:
- 完整的
innovus.log(包含 SEGV 前的 stack trace) - 正在运行的 Tcl 命令(出错时执行的是哪条命令)
setMultiCpuUsage的设置- Innovus 版本号及操作系统版本
- 引用 CCR:CCMPR02575911(
place_opt_designMEMPOOL-112 using 64CPUs)
4. 小结
| 检查项 | 说明 |
|---|---|
| Innovus 版本 | 升级至 21.1 ISR4+,CCMPR02575911 已修复 64CPU 场景崩溃 |
setMultiCpuUsage |
尝试减少 CPU 数,隔离多线程竞争 |
ulimit -u / -s |
确保系统进程数和栈大小足够 |
LD_PRELOAD |
排查第三方内存分配器干扰 |
| 前置日志 | 注意 job list is not empty,等待任务收尾再继续 |
MEMPOOL-112 本质上是线程生命周期管理缺陷,通常由工具 bug 或资源不足触发,用户侧可操作的空间有限,尽快升级版本或联系 Cadence 是最可靠的解决路径。