现象
xlings subos info 报:
⚠ nvidia EGL BROKEN — it carries DT_RUNPATH, which is not transitive, …
⚠ nvidia GLESv1 BROKEN — …
⚠ nvidia GLESv2 BROKEN — …
但对标签正确的消费者,这三个 vendor 是可以加载并跑在 GPU 上的。同一个 home、
同一个 interposer、同一台机器,只改消费者的 ELF 标签:
| 消费者标签 |
libEGL_nvidia.so.0 |
libGLESv2_nvidia.so.2 |
| DT_RUNPATH(0.0.57 之前的产物) |
打不开 |
打不开 |
| DT_RPATH(0.0.57 之后 elfpatch 打的) |
LOADED |
LOADED |
真实渲染同样如此(沙箱 + --gpu,发布件驱动):
| 探针标签 |
glx |
egl |
gles2 |
egl-surfaceless |
| DT_RUNPATH |
NVIDIA |
llvmpipe |
llvmpipe |
— |
| DT_RPATH |
NVIDIA |
NVIDIA |
NVIDIA |
NVIDIA |
为什么记录会这样说
graphics.vendor_closure_gaps 判的是 interposer 自己的标签:它带 DT_RUNPATH,
所以它背后的宿主驱动够不到我们的载荷。这个判断在 interposer 孤立看时是对的。
但加载器的规则是:消费者的 DT_RPATH 是传递的,当一个 DT_RPATH 的可执行文件打开这个
interposer 时,消费者的搜索路径对整条链都在作用域内,libpthread.so.0 因此可解析。
所以这个判定以消费者的标签为条件,而记录没有表达这个条件。
在 libxpkg 0.0.57(#41)之前,几乎所有已安装可执行文件都是 DT_RUNPATH,所以这个判定
在事实上是准确的。0.0.57 之后它不再准确 —— 已安装程序现在都是 DT_RPATH。
影响
面板低报能力:它告诉用户 EGL / GLES 坏了,而对正确打标签的程序它们是好的。
这比高报更隐蔽:一个报"坏"却其实能用的检查,会让人去修一个不存在的问题(我今天就
花了几小时在上面),并且会掩盖真正还坏着的那部分。
修法方向(未定)
判定必须表达"这取决于谁来打开它",可选:
- 探测时把传递路径纳入作用域 —— 用一个带 DT_RPATH 的探针去解析,即模拟一个正确
打标签的消费者。这样得到的答案就是"已安装程序会看到什么"。
- 或改变判定的语义 —— 不再说
broken,而是说 needs-transitive-consumer,
并在面板上区分"对已安装程序可用 / 对你自己构建的程序不可用"。
第二种更诚实,但它把 #532(构建侧标签)的状态暴露到每个用户面前,需要先想清楚
那句话怎么说才不制造新的困惑。
顺带:对账工具没抓到这个
.agents/tools/graphics-acceptance.sh 报"记录与加载器一致" —— 因为它自己的探针是
默认 dtags 编的,复现的正是记录描述的那个失败。这是它自己踩过两次的同一个坑的第三种
形态:测量工具与被测对象共享同一个错误假设时,它们会一致地错。
工具应当两种标签各测一遍,像 matrix.sh 的 tag differential 那样。
复现
# 同一个 home,同一个 interposer,只改消费者标签
gcc -o a probe.c -ldl # DT_RUNPATH
gcc -o b probe.c -ldl -Wl,--disable-new-dtags,-rpath,<subos>/lib:<nvidia载荷>
./a <nvidia载荷>/libEGL_nvidia.so.0 # cannot open shared object file
./b <nvidia载荷>/libEGL_nvidia.so.0 # LOADED
关联:#534(此前把这几格记为"原因未知"),#532(构建侧标签),openxlings/libxpkg#41
现象
xlings subos info报:但对标签正确的消费者,这三个 vendor 是可以加载并跑在 GPU 上的。同一个 home、
同一个 interposer、同一台机器,只改消费者的 ELF 标签:
libEGL_nvidia.so.0libGLESv2_nvidia.so.2真实渲染同样如此(沙箱 +
--gpu,发布件驱动):为什么记录会这样说
graphics.vendor_closure_gaps判的是 interposer 自己的标签:它带 DT_RUNPATH,所以它背后的宿主驱动够不到我们的载荷。这个判断在 interposer 孤立看时是对的。
但加载器的规则是:消费者的 DT_RPATH 是传递的,当一个 DT_RPATH 的可执行文件打开这个
interposer 时,消费者的搜索路径对整条链都在作用域内,
libpthread.so.0因此可解析。所以这个判定以消费者的标签为条件,而记录没有表达这个条件。
在 libxpkg 0.0.57(#41)之前,几乎所有已安装可执行文件都是 DT_RUNPATH,所以这个判定
在事实上是准确的。0.0.57 之后它不再准确 —— 已安装程序现在都是 DT_RPATH。
影响
面板低报能力:它告诉用户 EGL / GLES 坏了,而对正确打标签的程序它们是好的。
这比高报更隐蔽:一个报"坏"却其实能用的检查,会让人去修一个不存在的问题(我今天就
花了几小时在上面),并且会掩盖真正还坏着的那部分。
修法方向(未定)
判定必须表达"这取决于谁来打开它",可选:
打标签的消费者。这样得到的答案就是"已安装程序会看到什么"。
broken,而是说needs-transitive-consumer,并在面板上区分"对已安装程序可用 / 对你自己构建的程序不可用"。
第二种更诚实,但它把 #532(构建侧标签)的状态暴露到每个用户面前,需要先想清楚
那句话怎么说才不制造新的困惑。
顺带:对账工具没抓到这个
.agents/tools/graphics-acceptance.sh报"记录与加载器一致" —— 因为它自己的探针是默认 dtags 编的,复现的正是记录描述的那个失败。这是它自己踩过两次的同一个坑的第三种
形态:测量工具与被测对象共享同一个错误假设时,它们会一致地错。
工具应当两种标签各测一遍,像
matrix.sh的 tag differential 那样。复现
关联:#534(此前把这几格记为"原因未知"),#532(构建侧标签),openxlings/libxpkg#41