Actions
Bug #16342
closedmacOS + Ruby 2.6.0 以降で拡張ライブラリ内での waitpid() コールに失敗する
Description
再現環境¶
- Ruby 2.6.0 以降
- macOS 10.15 (試した環境)
問題の説明¶
macOS 上で Ruby 2.6.0 以降を使用した際に、拡張ライブラリ内で fork()/exec()
で外部コマンドを実行したあと waitpid()
をコールすると失敗するようになりました。
私がメンテナンスしている RMagick 利用している ImageMagick が PDF を処理する際にこのような処理を行っており、macOS + Ruby 2.6.0 以降で処理に失敗するようになり困っております。
https://github.com/rmagick/rmagick/issues/483
https://github.com/Watson1978/rmagick-issue483 に再現コードを用意しており、以下の様に実行していただくと macOS + Ruby 2.6.0 以降でエラー終了します。
$ ./setup.sh
$ ruby sample.rb
$ ruby sample.rb
Ruby v2.6.0
Error waitpid(): Interrupted system call
$ ./setup.sh
$ ruby ./sample.rb
Ruby v2.6.5
Error waitpid(): Interrupted system call
Ruby 2.5.x 以下ですと期待通りに WIFEXITED
のパスを通り正常に終了します。
$ ./setup.sh
$ ruby sample.rb
Ruby v2.5.7
(1) WIFEXITED : status = 0
$ ./setup.sh
$ ruby sample.rb
Ruby v2.3.8
(1) WIFEXITED : status = 0
確認した限り、macOS 上だけでこの現象が発生します。
再現コード¶
https://github.com/Watson1978/rmagick-issue483 のレポジトリに以下と同様の再現コードをコミットしており、すぐに確認できるかと思います。
#include <ruby.h>
#include <unistd.h>
VALUE
sample_test(VALUE self)
{
int status = 0;
int child_status = 0;
pid_t child_pid = fork();
if (child_pid == 0) {
char *const args[] = {
"/bin/sleep",
"1",
NULL
};
status = execvp(args[0], args);
exit(0);
}
else {
pid_t pid;
pid = waitpid(child_pid, &child_status, 0);
if (pid == -1) {
status = -1;
perror("Error waitpid()");
}
else {
if (WIFEXITED(child_status)) {
// Expected path
status = WEXITSTATUS(child_status);
printf("(1) WIFEXITED : status = %d\n", status);
}
else if (WIFSIGNALED(child_status)) {
status = -1;
printf("(2) WIFSIGNALED : status = %d\n", status);
}
}
}
return INT2FIX(status);
}
void Init_sample(void)
{
VALUE rb_cSample = rb_define_class("Sample", rb_cObject);
rb_define_method(rb_cSample, "test", sample_test, 0);
}
Actions
Like0
Like0Like0Like0Like0Like0Like0