0

我写了一条规则来运行一些编译器(Synopsys VCS MX)。运行单个目标时,一切正常。同时运行多个目标时,编译器会遇到分段错误。运行 Bazel 时不会发生这种情况--spawn_strategy=local。也设置--jobs 1工作。

我能想到的唯一原因是编译器尝试使用绝对路径写入文件,与自身的其他实例发生冲突。

我的问题如下:

  1. 如果我的理论是正确的,那么无论我是否在沙盒中,问题都不会发生吗?
  2. 如果我错了,如果不是因为某些共享文件,编译器怎么会发生冲突?
  3. 假设对于每个沙箱,我想挂载一个/tmp指向不同目录的,这可能吗?

更新:根据我在 中看到的strace,编译器的两个实例都打开一个文件/tmp/vcs_20200428163636_3/v710_tok进行读写,并且在某些时候一个实例调用pread64()会导致段错误。注意文件名,它看起来很可疑,就像暗示试图获取唯一文件名的日期一样,但两个实例的执行距离不够远。

问题 1 和 3 仍然有效。

4

1 回答 1

0

解决方案:

通过添加--sandbox_tmpfs_path=/tmp问题解决了。这告诉 Bazel,在为操作创建沙箱时,它应该挂载一个空的可写目录,该目录挂载到 path /tmp。这样每个编译器都有自己的/tmp,它们不会发生冲突。

为什么只有在沙盒时才会发生碰撞?

在沙箱中执行 run_shell 时,Bazel 将使用clone执行 shell ,这会导致它在新的PID 命名空间中运行。编译器的 PID(本例中为 3,如 中所示/tmp/vcs_20200428163636_3/v710_tok)被添加到在 中打开的文件中/tmp,以尝试使文件名唯一。但是,由于两个编译器都在各自的沙箱 PID 命名空间中分叉,因此它们都可以看到相对于其沙箱的 PID,从而允许它们发生冲突。

于 2020-04-29T09:38:01.257 回答