Hatena::ブログ(Diary)

PB memo このページをアンテナに追加 RSSフィード

2018-06-25 ruby-trunk-changes r63741 - r63748

[][]ruby-trunk-changes r63741 - r63748

今日は子プロセス fork の race condition 修正などがありました。

normal: r63741 2018-06-24 21:36:44 +0900

rb_fork_ruby() で fork(2) 前の処理で before_fork_ruby() の前に disable_child_handler_before_fork() を呼んで signal mask をかけておくようにしています。 signal を main thread に配送する役割をしている timer thread を止める前に mask をかける必要があったようです。 [ruby-core:87622] [Bug #14868] [Bug #13916]

normal: r63742 2018-06-25 07:08:15 +0900

拡張ライブラリ socket の UNIXSocket#recv_io で fd が枯渇していて recvmsg(2) から EMFILE または ENFILE がかえってきた時に余計な IO が close されるのを期待して rb_gc_for_fd() を呼んで GC を起動してリトライするようにしています。また struct msghdr::msg_control_len が足りない時も GC を呼ぶようにしています。

svn: r63743 2018-06-25 07:08:16 +0900

version.h の日付更新。

normal: r63744 2018-06-25 10:06:15 +0900

mjit.c でコンパイラ起動する子プロセスを execvp(3) で起動していたのを execv(3) を呼ぶようにしています。async-signal-safe なライブラリ関数を使うようにするため。そのため事前に PATH から呼ぶべきコマンドのパス解決をしておくようにしています。

normal: r63745 2018-06-25 11:52:29 +0900

mjit.c のコンパイラオプション選択のための preprocessor の分岐で FreeBSDDebian 上での clang のための __FreeBSD__ や __GLIBC__ をチェックも条件に追加しています。

normal: r63746 2018-06-25 11:52:34 +0900

mjit.c で関数ポインタをキャストするのに ptrdiff_t を使っていたのを符号なしの uintptr_t を使うように修正しています。 32bit 環境でうまく動かなかったとのこと。

shyouhei: r63747 2018-06-25 12:14:48 +0900

r63742 の変更で ext/socket/unixsocket.c の enum宣言の最後にカンマがあったのが C99 以降でのみ許された記法なので削っています。

normal: r63748 2018-06-25 16:57:39 +0900

r63744 の mjit.c で execvp(3) のかわりに execv(3) を使うようにする変更で、パスの解決に失敗した(みつからなかった)時のメッセージを fprintf(3) で stderr に出力していたのを mjit.c 内の utility 関数 verbose() を利用するようにしています。

2018-06-24 ruby-trunk-changes r63732 - r63740

[][]ruby-trunk-changes r63732 - r63740

今日はいくつかの標準添付ライブラリのテスト追加や MJIT 利用時の Process.wait/wait2 などのテストの skip などがありました。

k0kubun: r63732 2018-06-23 22:41:06 +0900

mjit.c のグローバル変数 mjit_init_p を mjit_enabled に改名しています。将来的にはこの変数を役目にあわせて 2つに分解する予定だそうです。

tarui: r63733 2018-06-23 22:58:51 +0900

gc.c の ruby_mimmalloc() という関数で r63701 で導入した USE_GC_MALLOC_OBJ_INFO_DETAILS という malloc統計情報を集計する機能を on にした時に SEGV してたのを修正しています。struct malloc_obj_info::gen と line の再初期化を追加しています。

k0kubun: r63734 2018-06-23 23:11:19 +0900

r63732 で予告していた mjit_enabled の変数から JIT したコードの利用を抑制する役割を mjit_call_p という変数に分離しています。 TracePoint を利用した時に trace 付きの命令に差し代わった時に MJIT がまだ対応していないので、これを FALSE にして JIT されたコードを利用しないようにするみたいです。

mame: r63735 2018-06-24 18:31:06 +0900

標準添付ライブラリ prime のテストに Integer.each_prime や Prime.prime? などのテストを追加しています。 https://github.com/ruby/prime/pull/3

svn: r63736 2018-06-24 18:31:07 +0900

version.h の日付更新。

mame: r63737 2018-06-24 18:31:07 +0900

標準添付ライブラリ prime の不要なメソッド TrialDivision#cache, #primes, #primes_so_far を削除しています。

mame: r63738 2018-06-24 18:31:09 +0900

標準添付ライブラリ net/http のテストにレスポンスのステータスコードに対応する例外クラスについてのテストを追加しています。

normal: r63739 2018-06-24 19:30:48 +0900

process.c の after_fork_ruby() を関数マクロとして定義していたのを関数として定義しなおしています。

k0kubun: r63740 2018-06-24 20:07:44 +0900

r63731 と同様に [Bug #14867] の MJIT 実行時に子プロセスとしてコンパイラが起動するので Process.wait がそのプロセスも掴んでしまう問題があるため Process のテストを一部 MJIT 有効な時に skip するようにしています。

2018-06-23 ruby-trunk-changes r63724 - r63731

[][]ruby-trunk-changes r63724 - r63731

今日は TracePoint のフック内で例外発生時に無限ループに陥る場合があった不具合修正などがありました。

normal: r63724 2018-06-23 12:47:54 +0900

thread_pthread.c の native_sleep() で th->unblock.arg を 0 クリアしていたのをやめています。 th->unblock.func をクリアしたら arg はみないからいらんやろ、ということでクリアしたらまずいというわけではなさそう。ちょっとした最適化

svn: r63725 2018-06-23 12:47:55 +0900

version.h の日付更新。

ktsj: r63726 2018-06-23 13:45:57 +0900

vm.c の vm_exce_handle_exception() という関数名、よーくみると typo していたので vm_exec_handle_exception() に修正しています。 static 関数でよかった。

ktsj: r63727 2018-06-23 13:52:58 +0900

vm_exec_handle_exception() において TracePoint などのフック実行のため EXEC_EVENT_HOOK() を使ってたのを stack frame を取り除く EXEC_EVENT_HOOK_AND_POP_FRAME() を利用するように修正しています。フック内で再度例外が発生した場合に frame が残ってるとまた同じフックが呼ばれて無限ループ状態に陥ってしまっていたみたいです。 [ruby-dev:50582] [Bug #14865]

ktsj: r63728 2018-06-23 13:56:49 +0900

test/ruby/test_settracefunc.rb の TracePoint のテストで子プロセス内で呼ばれるためフック内で Thread のチェックをする utility メソッドが呼べないのに呼んでたのを削っています。ここでは Thread のチェックは不要だった模様。

ktsj: r63729 2018-06-23 13:57:49 +0900

Array#any? と Hash#any? の rdoc 用コメントの call-seq にブロックなしで引数に pattern を渡す呼びかたを追記しています。え、そんな仕様あったのか…。

k0kubun: r63730 2018-06-23 16:21:12 +0900

kMJIT が cygwin でも有効にできるようにしています。 また pthread_attr_setscope() で PTHREAD_SCOPE_PROCESS していたのを削っていますが、これは cygwin では動かないというのと LinuxmacOS でもサポートされていない(なんで入ってたんだろ)らしいので不要みたいです。 cygwin 版はとりあえずビルドはできる、という程度の状態らしいですが、あまり大きな変更はなくて動いててすごいですね。 [ruby-dev:50579] [Misc #14854]

k0kubun: r63731 2018-06-23 17:29:20 +0900

[Bug #14867] で問題提起されているように MJIT では実行時のコンパイルのため gcc/clang などのコンパイラを起動するので、Process.wait が無条件に子プロセスを待つ時にこのコンパイラプロセスも待ってしまうという問題があり、rubyspec のいくつかのテストが動かないので当面 skip するようにしています。これは難しそうですね。チケットではひとつのアイデアとしてコンパイラプロセスを起動するための孫プロセスを1つ立てて、そこを経由して(pipe を使った通信で)ひ孫プロセスとしてコンパイラを起動するというのが提案されてました。

2018-06-22 ruby-trunk-changes r63710 - r63723

[][]ruby-trunk-changes r63710 - r63723

今日は RubyVM::MJIT.pause, resume メソッドの追加、Mutex の deadlock の恐れがあった不具合修正、endless range に対する Range#to_a, #size, #max, #min などのメソッドの挙動変更などがありました。

k0kubun: r63710 2018-06-21 23:04:05 +0900

RubyVM::MJIT.pause と RubyVM::MJIT.resume というメソッドを追加しています。 MJIT の worker を起動する pthread を止めたり再開したりするコントロールができるようになっています。チケットをみると、これは MJIT が JIT コンパイル用に gcc などのコンパイラを動かすのがベンチマークノイズになるので、必要なコンパイルが終わった時点でそれ以上のコンパイルが走るのを止めたいというもののようです。 [ruby-core:87428] [Feature #14830]

normal: r63711 2018-06-22 11:32:30 +0900

Mutex の実装で RUBY_VM_CHECK_INTS_BLOCKING() で割り込みチェックするとその時点で mutex->th が書き変わっている恐れがあるのを見落していいて deadlock する可能性があった不具合を修正しているようです。じーっと睨んでなんとなくわかった気がするけどちゃんとした再現シナリオはよくわかってない。 たぶん r58604 で Mutex の実装に直接 pthread_mutex_t などを使うのをやめて linked list を使った実装に変えた時の影響なのではないかと思いますが、normal によれば 2.4 以前からあったんじゃないかってことで backport が REQUIRED に設定されてます。うーん、そうなのかな? 少なくともこの差分そのまま backport は無理そうだと思うけど。 [ruby-core:87467] [Bug #14841]

svn: r63712 2018-06-22 11:32:32 +0900

version.h の日付更新。

normal: r63713 2018-06-22 11:43:51 +0900

rb_vm_t::sleeper の宣言から volatile を外しています。 さっきの deadlock 修正のチケットの中でついでに normal が気がついたようです。 [ruby-core:87467] [Bug #14841]

mame: r63714 2018-06-22 11:58:37 +0900

終端が nil の Range いわゆる endless range に Range#to_a が呼ばれたらすぐに RangeError 例外を発生させるようにしています。まああきらかに止まらなくなる(というかメモリ食いつぶして NoMemoryError?) からそれよりは例外になって欲しいですよね。 [ruby-dev:50568] [Bug #14845]

mame: r63715 2018-06-22 11:58:39 +0900

終端が nil の Range いわゆる endless range に Range#size が呼ばれたら Float::INFINITY を返すようにしています。修正前は例外になりそうな感じなので、それよりはましな気がしますが、うーん、そうか Float::INFINITY か……。 [ruby-core:86612] [Bug #14699]

mame: r63716 2018-06-22 11:58:40 +0900

終端が nil の Range いわゆる endless range に Range#last や Range#max を呼んだ時も RangeError 例外を発生させるようにしています。 last はそうだよなあ。Range#max は終端のオブジェクトを得るので、終端はないので…… Float::INFINITY はあくまで収束先だから……みたいなこう ruby の禅を感じる一連の仕様定義でした。 [ruby-core:86612] [Bug #14699]

mame: r63717 2018-06-22 12:07:24 +0900

見落としてましたが r63716 で endless range にブロック付きで Range#min を呼ばれた時にも RangeError を発生させるようにしていて、そのテストを追加しています。 [ruby-core:86612] [Bug #14699]

nobu: r63718 2018-06-22 13:13:02 +0900

configure 時に config.h に DISABLE_RUBYGEMS の定義を出力するのをやめて、かわりに USE_RUBYGEMS という変数を管理してこれが no の時に $CPPFLAGS にコマンドラインオプションで -DDISABLE_RUBYGEMS=1 を追加するようにしています。コミットログを読む感じだと、たぶんデバッグ(?)とかでこのオプションを切り替えてビルドしなおす時に config.h が更新されて全体再ビルドになるのが辛いので、みたいな感じに読めます。configure しなおしたらどのみち再ビルドになるんじゃないのかな?

normal: r63719 2018-06-22 15:17:15 +0900

thread.c の sleep_timespec() で spurious wakeup のチェックの前にタイマーの更新をしていたのでチェックの後にずらしています。

normal: r63720 2018-06-22 17:47:12 +0900

dir.c で O_CLOEXEC がない環境では 0 に定義するマクロを追加しておくようにしています。 SuSE 10 には O_CLOEXEC がないためビルドエラーになってたそうで。 O_CLOEXEC ってそんなに新しめのものだっけ? と思ったら SuSE 10 ってもう 10年くらい前のバージョンみたいですね。若干ヤケクソ気味の対応でした。 [ruby-core:87591] [Bug #14864]

naruse: r63721 2018-06-22 19:53:03 +0900

Travis CI で r63598 の Windows で Net::HTTP の write_timeout のテストが失敗するようで、assertion のメッセージに systcl net.ipv4.tcp_wmem の出力を含めるようにしています。

naruse: r63722 2018-06-22 20:10:56 +0900

r63721 の続きで今度は sysctl net.core.wmem_default と sysctl net.core.wmem_default をメッセージに含めるようにしています。

naruse: r63723 2018-06-22 20:57:06 +0900

r63721 および r63721 のテストのデバッグ用のメッセージ追加を消しています。

2018-06-21 ruby-trunk-changes r63703 - r63709

[][]ruby-trunk-changes r63703 - r63709

今日は RubyVM::AST のテストの修正や IO のテストのタイミング依存の問題対応などがありました。

yui-knk: r63703 2018-06-20 21:11:25 +0900

RubyVM::AST のテストで RubyVM::AST#children から Node だけ残すつもりで書いた grep の条件が RubyVM::AST になっていたため、全ての要素が削られてしまっていたので RubyVM::AST::Node に修正しています。

yui-knk: r63704 2018-06-20 21:40:59 +0900

r63602 で RubyVM::AST.parse_file などで文法エラーになるスクリプトを渡すと SyntaxError 例外が発生するようになったので RubyVM::AST のテストで nil がかえってきたら例外を発生させるようにしていた処理を削っています。

hsbt: r63705 2018-06-20 21:51:38 +0900

doc/standard_library.rdoc からコアに取り込まれたため標準添付ライブラリではなくなった ConditionVariable と Queue のクラス名を削っています。

ko1: r63706 2018-06-21 03:10:09 +0900

vm_search_method() において klass について 0 じゃないか(内部オブジェクトじゃないか?)、Class継承したオブジェクト(つまりクラス)かどうかなどチェックするように VM_ASSERT() で assertion を追加しています。

svn: r63707 2018-06-21 03:10:10 +0900

version.h の日付更新。

normal: r63708 2018-06-21 08:38:16 +0900

IO のテストで SIGUSR2 を利用したテストでシグナルハンドラでインスタンス変数の更新をするだけにしていたのを、pipe を利用したデータのやりとりをするようにしています。timer thread が常に定期的に起きるようにビルドされてる時にシグナル送出後に意図したよりも遅れて処理される可能性があるのでより確実に同期するため。別に sleepy timer thread disabled じゃなくても遅延する可能性はあるとは思うけど。

normal: r63709 2018-06-21 08:38:21 +0900

これも sleepy timer thread (不要な時に timer thread が定期的に wakeup するのを抑制する実装)が無効化されたビルドの時の fork のテストの修正のため native_stop_timer_thread() で USE_SLEEPY_TIMER_THREAD が偽の時も native_thread_join() は呼ぶようにしています。