Valgrind error in a readline test

Issue #8644 has been updated by akr (Akira T.).

http://rbci.lakewood.privs.net/ruby-trunk/log/20130801T131001Z.diff.html.gz
をみると、


TestRange#test_bsearch_for_other_numerics = s = .
TestRange#test_bsearch_typechecks_return_values = s = .
+TestRange#test_bsearch_with_mathn =
/home/chkbuild/build//ruby/test/readline/test_readline.rb:299:
[BUG] Segmentation fault
ruby

±- Control frame information

+c:0028 p:---- s:0127 e:000126 CFUNC :readline
+c:0027 p:0013 s:0124 e:000123 BLOCK
/home/chkbuild/build//ruby/test/readline/test_readline.rb:299
+c:0026 p:0036 s:0122 e:000121 METHOD
/home/chkbuild/build//ruby/lib/minitest/unit.rb:362

みたいな感じで SEGV していて、
test_readline.rb:299 というのは test_closed_outstream 内の
Readline.readline を呼び出しているところで、
なかなか怪しいんじゃないかと思うんですが、どうですかね。


Bug #8644: valgrind error in a readline test
https://bugs.ruby-lang.org/issues/8644#change-40798

Author: akr (Akira T.)
Status: Assigned
Priority: Normal
Assignee: kouji (Kouji T.)
Category: ext
Target version: next minor
ruby -v: ruby 2.1.0dev (2013-07-16 trunk 42006) [x86_64-linux]
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN

test-all が readline のところで SEGV することがあったので、
とりあえず valgrind をかけてみたところ、ひとつ問題を指摘されました。

% ./ruby -v
ruby 2.1.0dev (2013-07-16 trunk 42006) [x86_64-linux]
% valgrind ./ruby -I.ext/x86_64-linux …/…/ruby/test/runner.rb
…/…/ruby/test/readline -n test_closed_outstream
==27651== Memcheck, a memory error detector
==27651== Copyright © 2002-2011, and GNU GPL’d, by Julian Seward et
al.
==27651== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright
info
==27651== Command: ./ruby -I.ext/x86_64-linux
…/…/ruby/test/runner.rb …/…/ruby/test/readline -n
test_closed_outstream
==27651==
Run options: -n test_closed_outstream

Running tests:

[1/1] TestReadline#test_closed_outstream==27651== Invalid read of size
4
==27651== at 0x597B610: fileno (fileno.c:37)
==27651== by 0x74A3EA6: readline_readline (readline.c:397)
==27651== by 0x390B39: call_cfunc_m1 (vm_insnhelper.c:1348)
==27651== by 0x396943: vm_call_cfunc_with_frame
(vm_insnhelper.c:1492)
==27651== by 0x395144: vm_call_cfunc (vm_insnhelper.c:1582)
==27651== by 0x394915: vm_call_method (vm_insnhelper.c:1774)
==27651== by 0x396A84: vm_call_general (vm_insnhelper.c:1925)
==27651== by 0x3724DC: vm_exec_core (insns.def:1017)
==27651== by 0x383DDF: vm_exec (vm.c:1198)
==27651== by 0x389DBD: invoke_block_from_c (vm.c:646)
==27651== by 0x38E299: vm_yield (vm.c:677)
==27651== by 0x380012: rb_yield_0 (vm_eval.c:937)
==27651== Address 0x847a1a0 is 0 bytes inside a block of size 568
free’d
==27651== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27651== by 0x5977CCC: [email protected]@GLIBC_2.2.5 (iofclose.c:88)
==27651== by 0x190F5C: nogvl_fclose (io.c:4048)
==27651== by 0x3A33FC: call_without_gvl (thread.c:1244)
==27651== by 0x3A3532: rb_thread_call_without_gvl (thread.c:1354)
==27651== by 0x190E7C: maygvl_fclose (io.c:4057)
==27651== by 0x190620: fptr_finalize (io.c:4099)
==27651== by 0x16C922: rb_io_fptr_cleanup (io.c:4130)
==27651== by 0x16CAE7: rb_io_close (io.c:4221)
==27651== by 0x17A2F1: rb_io_close_m (io.c:4250)
==27651== by 0x390B62: call_cfunc_0 (vm_insnhelper.c:1354)
==27651== by 0x396943: vm_call_cfunc_with_frame
(vm_insnhelper.c:1492)
==27651==
Finished tests in 0.521803s, 1.9164 tests/s, 5.7493 assertions/s.
1 tests, 3 assertions, 0 failures, 0 errors, 0 skips

ruby -v: ruby 2.1.0dev (2013-07-16 trunk 42006) [x86_64-linux]
==27651==
==27651== HEAP SUMMARY:
==27651== in use at exit: 1,905,554 bytes in 30,452 blocks
==27651== total heap usage: 94,021 allocs, 63,569 frees, 19,535,963
bytes allocated
==27651==
==27651== LEAK SUMMARY:
==27651== definitely lost: 447,671 bytes in 3,643 blocks
==27651== indirectly lost: 979,312 bytes in 17,524 blocks
==27651== possibly lost: 0 bytes in 0 blocks
==27651== still reachable: 478,571 bytes in 9,285 blocks
==27651== suppressed: 0 bytes in 0 blocks
==27651== Rerun with --leak-check=full to see details of leaked memory
==27651==
==27651== For counts of detected and suppressed errors, rerun with: -v
==27651== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from
4)

ちょっとソースを見たところ、fclose した後に fileno しているようですが、
これはよろしくないんじゃないでしょうか。

valgrind で指摘されたのが原因かどうかはわかりませんが、
SEGV したときのログもつけておきます。
(長すぎるので消しました。test_closed_outstream-segv.txt をみてください。)