跳转至

SOP — 在 Rocky 9.8 上打通 Synopsys 2018 批次工具(31.28 / EDA-HPC)

  • 变更日期:2026-09-28
  • 执行主机:192.168.31.28(EDA-HPC,Rocky 9.8 / glibc 2.34 / 8 核 15G,TigerVNC :1~:4)
  • 触发来源:用户要求「数字设计全链路可用」,且明确不使用容器、环境全为 Rocky 9
  • 性质:C 类变更(系统包 + 兼容层 + 系统级 nsswitch 调整 + modulefile)
  • 结论:31.28 上全部工具打通(含 GUI 与 SpyGlass 命令行 lint,见 §10);六台 work 节点已幂等推广完成(见 §9)

目录:1 背景 · 2 目标 · 3 前置条件 · 4 影响范围 · 5 分步操作 · 6 验证 · 7 回滚 · 8 风险 · 9 六台推广 · 10 SpyGlass 打通 · 附录 A/B

1. 背景

Synopsys 2018 批次工具(2018.06 / 2017.12)官方支持 RHEL 7 世代,而本环境全为 Rocky 9.8(glibc 2.34)。工具在该宿主上启动失败,原因有三层,逐一定位:

# 现象 根因
1 libpthread.so.0: version 'GLIBC_PRIVATE' not found glibc ≥2.34 把 libpthread 并入 libc,不再导出 __pthread_unwind@GLIBC_PRIVATE,而老工具的 DT_VERNEED 要求该版本
2 tools/.../shlib/libz.so.1: version 'ZLIB_1.2.9' not found (required by /lib64/libpng16.so.16) 工具自带的老 zlib 抢先加载,系统 libpng16 需要新版符号
3 MEM Error / Segmentation fault(仅 pt/pwr) 崩在 glibc 2.34 的 nss-myhostname 模块(getaddrinfo → _nss_myhostname_gethostbyname_r),由 /etc/nsswitch.conf 的 hosts 行触发

另有 SpyGlass 两项独立问题,均在 2026-09-29 定位并解决(详见 §10):

# 现象 根因
4 INTERNAL-ERROR ... the Perl 5 installation within $SPYGLASS_HOME could not be validated 工具用 uname -sr 判定平台,只识别 Linux-2/3/4;Rocky 9 是 Linux 5.14 → species=UNKNOWN。且工具内部会把 PATH 重建为 …/usr/local/bin:/usr/bin:/bin:$SAVE_PATH,使 modulefile 里 PATH 前置的 uname 包装被绕过
5 obj/check.Linux4: symbol lookup error: /usr/lib64/libfontconfig.so.1: undefined symbol: FT_Get_Advance(Exit 127) 工具把自带的 dotty/lib/Linux4(含 freetype 2.3.7)塞进 LD_LIBRARY_PATH,系统 libfontconfig 需要的 FT_Get_Advance 在老 freetype 中不存在

2. 目标

  1. 31.28(submit/GUI 节点)上:数字设计主链路工具命令行与 GUI 均可用。
  2. 以 modulefile 作为统一入口(用户既定方式),一次 module load 完成环境准备。
  3. 不改工具树(NFS 只读)、不改系统 glibc、不引入容器。

3. 前置条件

  • 31.28 已挂载 /tools(ro)、/opt/modulefiles(rw)、/pdk;TigerVNC 桌面可用。
  • license:2700@192.168.31.29(Synopsys snpslmd,systemd 托管)。
  • Rocky 9 自带源 + EPEL 可用;需能访问 mirrors.aliyun.com/centos-vault/6.10(取 el6 老库)。
  • 编译 shim 需要 gcc:31.28 原本没有,在 31.30(CentOS 7.2,gcc 4.8.5)编译后传输(产物 glibc 需求最低,便于跨版本加载)。
  • 备份与留档:backup/README.md。

4. 影响范围

项 说明
主机 仅 192.168.31.28;六台 work 节点未做改动
是否停服 否。变更前后均确认:负载 0.1、Slurm/LSF 无作业、VNC 会话(18 个 590x 监听)全程正常
变更面 ① 系统包(ncurses-compat-libs、libpng12、cpio、gdb);② /opt/compat/(3 个 el6 库 + shim + uname 包装);③ /etc/ld.so.conf.d/compat-layer.conf;④ /etc/nsswitch.conf(hosts 行去掉 myhostname);⑤ NFS 共享 /opt/modulefiles/synopsys_compat/;⑥ modulefile /opt/modulefiles/synopsys/eda2018/1.0.lua
⚠️ 系统级改动 nsswitch.conf 影响全机主机名解析(详见第 8 章风险)
轮次 无需停服;ldconfig 期间对新进程库解析有毫秒级影响

5. 分步操作

步骤 1:补系统库(Rocky 9 / EPEL)

工具树自带 Qt5、ICU、tbb、libstdc++(在各产品 amd64/*/shlib/),系统侧只需补少量包。其中 libpng12 在 EPEL 里有(1.2.57-18.el9),无需老源。

ssh root@192.168.31.28 'dnf install -y ncurses-compat-libs libpng12 cpio gdb'

预期:rpm -q ncurses-compat-libs libpng12 均有版本号。 失败判断:非 0 → 检查 EPEL 是否启用(dnf repolist)。

步骤 2:补 el6 老库(Rocky 9 已不提供)

libtiff.so.3(DC/StarRC 需要)、libmng.so.1、liblcms.so.1(DC/wv/siliconsmart 共性依赖)在 Rocky 9 中只有 .so.5 / 无 / 只有 lcms2。

坑:lcms 主包只含命令行工具,库在 lcms-libs 子包。

ssh root@192.168.31.28 'mkdir -p /opt/compat/lib64 /tmp/el6rpms && cd /tmp/el6rpms
B=https://mirrors.aliyun.com/centos-vault/6.10/os/x86_64/Packages
for f in libtiff-3.9.4-21.el6_8.x86_64.rpm libmng-1.0.10-4.1.el6.x86_64.rpm lcms-libs-1.19-1.el6.x86_64.rpm; do
  [ -f "$f" ] || curl -sf -O "$B/$f"
done
for r in *.rpm; do rpm2cpio "$r" | cpio -idmu --no-absolute-filenames -d; done
cp -a usr/lib64/libtiff.so.3* usr/lib64/libmng.so.1* usr/lib64/liblcms.so.1* /opt/compat/lib64/
echo "/opt/compat/lib64" > /etc/ld.so.conf.d/compat-layer.conf && ldconfig'

预期:ldconfig -p | grep -E "libtiff.so.3|libmng.so.1|liblcms.so.1" 三条均指向 /opt/compat/lib64。

步骤 3:制作 libpthread 版本声明 shim

原理:老工具要求 libpthread.so.0 提供 GLIBC_PRIVATE 等版本;glibc 2.34 的空壳不提供。我们提供一个同名(SONAME)小库,只声明这些版本名(符号由系统 libc 解析),从而通过版本检查。

坑 1:必须设 -Wl,-soname,libpthread.so.0,否则 ld.so 不认它顶替同名库,版本检查仍指向 /lib64。 坑 2:版本名要列全(工具对 libpthread 的版本需求不止一个,实测含 GLIBC_2.2.5/2.3.2/2.3.3/2.3.4/2.12 等),漏一个就继续报错。 坑 3:绝不能放进被 ldconfig 扫描的目录(会顶替全系统的 libpthread);本方案放在 libexec/,仅在加载 module 时经 LD_PRELOAD 注入。

# 在 31.30(有 gcc)编译
ssh root@192.168.31.30 'cd /tmp/shim2; VERS="2.2.5 2.2.6 2.3 2.3.2 2.3.3 2.3.4 2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 2.14 2.15 2.16 2.17 2.18 2.22 2.23 2.24 2.25 2.26 2.27 2.28 2.29 2.30 2.31 2.32 2.33 2.34"
for v in $VERS; do s="__cd_$(echo $v | tr . _)"; printf "void %s(void){}\n" "$s" >> s.c; printf "GLIBC_%s { global: %s; };\n" "$v" "$s" >> v.map; done
printf "GLIBC_PRIVATE { global: __cd_private_dummy; };\n" >> v.map; printf "void __cd_private_dummy(void){}\n" >> s.c
gcc -shared -fPIC -Wl,-soname,libpthread.so.0 -Wl,--version-script=v.map -o libpthread.so.0 s.c'
# 传到共享位置(下列路径在客户端为 /opt/modulefiles/...)
scp root@192.168.31.30:/tmp/shim2/libpthread.so.0 /tmp/ && scp /tmp/libpthread.so.0 root@192.168.31.28:/opt/modulefiles/synopsys_compat/libexec/libpthread.so.0

预期:readelf --version-info 显示 GLIBC_PRIVATE 等版本定义齐全,且 readelf --dyn-syms 不再出现 __pthread_unwind(它是弱引用,找不到即为 NULL,工具按"没有就算了"处理)。

说明:早期版本曾让 shim 实现 __pthread_unwind 空函数,实测对 dc/icc2 无害但对诊断无益;最终采用"只声明版本、不提供实现",更贴近工具对弱符号的预期。

步骤 4:装 uname 包装(SpyGlass 平台探测用)

SpyGlass 用 uname -sr 匹配平台,只认到 Linux-2/3/4;Rocky 9 是 Linux-5.14-… → species=UNKNOWN → 报 the Perl 5 installation ... could not be validated 并 exit 1。

坑(2026-09-29 修正):工具内部会把 PATH 重建为 $SPYGLASS_HOME/{obj,bin}:/usr/local/bin:/usr/bin:/bin:$SAVE_PATH (见 lib/SpyGlass/standard-environment.sh),/usr/bin 排在原始 PATH 之前 —— 因此只做 PATH 前置无效,包装必须落在 /usr/local/bin(sys_bpath 首段,优先于 /usr/bin)。同一份制品两个位置都用。

包装带开关:仅当 EDA_COMPAT_FAKE_UNAME=1(由 modulefile 设置)时才伪造 uname -sr,否则原样透传,避免影响系统其它脚本。

# 制品源:本主题 artifacts/compat-uname.sh(sha256 75ce4fd4f80a5cd4013d2c0e6bb130fec50d94ccf207f130836b08a72be3f163)
ssh root@192.168.31.28 'install -m 0755 /opt/modulefiles/synopsys_compat/bin/uname /usr/local/bin/uname'

预期:EDA_COMPAT_FAKE_UNAME=1 /usr/local/bin/uname -sr → Linux 4.18.0-513.el8.x86_64;不设该变量时输出真实 Linux 5.14.0-…。 实现体:六台节点由部署工程同步(config/rollout.yaml 的 shims[uname_syslocal]),见 §10。

步骤 5:调整 /etc/nsswitch.conf(⚠️ 系统级)

这是 pt/pwr 能起来的关键。glibc 2.34 的 nss-myhostname 模块在该场景下段错误(backtrace 见第 6 章),把 myhostname 从 hosts 行移除即可。

ssh root@192.168.31.28 'TS=$(date +%Y%m%d-%H%M%S); cp -a /etc/nsswitch.conf "/etc/nsswitch.conf.bak.$TS"
sed -i "s/^hosts:.*/hosts:      files dns/" /etc/nsswitch.conf
grep "^hosts" /etc/nsswitch.conf'

预期:hosts: files dns;getent hosts $(hostname) 仍能解析(由 files 提供)。

步骤 6:写 modulefile(统一入口)

放到 Lmod 层级树的工具层(先 module load synopsys 展开家族)。

# 文件内容见仓库:rocky9_eda_compat_20260928/docs/eda2018-1.0.lua
scp rocky9_eda_compat_20260928/docs/eda2018-1.0.lua root@192.168.31.28:/tmp/eda2018.lua
ssh root@192.168.31.28 'mkdir -p /opt/modulefiles/synopsys/eda2018 && cp /tmp/eda2018.lua /opt/modulefiles/synopsys/eda2018/1.0.lua'

预期:module load synopsys && module load eda2018/1.0 无报错。 失败判断:unknown module → 确认先 load 了 synopsys(MODULEPATH 由 Core/synopsys.lua 注入)。

6. 验证

6.1 一键加载实测(31.28)

ssh root@192.168.31.28 'bash -lc "module load synopsys && module load eda2018/1.0
  echo \$SNPSLMD_LICENSE_FILE \$VCS_USE_MALLOC \$LD_PRELOAD
  which dc_shell pt_shell icc2_shell fm_shell verdi
  cd /tmp && echo exit | dc_shell | head -3"'

实测结果:环境变量正确注入;7 个命令全部定位;dc_shell 打印 Design Compiler Graphical;pt_shell 交互返回 PT-MODULE-OK。

6.2 工具矩阵(31.28 / Rocky 9.8 / keygen license)

工具 类型 结果
verdi GUI ✅ 已在 VNC 桌面实际显示
vcs-mx 仿真 ✅ 编译+仿真(依赖 VCS_USE_MALLOC=1)
dc_shell(Design Compiler) 综合 ✅
icc2_shell(IC Compiler II) 布局布线 ✅
pt_shell(PrimeTime) 时序 ✅ 交互实测
pwr_shell(PrimePower) 功耗 ✅
lc_shell(Library Compiler) 库编译 ✅
fm_shell(Formality) 形式验证 ✅
StarXtract(StarRC) 寄生提取 ✅
siliconsmart 库表征 ✅
hspice 模拟仿真 ✅(真仿真跑通,在 31.30 上;31.28 上待复测)
tmax / custom_compiler / wv / synplify / identify 其它 ✅ 命令行启动正常
spyglass lint ✅ 真实 lint 跑通(Exit Code 0,见 §10)

6.3 关键取证:pt 的崩溃栈(定位到 nss-myhostname)

__libc_start_main → … → getaddrinfo → gethosts
  → _nss_myhostname_gethostbyname3_r → _nss_myhostname_gethostbyname_r
  → malloc_usable_size → __sigaction → Segmentation fault

移除 myhostname 后同一命令正常进入 pt_shell>;pwr_shell 同步恢复。

6.4 幂等复跑

动作 第二次执行结果
dnf install(步骤 1) 全部「已安装,无事可做」
cp -a 到 /opt/compat/lib64 覆盖同名文件,内容一致
ldconfig 幂等
module load(步骤 6) 重复加载报「已加载」/无变更

7. 回滚

# 回滚 1:nsswitch(系统级,最需优先恢复)
ls /etc/nsswitch.conf.bak.*            # 选择变更前的那份
cp -a /etc/nsswitch.conf.bak.<TS> /etc/nsswitch.conf

# 回滚 2:module 层(摘掉入口,工具随之不可用)
rm -f /opt/modulefiles/synopsys/eda2018/1.0.lua

# 回滚 3:兼容层(不影响已装系统包)
rm -rf /opt/compat/lib64/libpthread.so.0 /opt/compat/bin/uname
rm -rf /opt/modulefiles/synopsys_compat
rm -f /etc/ld.so.conf.d/compat-layer.conf && ldconfig

# 回滚 4(可选,高危):移除本次安装的系统包
dnf remove -y ncurses-compat-libs libpng12 cpio gdb

回滚验证:ldconfig -p | grep libtiff.so.3 无输出;module load synopsys && module load eda2018/1.0 报模块不存在;getent hosts $(hostname) 正常。 回滚触发判据:主机名解析异常(登录变慢、getent 失败)→ 执行回滚 1;工具无法启动 → 回滚 2/3。 备份台账:backup/README.md(含 nsswitch.conf 备份文件路径)。

8. 风险说明

风险 缓解
⚠️ /etc/nsswitch.conf 去掉 myhostname 影响全机 主机名解析仍由 files(/etc/hosts)兜底;变更前已备份;出现解析异常立即回滚 1。这是本方案最需知情的一项
LD_PRELOAD 顶替 libpthread.so.0 shim 只声明版本、不提供实现,符号仍由系统 libc 解析 —— 对普通程序行为等价于系统空壳 libpthread;且仅在加载该 module 的会话内生效,建议不写入默认环境
工具自带老 zlib 被系统 libz 覆盖 zlib ABI 长期稳定;实测 dc/pt/icc2/lc/fm 均正常
shim 放在 NFS 共享目录,多机共用 单一副本便于维护;NFS 不可用时 module 会明确报错(isDir 守卫)
六台 work 节点尚未推广 需在各节点重复步骤 1~5(步骤 6 的 modulefile 已共享);注意每台都要处理 nsswitch.conf
SpyGlass 依赖两处配套改动 /usr/local/bin/uname(EDA_COMPAT_FAKE_UNAME 开关)+ modulefile 的 SG_CONSOLE_SE=1;不经 module 直接调用工具树命令会复现原报错,属预期,见 §10

9. 推广到六台 work 节点(2026-09-29,工程化实现)

六台计算节点(.18/.19/.20、.25/.26/.27)的变更不再逐台手工执行,由本主题下的部署工程幂等推广(多主机变更按规范以工程承载)。

9.1 工程位置与用法

工程根:rocky9_eda_compat_20260928/(与 docs/、backup/ 同级),按共享库契约建成 (共享库 /home/rain/py_public_modules,经 .venv 的 .pth 挂载)。

cd rocky9_eda_compat_20260928
.venv/bin/python main.py --config config/rollout.yaml precheck            # 只读门禁(配置校验 + 环境预检查)
.venv/bin/python main.py --config config/rollout.yaml --dry-run rollout   # 零改动预演
.venv/bin/python main.py --config config/rollout.yaml rollout             # 分批变更
.venv/bin/python main.py --config config/rollout.yaml drift               # 只读漂移检测
  • 分批:rollout.batch.size=2;批内失败超 max_failures=1 即停止后续批次并回滚本批;
  • 幂等:探测三态 done/pending/unknown,unknown 一律中止(不把探测失败当作需要变更);
  • 制品来源:NFS 共享 /opt/modulefiles/synopsys_compat(shim、uname 包装、el6 库),一处维护、多机共用;
  • 报告与日志:reports/precheck-*.md、reports/plan-*.yaml、reports/drift-*.md、logs/。

9.2 实测结果

阶段 结果
门禁(precheck) 六台全部通过:SSH / root / OS 9.8 / 内核 / NTP / SELinux / 磁盘 / /tools 挂载 / 共享制品 / license 端口
预演(dry-run) 变更清单正确;实机零改动(已抽查 /etc/nsswitch.conf 未变)
变更(rollout) 六台 success;.18 已具备跳过,其余五台装包 + 同步制品 + 改 nsswitch + ldconfig
工具能力验证 六台 dc_shell 均输出 Design Compiler
幂等复跑 skipped(零变更)
漂移检测 无漂移(退出码 0)
节点抽查(.18) dc_shell / pt_shell / icc2_shell / lc_shell / fm_shell / pwr_shell / verdi 全部可用

9.3 推广中暴露并修正的两个真实坑

  1. ldconfig 必须显式执行:.18 的 /etc/ld.so.conf.d/compat-layer.conf 在 VCS 时期就已配好, 探测判 done 后不会重写配置,于是出现"库已落盘、ld.so 缓存未更新" → error while loading shared libraries。 已把 ldconfig 固化为每次变更的收尾动作(幂等、开销小)。
  2. 包必须限定架构:.19 等节点已装 i686 版 libXScrnSaver,rpm -q libXScrnSaver 判为"已装", 但 64 位 libXss.so.1 仍缺失。配置中改为 libXScrnSaver.x86_64 后通过。

9.4 六台的系统级改动

六台的 /etc/nsswitch.conf hosts 行同样移除了 myhostname(与 31.28 同理), 变更前由工程自动备份为 /etc/nsswitch.conf.bak.<时间戳>;台账见 backup/README.md。

10. SpyGlass 打通(2026-09-29 追补)

10.1 背景与根因

SpyGlass_vN-2017.12-SP2 是 31.28 上最后一个未通的工具。原记录写作"perl 包装的平台校验链仍未通过",实测应拆成两层障碍:

  1. 平台探测:lib/SpyGlass/standard-environment.sh 的 platform_species() 用 uname -sr 匹配 Linux-2/3/4*;Rocky 9 返回 Linux-5.14… → species=UNKNOWN → lib/multi-perl/obj/$species 目录校验失败 → INTERNAL-ERROR ... the Perl 5 installation ... could not be validated。 关键坑:同一脚本第 1410 行会把 PATH 重建为 $SPYGLASS_HOME/{obj,bin}:$user_bpath:/usr/local/bin:/usr/bin:/bin:$SAVE_PATH —— /usr/bin 排在调用者 PATH 之前,所以此前"PATH 前置 uname 包装"的做法在工具内部完全失效(实测工具内 command -v uname = /usr/bin/uname,输出真实 5.14)。
  2. 运行期库冲突:平台校验通过后,obj/check.Linux4 报 symbol lookup error: /usr/lib64/libfontconfig.so.1: undefined symbol: FT_Get_Advance(Exit 127)。 根因:standard-environment.sh:1711-1715 把工具自带的 dotty/lib/Linux4(含 freetype 2.3.7,无 FT_Get_Advance)放进 LD_LIBRARY_PATH 首段,系统 libfontconfig 因而解析不到所需符号。

两点反证(均实测): - SKIP_PLATFORM_CHECK=1(工具内置、.platform_check.sh 自提示的开关)无效 —— 它只管发行版校验(/etc/centos-release 版本匹配),与 species 推导无关; - LD_PRELOAD 系统 libfreetype 无效 —— 老 freetype 仍被加载,只有让 dotty/lib/Linux4 不出现在 LD_LIBRARY_PATH 才解决。

10.2 变更点

项 位置 内容
uname 包装(改) /opt/modulefiles/synopsys_compat/bin/uname(NFS 共享;制品源 artifacts/compat-uname.sh) 加开关:仅 EDA_COMPAT_FAKE_UNAME=1 时伪造 uname -sr,否则透传
uname 包装(新增位置) 各机 /usr/local/bin/uname 同一份制品;该路径属 sys_bpath 首段,绕不过
modulefile /opt/modulefiles/synopsys/eda2018/1.0.lua(NFS) 新增 setenv("EDA_COMPAT_FAKE_UNAME","1")、setenv("SG_CONSOLE_SE","1")

SG_CONSOLE_SE=1 是厂商自带开关(bin/sg_shell:203 自身即设置它),作用是令 DOTTY_LIBRARY_PATH 为空(standard-environment.sh:1712),从而不再引入老 freetype;副作用是启用工具自带 jemalloc(spyglass_main:878)。

10.3 步骤

# 1) 更新 NFS 上的制品与 modulefile(操作机 192.168.31.249 即 NFS server)
sudo install -m 0755 artifacts/compat-uname.sh /data/nfs/modulefiles/synopsys_compat/bin/uname
sudo install -m 0644 docs/eda2018-1.0.lua  /data/nfs/modulefiles/synopsys/eda2018/1.0.lua

# 2) 31.28(母机,非工程管理节点)手工落 /usr/local/bin
ssh root@192.168.31.28 'install -m 0755 /opt/modulefiles/synopsys_compat/bin/uname /usr/local/bin/uname'

六台 work 节点由部署工程同步(config/rollout.yaml 新增 shims[uname_syslocal],目标 /usr/local/bin/uname),modulefile 在 NFS 共享、无需分发。

预期:module load synopsys && module load eda2018/1.0 后 echo $EDA_COMPAT_FAKE_UNAME $SG_CONSOLE_SE → 1 1。

10.4 验证

# 最小项目:top.v(4bit 计数器 + 1 根悬空 wire)+ s.prj(read_file / set_option / current_methodology)
ssh root@192.168.31.28 'bash -lc "module load synopsys && module load eda2018/1.0
  cd /tmp/sgtest && spyglass -project s.prj -batch -goals \"lint/lint_rtl\" | tail -20"'

实测(31.28 / .18 / .25 三处一致):

项 结果
spyglass -version SpyGlass_vN-2017.12-SP2;对照:不设 SG_CONSOLE_SE 时 Exit 127
真实 lint Goal Run: lint/lint_rtl、0 Fatals, 0 Errors, 0 Warnings, 2 Infos、SpyGlass Exit Code 0 (Rule-checking completed without errors or warnings),并生成 consolidated_reports/、html_reports/goals_summary.html
六台推广 幂等复跑 skipped、漂移检测 0;.18 / .25 抽查 lint 通过

命令行备忘:-batch 必须与 -goals "<goal>" 同用(单独 -batch 只打印用法);goal 名用 -showgoals 查得(如 lint/lint_rtl);项目文件里写 current_goal <goal> 的 goal 名须与方法学路径严格一致,容易踩 null value passed in current_goal,用 -goals 更省事。

10.5 回滚

# 1) 摘除 /usr/local/bin 包装(31.28 与六台)
for h in 28 18 19 20 25 26 27; do ssh root@192.168.31.$h 'rm -f /usr/local/bin/uname'; done

# 2) 还原 uname 制品与 modulefile(本主题 backup/,登记见 backup/README.md)
sudo cp -a backup/data/nfs/modulefiles/synopsys_compat/bin/uname.bak.20260929-002439 \
           /data/nfs/modulefiles/synopsys_compat/bin/uname
sudo cp -a backup/data/nfs/modulefiles/synopsys/eda2018/1.0.lua.bak.20260929-002439 \
           /data/nfs/modulefiles/synopsys/eda2018/1.0.lua

回滚触发判据:若其它工具(dc/pt/vcs/verdi…)出现异常,优先执行 2)(modulefile 是全局影响面);仅 SpyGlass 需要退回时执行 1)。 回滚后验证:module load synopsys && module load eda2018/1.0 && dc_shell 正常;spyglass -version 复现 §1 表中第 4 项报错。

10.6 风险说明

风险 缓解
/usr/local/bin/uname 成为全机 uname 的优先版本 包装默认完全透传,仅当 EDA_COMPAT_FAKE_UNAME=1(modulefile 设置)时伪造 uname -sr;未加载 module 的进程行为不变
SG_CONSOLE_SE=1 改变 SpyGlass 运行模式 该变量为厂商内置(bin/sg_shell:203 自身设置),真实 lint 已实测通过;GUI(-ispy)亦已实测可启动,见 §10.7。附带效果:standard-environment.sh 在 SE 模式下关闭 ptmalloc/jemalloc(:792、:868,注释明示为避免 dotty 崩溃),并不注入 dotty/lib/Linux4(:1712)
32 位子进程的 LD_PRELOAD 告警 ld.so: object … wrong ELF class: ELFCLASS64 … ignored 属既有现象(工具含 32 位子进程),不影响功能,本次未处置

10.7 GUI(-ispy)验证(2026-09-29)

31.28 上以 DISPLAY=:1(rain01 的 TigerVNC)、module load synopsys && module load eda2018/1.0 环境实测:

项 结果
启动命令 cd /tmp/sgtest && spyglass -project sg.prj -ispy
进程链 spyglass → sg_shell -gui=se --intrnl_gui_se → spyglass -batch -nl -gui=se -ispy → spyglass_main → obj/ipcServer.Linux4 + obj/check.Linux4;存活至 timeout 到期(rc=124),无崩溃
库层 无 FT_Get_Advance / symbol lookup error;ldd obj/check.Linux4 只解析到系统 /lib64/libz.so.1
图形态 check.Linux4 进入 GTK 初始化,X 会话建立并发生绘图调用(X_CopyArea 逾 100 次)

三点机制结论:

  1. 该版 SpyGlass 没有 dotty GUI 后端:bin/sg_shell 只处理 -gui|-gui=se(:199)与 --verdi|-gui=verdi(:275)。-ispy 走的是 SE GUI(GTK)——即"传统 dotty GUI"在本版本的实际形态;dotty/bin/Linux4 下的 dotty/lefty 全程未启动。
  2. bin/sg_shell:203 自身 export SG_CONSOLE_SE=1,故外部 unset SG_CONSOLE_SE 无效:实测 unset 后表现与设置时完全一致(同样无库错误、同样逾百次 X Error)。
  3. 因此 §10.6 中「让 dotty/lib/Linux4 不出现在 LD_LIBRARY_PATH」这一取舍不影响 GUI 可用性——SE GUI 不依赖那批老库。

遗留渲染告警(不影响功能,本次未处置):GTK 主题 pixmap 加载失败 —— Failed to load image …/themes/Adwaita/gtk-2.0/assets/progressbar-horz-trough.png: bad parameters to zlib(libpng 报错),随之出现 109–128 次 X Error: BadDrawable (X_CopyArea)。属视觉瑕疵与日志噪声,未见功能中断。 可选治理方向(未验证):GTK2_RC_FILES 换用不含 PNG pixmap 的 GTK 主题,或 GDK_PIXBUF_MODULE_FILE 指向系统 loaders.cache。

无害噪声:lib/multi-perl/bin/perl: line 14: lsb_release: command not found(发行版探测脚本,不影响运行)。

未做:窗口内容完整性的目视确认 —— 31.28 上 import/xwd/scrot 均未安装,无法自动抓屏,需在 VNC 会话中人工确认一次。 副作用提示:验证期间在 rain01 的 :1 桌面短暂弹出过 SpyGlass 窗口(每次约 45–60 s,由 timeout 自动清理)。

附录 A:交付物清单

文件 说明
docs/SOP.md 本文件
docs/eda2018-1.0.lua modulefile 正式副本(部署到 /opt/modulefiles/synopsys/eda2018/1.0.lua)
main.py / deployer.py / utils/ 六台推广工程:门禁、幂等三态、分批、回滚、只读漂移检测
config/rollout.yaml.example 工程配置样例(包清单、制品来源、批次参数)
artifacts/compat-uname.sh uname 包装制品源(带 EDA_COMPAT_FAKE_UNAME 开关;部署到 NFS 与各机 /usr/local/bin)
backup/README.md 备份台账(含六台 nsswitch 备份登记、§10 的 uname/modulefile 备份)

附录 B:取证留痕

  • 时间窗:2026-09-28 22:40 — 23:35;§10.7 GUI 验证 2026-09-29 01:11 — 01:20
  • §10.7 取证方式:ssh root@192.168.31.28,DISPLAY=:1 XAUTHORITY=/home/rain01/.Xauthority,日志 /tmp/sgtest/ispy_run{,2,_c,_nose}.log;所有远程命令以 timeout 包裹
  • 主机:操作机 192.168.31.249 → 目标 192.168.31.28;编译辅助机 192.168.31.30
  • 关键证据:gdb backtrace(pt_shell,见 6.3)、/tmp/shim2/{s.c,v.map}(shim 源码)、/tmp/el6rpms/(el6 包)
  • 每步执行均以 timeout 包裹;GUI 测试进程用进程组信号清理(kill -TERM -<pgid>)

11. 兼容层位置迁移与模块别名(2026-10-05)

交接单 eda_tools_ins/docs/LMOD-CROSS-PROJECT-TODO.md 第 2 节 C-1/D 的落地(本工程部分):

  • C-1:兼容层由 /opt/modulefiles/synopsys_compat(NFS module 树内的非模块目录)迁至 节点本地 /opt/compat(与 el7 binutils 统一;实测六台 + .28 已含全部制品)。 docs/eda2018-1.0.lua 的 compat 改指 /opt/compat、守卫改 isFile(compat .. "/libexec/libpthread.so.0"),并移除 PATH 前置——/opt/compat/bin 含 el7 ld/ar/as,整目录前置会污染所有 eda2018 会话;uname 实际靠各机 /usr/local/bin/uname。
  • 制品源:迁入本工程 artifacts/share/(bin/uname、libexec/libpthread.so.0、 lib64/{libtiff.so.3,libmng.so.1,liblcms.so.1})。部署工程新增配置 compat_share_local (config/rollout.yaml 设为 true):源在操作机 → 探测走 utils/eda_state.py::local_src_sha_state()(本地算 sha256)、同步走上传(ssh.upload + 远端 chmod)。
  • D(本工程侧):docs/eda2018-.modulerc.lua 提供 module_version("eda2018/1.0", "2018"), 部署到 /opt/modulefiles/synopsys/eda2018/.modulerc.lua。
  • 验证:六台 --dry-run rollout 显示「状态一致」零变更;.18 module load eda2018/1.0 与 eda2018/2018 均正常,dc_shell 定位、spyglass -version Exit Code 0;模块树语法自检 No errors found。制品同步幂等复跑(--dry-run)零变更。
  • 完整变更档案(背景 / 影响范围 / 分步 / 验证 / 回滚 / 风险): eda_tools_ins/lmod_cross_project_fix_20261005/SOP.md 附录 C。

来源:/home/rain/Documents/eda_tools_ins/Synopsys/rocky9_eda_compat_20260928/docs/SOP.md | 最后更新:2026-10-05 17:32(由 build/sync.py 同步,请勿在站点侧修改)