bazel - 如何防止 Bazel 中并发作业的分段错误?
问题描述
我写了一条规则来运行一些编译器(Synopsys VCS MX)。运行单个目标时,一切正常。同时运行多个目标时,编译器会遇到分段错误。运行 Bazel 时不会发生这种情况--spawn_strategy=local
。也设置--jobs 1
工作。
我能想到的唯一原因是编译器尝试使用绝对路径写入文件,与自身的其他实例发生冲突。
我的问题如下:
- 如果我的理论是正确的,那么无论我是否在沙盒中,问题都不会发生吗?
- 如果我错了,如果不是因为某些共享文件,编译器怎么会发生冲突?
- 假设对于每个沙箱,我想挂载一个
/tmp
指向不同目录的,这可能吗?
更新:根据我在 中看到的strace
,编译器的两个实例都打开一个文件/tmp/vcs_20200428163636_3/v710_tok
进行读写,并且在某些时候一个实例调用pread64()
会导致段错误。注意文件名,它看起来很可疑,就像暗示试图获取唯一文件名的日期一样,但两个实例的执行距离不够远。
问题 1 和 3 仍然有效。
解决方案
解决方案:
通过添加--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,从而允许它们发生冲突。
推荐阅读
- stripe-payments - Why I am getting 'insufficient funds' when trying Stripe Transfers even though I added TEST mode funds in my Account?
- php - 在我的购物车列表中添加一个表格列而不是行
- java - 如何在 textView 中显示 JSON 凌空请求响应的对象(以 HTML 格式)形式?
- angular - 如何设置单独的开发和发布代理/后端 api url?
- android - 如果我在下载时重新启动活动,如何处理布局中的进度条和其他 UI 更新?
- angular - 断言变量已定义
- typo3 - TYPO3 TCA 类别和 FAL
- javascript - 模态关闭后停止 iframe 自动播放
- docker - 如何将文件复制到docker容器中的主机挂载目录
- ruby-on-rails - 安装gem“设计”时如何修复错误?