Issue #9820 has been updated by Nobuyoshi Nakada. 元々シグナルがすぐ配送されるとは限らないわけで、とりあえずタイムアウトをつけてみるのはどうでしょうか。 ~~~diff diff --git i/thread.c w/thread.c index dfa91a8..209aff1 100644 --- i/thread.c +++ w/thread.c @@ -5180,10 +5180,11 @@ ruby_kill(rb_pid_t pid, int sig) * delivered immediately and synchronously. */ if ((sig != 0) && (th == vm->main_thread) && (pid == getpid())) { + static const struct timespec limit = {0, 1000*1000}; /* 1ms */ GVL_UNLOCK_BEGIN(); native_mutex_lock(&th->interrupt_lock); err = kill(pid, sig); - native_cond_wait(&th->interrupt_cond, &th->interrupt_lock); + native_cond_timedwait(&th->interrupt_cond, &th->interrupt_lock, &limit); native_mutex_unlock(&th->interrupt_lock); GVL_UNLOCK_END(); } ~~~ ---------------------------------------- Bug #9820: miniruby -e 'Process.kill(:INT, $$)' hang under cron https://bugs.ruby-lang.org/issues/9820#change-46641 * Author: Akira Tanaka * Status: Open * Priority: Normal * Assignee: * Category: * Target version: * ruby -v: ruby 2.2.0dev (2014-05-09 trunk 45884) [x86_64-linux] * Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN ---------------------------------------- 最近、しばたさんが運用を始めた chkbuild で、 TestBeginEndBlock#test_propagate_signaled が hang しています。 http://chkbuild002.hsbt.org/chkbuild/ruby-trunk/log/20140509T060013Z.fail.html.gz 調べて再現コードを小さくしていった結果、 miniruby -e 'Process.kill(:INT, $$)' というのを cron から動かしたときは hang し、 端末から動かしたときは hang しない、ということが判明しました。 strace した結果をみると、 cron 下では timer thread が prctl の直後に poll を呼び出してそれが終わらないという挙動なのに対し、 端末ではそのあたりで context switch が起きている、ような気がします。 strace の結果を strace.cron.log と strace.term.log として添付します。 なにかわかるひとはいますでしょうか? ``` % ./miniruby -v ruby 2.2.0dev (2014-05-09 trunk 45884) [x86_64-linux] % uname -mrsv Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.54-2 x86_64 % lsb_release -idrc Distributor ID: Debian Description: Debian GNU/Linux 7.5 (wheezy) Release: 7.5 Codename: wheezy ``` なお、コミッタならしばたさんに頼むとそのマシンにアカウントを作ってくれる模様です。 ---Files-------------------------------- strace.cron.log (15.8 KB) strace.term.log (17.6 KB) -- https://bugs.ruby-lang.org/