Project

General

Profile

Bug #212

Issues with Readline in Mac OS X

Added by febuiles (Federico Builes) almost 10 years ago. Updated about 7 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
[ruby-core:17479]

Description

=begin
There are currently some issue with the Readline wrappers for Editline in Mac OS 10.5, e.g.:

 require 'readline'
 puts Readline::VERSION
 Readline::HISTORY.push("1", "2", "3")
 Readline::HISTORY.each { |i| puts i }
 # => "EditLine wrapper"
 # => 2
 # => 3

Any idea if this is an issue with the wrapper or if it's a bug with the underlying library?
Compiling ruby with GNU Readline works fine.
=end

no212.patch (953 Bytes) no212.patch history_base - 1 with libedit kouji (Kouji Takao), 07/13/2008 09:09 PM
no212_ext-readline-readline.c.patch (4.14 KB) no212_ext-readline-readline.c.patch for 1.8.6. kouji (Kouji Takao), 08/14/2008 01:38 AM
no212_ext-readline-readline.c.patch (11.4 KB) no212_ext-readline-readline.c.patch for 1.8 branch. kouji (Kouji Takao), 08/14/2008 01:38 AM

Associated revisions

Revision e3e8af93
Added by k0kubun (Takashi Kokubun) 4 months ago

mjit.c: fix deadlock on class serial increment

This is reported by @hasimo. Fixing a case like this:

#0 lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1 0x00007fc7bd824dbd in __GI
_pthread_mutex_lock (mutex=mutex@entry=0x55946d294440 ) at ../nptl/pthread_mutex_lock.c:80 4
#2 0x000055946cec54d9 in rb_native_mutex_lock (lock=lock@entry=0x55946d294440 ) at thread_pthread.c:211
#3 0x000055946cde10ca in CRITICAL_SECTION_START (msg=0x55946cfb5423 "mjit_gc_start_hook", level=4) at mjit.c:392
#4 mjit_gc_start_hook () at mjit.c:412
#5 0x000055946cda0dfe in gc_enter (event=0x55946cfaf91e "gc_rest", objspace=0x55946da51760) at gc.c:6623
#6 gc_rest (objspace=objspace@entry=0x55946da51760) at gc.c:6515
#7 0x000055946cd9f1cf in gc_rest (objspace=0x55946da51760) at gc.c:7841
#8 objspace_malloc_increase (objspace=objspace@entry=0x55946da51760, new_size=, old_size=old_size@entry=0, type=type@entry=MEMOP_TYPE_MALLOC, mem=0x7fc7a4439010) at gc.c:7842
#9 0x000055946cda1706 in objspace_malloc_fixup (size=, mem=0x7fc7a4439010, objspace=0x55946da51760) at gc.c:7910
#10 objspace_xmalloc0 (objspace=0x55946da51760, size=, size@entry=3145728) at gc.c:7939
#11 0x000055946cda3620 in ruby_xmalloc0 (size=3145728) at gc.c:8006
#12 ruby_xmalloc (size=size@entry=3145728) at gc.c:8015
#13 0x000055946ce93f4c in st_init_table_with_size (type=0x55946d28da30 , size=) at st.c:602
#14 0x000055946ce94287 in rebuild_table (tab=tab@entry=0x55946db669f0) at st.c:777
#15 0x000055946ce963f7 in rebuild_table_if_necessary (tab=0x55946db669f0) at st.c:1139
#16 st_add_direct_with_hash (hash=8577035585096733536, value=20, key=808451, tab=0x55946db669f0) at st.c:1207
#17 st_update (tab=0x55946db669f0, key=key@entry=808451, func=, arg=140726472841392) at st.c:1512
#18 0x000055946cda9e27 in tbl_update (optional_arg=, func=, key=, hash=) at hash.c:561
#19 rb_hash_aset (hash=94095983218480, key=key@entry=808451, val=val@entry=20) at hash.c:1654
#20 0x000055946cde243a in mjit_add_class_serial (class_serial=class_serial@entry=404225) at mjit.c:1414 3
#21 0x000055946cefcfab in rb_next_class_serial () at vm.c:321
#22 0x000055946cf48324 in class_alloc (klass=, flags=28) at class.c:178
#23 rb_include_class_new (module=module@entry=94096115733840, super=0) at class.c:820
#24 0x000055946cf487ac in include_modules_at (klass=klass@entry=94096135960920, c=, module=, module@entry=94096115734160, search_super=search_super@entry=1) at class.c:913
#25 0x000055946cf48ac8 in rb_include_module (klass=94096135960920, module=module@entry=94096115734160) at class.c:870
#26 0x000055946cd84993 in rb_mod_append_features (module=94096115734160, include=) at eval.c:1178
#27 0x000055946cf06829 in vm_call0_cfunc_with_frame (ci=0x7ffd6f6c9a20, cc=0x7ffd6f6c9ba0, argv=0x7ffd6f6c9ba0, calling=0x7ffd6f6c9a30, ec=0x55946da519c8) at vm_eval.c:87
#28 vm_call0_cfunc (argv=0x7ffd6f6c9ba0, cc=0x7ffd6f6c9ba0, ci=0x7ffd6f6c9a20, calling=0x7ffd6f6c9a30, ec=0x55946da519c8) at vm_eval.c:102
#29 vm_call0_body (ec=ec@entry=0x55946da519c8, calling=calling@entry=0x7ffd6f6c9ae0, ci=ci@entry=0x7ffd6f6c9ad0, cc=cc@entry=0x7ffd6f6c9b00, argv=argv@entry=0x7ffd6f6c9ba0) at vm_eval.c:133
#30 0x000055946cf074b2 in vm_call0 (me=, argv=0x7ffd6f6c9ba0, argc=1, id=4849, recv=94096115734160, ec=0x55946da519c8) at vm_eval.c:60
#31 rb_call0 (ec=0x55946da519c8, recv=94096115734160, mid=4849, mid@entry=94096135960920, argc=argc@entry=1, argv=argv@entry=0x7ffd6f6c9ba0, scope=scope@entry=CALL_FCALL, self=94096135960920) at vm_eval.c:302
#32 0x000055946cf07b9b in rb_call (scope=CALL_FCALL, argv=0x7ffd6f6c9ba0, argc=1, mid=94096135960920, recv=) at vm_eval.c:595
#33 rb_funcallv (recv=, mid=mid@entry=4849, argc=argc@entry=1, argv=argv@entry=0x7ffd6f6c9ba0) at vm_eval.c:825
#34 0x000055946cd848a7 in rb_mod_include (argc=0, argv=0x7fc7bdb4fce8, module=94096135960920) at eval.c:1203
#35 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x5594710c06b0, cc=, calling=, reg_cfp=0x7fc7bdc4df00, ec=0x55946da519c8) at vm_insnhelper.c:1928
#36 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4df00, calling=, ci=0x5594710c06b0, cc=) at vm_insnhelper.c:1944
#37 0x000055946cf0b5c2 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:779
#38 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#39 0x000055946cf035fc in invoke_block (captured=0x7ffd6f6ca0a0, opt_pc=, type=, cref=0x559476c23930, self=94096135960920, iseq=0x559471335ee0, ec=0x55946da519c8) at vm.c:1005
#40 invoke_iseq_block_from_c (ec=0x55946da519c8, captured=0x7ffd6f6ca0a0, self=94096135960920, argc=, argv=, passed_block_handler=0, cref=0x559476c23930, is_lambda=0) at vm.c:1057
#41 0x000055946cf04520 in invoke_block_from_c_bh (ec=ec@entry=0x55946da519c8, block_handler=, argc=argc@entry=1, argv=argv@entry=0x7ffd6f6ca108, cref=, is_lambda=, is_lambda@entry=0, force_blockarg=0, passed_block_handler=0) at vm.c:1075
#42 0x000055946cf04958 in vm_yield_with_cref (is_lambda=0, cref=, argv=0x7ffd6f6ca108, argc=1, ec=0x55946da519c8) at vm.c:1112
#43 yield_under (under=94096135960920, self=, argc=argc@entry=1, argv=argv@entry=0x7ffd6f6ca108) at vm_eval.c:1572
#44 0x000055946cf04b12 in rb_mod_module_exec (argc=argc@entry=1, argv=argv@entry=0x7ffd6f6ca108, mod=) at vm_eval.c:1770
#45 0x000055946ce00fc6 in rb_mod_initialize (module=94096135960920) at object.c:1978
#46 0x000055946cf06829 in vm_call0_cfunc_with_frame (ci=0x7ffd6f6ca130, cc=0x7fc7bdb4fc98, argv=0x7fc7bdb4fc98, calling=0x7ffd6f6ca140, ec=0x55946da519c8) at vm_eval.c:87
#47 vm_call0_cfunc (argv=0x7fc7bdb4fc98, cc=0x7fc7bdb4fc98, ci=0x7ffd6f6ca130, calling=0x7ffd6f6ca140, ec=0x55946da519c8) at vm_eval.c:102
#48 vm_call0_body (ec=ec@entry=0x55946da519c8, calling=calling@entry=0x7ffd6f6ca1f0, ci=ci@entry=0x7ffd6f6ca1e0, cc=cc@entry=0x7ffd6f6ca210, argv=argv@entry=0x7fc7bdb4fc98) at vm_eval.c:133
#49 0x000055946cf074b2 in vm_call0 (me=, argv=0x7fc7bdb4fc98, argc=0, id=3057, recv=94096135960920, ec=0x55946da519c8) at vm_eval.c:60
#50 rb_call0 (ec=0x55946da519c8, recv=recv@entry=94096135960920, mid=mid@entry=3057, argc=argc@entry=3057, argv=argv@entry=0x0, scope=scope@entry=CALL_FCALL, self=94095983466120) at vm_eval.c:302
#51 0x000055946cf07b9b in rb_call (scope=CALL_FCALL, argv=0x0, argc=3057, mid=3057, recv=94096135960920) at vm_eval.c:595
#52 rb_funcallv (recv=recv@entry=94096135960920, mid=mid@entry=3057, argc=argc@entry=0, argv=argv@entry=0x7fc7bdb4fc98) at vm_eval.c:825
#53 0x000055946cd89673 in rb_obj_call_init (obj=obj@entry=94096135960920, argc=argc@entry=0, argv=argv@entry=0x7fc7bdb4fc98) at eval.c:1590
#54 0x000055946ce048a1 in rb_class_s_new (argc=0, argv=0x7fc7bdb4fc98, klass=) at object.c:2153
#55 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x559471339c80, cc=, calling=, reg_cfp=0x7fc7bdc4dfa8, ec=0x55946da519c8) at vm_insnhelper.c:1928
#56 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4dfa8, calling=, ci=0x559471339c80, cc=) at vm_insnhelper.c:1944
#57 0x000055946cf0cb05 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:716
#58 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#59 0x000055946cf03274 in invoke_bmethod (ec=ec@entry=0x55946da519c8, iseq=iseq@entry=0x55946f15cbc0, self=self@entry=94096115734640, me=me@entry=0x559475664e28, type=type@entry=572653825, opt_pc=0, captured=0x55947158e8a0) at vm.c:1026
#60 0x000055946cf03534 in invoke_iseq_block_from_c (ec=0x55946da519c8, captured=0x55947158e8a0, self=94096115734640, argc=, argv=, passed_block_handler=0, cref=0x0, is_lambda=1) at vm.c:1060
#61 0x000055946cf036ce in invoke_block_from_c_proc (ec=, proc=, self=, argc=1, argv=, passed_block_handler=, is_lambda=) at vm.c:1150
#62 0x000055946cf03811 in vm_invoke_bmethod (block_handler=, argv=, argc=1, self=, proc=, ec=0x55946da519c8) at vm.c:1175
#63 vm_call_bmethod_body (ci=, cc=0x55946f625960, argv=, calling=0x7ffd6f6ca9b0, ec=0x55946da519c8) at vm_insnhelper.c:1971
#64 vm_call_bmethod (ec=0x55946da519c8, cfp=0x7fc7bdc4e0c0, calling=0x7ffd6f6ca9b0, ci=, cc=0x55946f625960) at vm_insnhelper.c:1988
#65 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4e0c0, calling=, ci=, cc=) at vm_insnhelper.c:2417
#66 0x000055946cf0e63e in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:797
#67 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#68 0x000055946cf06767 in vm_call0_body (ec=ec@entry=0x55946da519c8, calling=calling@entry=0x7ffd6f6cad00, ci=ci@entry=0x7ffd6f6cacf0, cc=cc@entry=0x7ffd6f6cad20, argv=argv@entry=0x7ffd6f6cadb0) at vm_eval.c:129
#69 0x000055946cf074b2 in vm_call0 (me=, argv=0x7ffd6f6cadb0, argc=1, id=3681, recv=94096115734640, ec=0x55946da519c8) at vm_eval.c:60
#70 rb_call0 (ec=0x55946da519c8, recv=recv@entry=94096115734640, mid=3681, argc=argc@entry=1, argv=argv@entry=0x7ffd6f6cad90, scope=scope@entry=CALL_FCALL, self=94095983452880) at vm_eval.c:302
#71 0x000055946cf07b9b in rb_call (scope=CALL_FCALL, argv=0x7ffd6f6cad90, argc=1, mid=, recv=94096115734640) at vm_eval.c:595
#72 rb_funcallv (recv=recv@entry=94096115734640, mid=, argc=argc@entry=1, argv=argv@entry=0x7ffd6f6cadb0) at vm_eval.c:825
#73 0x000055946cf477d2 in rb_class_inherited (super=super@entry=94096115734640, klass=klass@entry=94096135961440) at class.c:625
#74 0x000055946cf0f796 in vm_declare_class (super=, cbase=94096094868200, flags=, id=847387) at vm_insnhelper.c:3134
#75 vm_define_class (super=, cbase=, flags=, id=847387) at vm_insnhelper.c:3167
#76 vm_find_or_create_class_by_id (super=, cbase=, flags=, id=847387) at vm_insnhelper.c:3196
#77 vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:685
#78 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#79 0x000055946cf118d1 in rb_iseq_eval (iseq=iseq@entry=0x559471f1b548) at vm.c:2046
#80 0x000055946cdd2164 in rb_load_internal0 (ec=ec@entry=0x55946da519c8, fname=fname@entry=94096135872160, wrap=wrap@entry=0) at load.c:611
#81 0x000055946cdd41f1 in rb_require_internal (fname=94096135872400, fname@entry=94096135872440, safe=0) at load.c:992
#82 0x000055946cdd4493 in rb_require_safe (safe=, fname=94096135872440) at load.c:1038
#83 rb_f_require (obj=, fname=94096135872440) at load.c:820
#84 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x5594708700a0, cc=, calling=, reg_cfp=0x7fc7bdc4e168, ec=0x55946da519c8) at vm_insnhelper.c:1928
#85 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e168, calling=, ci=0x5594708700a0, cc=) at vm_insnhelper.c:1944
#86 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4e168, calling=, ci=, cc=) at vm_insnhelper.c:2417
#87 0x000055946cf0e63e in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:797
#88 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#89 0x000055946cf035fc in invoke_block (captured=0x7fc7bdc4e490, opt_pc=, type=, cref=0x0, self=94096096426480, iseq=0x55946e49f0b8, ec=0x55946da519c8) at vm.c:1005
#90 invoke_iseq_block_from_c (ec=0x55946da519c8, captured=0x7fc7bdc4e490, self=94096096426480, argc=, argv=, passed_block_handler=0, cref=0x0, is_lambda=0) at vm.c:1057
#91 0x000055946cf04699 in invoke_block_from_c_bh (argc=, passed_block_handler=, cref=, is_lambda=, force_blockarg=, argv=, block_handler=, ec=) at vm.c:1075
#92 vm_yield (argc=1, argv=0x7ffd6f6cb938, ec=) at vm.c:1120
#93 rb_yield_0 (argv=0x7ffd6f6cb938, argc=1) at vm_eval.c:980
#94 rb_yield_1 (val=94096130169040) at vm_eval.c:986
#95 rb_yield (val=) at vm_eval.c:996
#96 0x000055946cf2113d in rb_ary_each (ary=94096076222560) at array.c:1820
#97 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946ed0d090, cc=, calling=, reg_cfp=0x7fc7bdc4e478, ec=0x55946da519c8) at vm_insnhelper.c:1928
#98 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e478, calling=, ci=0x55946ed0d090, cc=) at vm_insnhelper.c:1944
#99 0x000055946cf0cb05 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:716
#100 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#101 0x000055946cf035fc in invoke_block (captured=0x7fc7bdc4e500, opt_pc=, type=, cref=0x0, self=94096096426480, iseq=0x55946e49f298, ec=0x55946da519c8) at vm.c:1005
#102 invoke_iseq_block_from_c (ec=0x55946da519c8, captured=0x7fc7bdc4e500, self=94096096426480, argc=, argv=, passed_block_handler=0, cref=0x0, is_lambda=0) at vm.c:1057
#103 0x000055946cf04699 in invoke_block_from_c_bh (argc=, passed_block_handler=, cref=, is_lambda=, force_blockarg=, argv=, block_handler=, ec=) at vm.c:1075
#104 vm_yield (argc=1, argv=0x7ffd6f6cbdf8, ec=) at vm.c:1120
#105 rb_yield_0 (argv=0x7ffd6f6cbdf8, argc=1) at vm_eval.c:980
#106 rb_yield_1 (val=94096095502480) at vm_eval.c:986
#107 rb_yield (val=) at vm_eval.c:996
#108 0x000055946cf2113d in rb_ary_each (ary=94096095328480) at array.c:1820
#109 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946e8552a0, cc=, calling=, reg_cfp=0x7fc7bdc4e4e8, ec=0x55946da519c8) at vm_insnhelper.c:1928
#110 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e4e8, calling=, ci=0x55946e8552a0, cc=) at vm_insnhelper.c:1944
#111 0x000055946cf0cb05 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:716
#112 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#113 0x000055946cf06767 in vm_call0_body (ec=ec@entry=0x55946da519c8, calling=calling@entry=0x7ffd6f6cc2d0, ci=ci@entry=0x7ffd6f6cc2c0, cc=cc@entry=0x7ffd6f6cc2f0, argv=argv@entry=0x7ffd6f6cc390) at vm_eval.c:129
#114 0x000055946cf074b2 in vm_call0 (me=, argv=0x7ffd6f6cc390, argc=0, id=135807, recv=94096096186440, ec=0x55946da519c8) at vm_eval.c:60
#115 rb_call0 (ec=0x55946da519c8, recv=94096096186440, mid=135807, argc=, argv=argv@entry=0x8, scope=scope@entry=CALL_PUBLIC, self=94095993048320) at vm_eval.c:302
#116 0x000055946cf0a31a in rb_call (scope=CALL_PUBLIC, argv=0x8, argc=, mid=, recv=) at vm_eval.c:595
#117 rb_funcall_with_block (recv=, mid=, argc=argc@entry=0, argv=argv@entry=0x7ffd6f6cc390, passed_procval=passed_procval@entry=8) at vm_eval.c:857
#118 0x000055946ceb319c in rb_sym_proc_call (mid=, argc=argc@entry=1, argv=argv@entry=0x7ffd6f6cc388, passed_proc=passed_proc@entry=8) at string.c:10480
#119 0x000055946cf0477c in vm_yield_with_symbol (block_handler=0, argv=0x7ffd6f6cc388, argc=1, symbol=, ec=) at vm_insnhelper.c:2573
#120 invoke_block_from_c_bh (argc=, passed_block_handler=, cref=, is_lambda=, force_blockarg=, argv=, block_handler=, ec=) at vm.c:1084
#121 vm_yield (argc=1, argv=0x7ffd6f6cc388, ec=) at vm.c:1120
#122 rb_yield_0 (argv=0x7ffd6f6cc388, argc=1) at vm_eval.c:980
#123 rb_yield_1 (val=94096096186440) at vm_eval.c:986
#124 rb_yield (val=) at vm_eval.c:996
#125 0x000055946cf2113d in rb_ary_each (ary=94095993048320) at array.c:1820
#126 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x5594744d8280, cc=, calling=, reg_cfp=0x7fc7bdc4e590, ec=0x55946da519c8) at vm_insnhelper.c:1928
#127 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e590, calling=, ci=0x5594744d8280, cc=) at vm_insnhelper.c:1944
#128 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4e590, calling=, ci=, cc=) at vm_insnhelper.c:2417
#129 0x000055946cf0cb05 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:716
#130 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#131 0x000055946cf035fc in invoke_block (captured=0x7ffd6f6cc8e0, opt_pc=, type=, cref=0x559474604128, self=94096096426480, iseq=0x5594745027e8, ec=0x55946da519c8) at vm.c:1005
#132 invoke_iseq_block_from_c (ec=0x55946da519c8, captured=0x7ffd6f6cc8e0, self=94096096426480, argc=, argv=, passed_block_handler=0, cref=0x559474604128, is_lambda=0) at vm.c:1057
#133 0x000055946cf04520 in invoke_block_from_c_bh (ec=ec@entry=0x55946da519c8, block_handler=, argc=argc@entry=1, argv=argv@entry=0x7fc7bdb4f7f8, cref=, is_lambda=, is_lambda@entry=0, force_blockarg=0, passed_block_handler=0) at vm.c:1075
#134 0x000055946cf04958 in vm_yield_with_cref (is_lambda=0, cref=, argv=0x7fc7bdb4f7f8, argc=1, ec=0x55946da519c8) at vm.c:1112
#135 yield_under (under=94096093646040, self=, argc=1, argv=0x7fc7bdb4f7f8) at vm_eval.c:1572
#136 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946e5cd230, cc=, calling=, reg_cfp=0x7fc7bdc4e600, ec=0x55946da519c8) at vm_insnhelper.c:1928
#137 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e600, calling=, ci=0x55946e5cd230, cc=) at vm_insnhelper.c:1944
#138 0x000055946cf0cb05 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:716
#139 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#140 0x000055946cf035fc in invoke_block (captured=0x5594744c4fb0, opt_pc=, type=, cref=0x0, self=94095990659320, iseq=0x55946e192aa0, ec=0x55946da519c8) at vm.c:1005
#141 invoke_iseq_block_from_c (ec=0x55946da519c8, captured=0x5594744c4fb0, self=94095990659320, argc=, argv=, passed_block_handler=0, cref=0x0, is_lambda=0) at vm.c:1057
#142 0x000055946cf04699 in invoke_block_from_c_bh (argc=, passed_block_handler=, cref=, is_lambda=, force_blockarg=, argv=, block_handler=, ec=) at vm.c:1075
#143 vm_yield (argc=1, argv=0x7ffd6f6ccdc8, ec=) at vm.c:1120
#144 rb_yield_0 (argv=0x7ffd6f6ccdc8, argc=1) at vm_eval.c:980
#145 rb_yield_1 (val=94096094867920) at vm_eval.c:986
#146 rb_yield (val=) at vm_eval.c:996
#147 0x000055946cf2113d in rb_ary_each (ary=94096094867160) at array.c:1820
#148 0x000055946cf06829 in vm_call0_cfunc_with_frame (ci=0x7ffd6f6cce00, cc=0x7ffd6f6cce70, argv=0x7fc7bdb4f6b8, calling=0x7ffd6f6cce50, ec=0x55946da519c8) at vm_eval.c:87
#149 vm_call0_cfunc (argv=0x7fc7bdb4f6b8, cc=0x7ffd6f6cce70, ci=0x7ffd6f6cce00, calling=0x7ffd6f6cce50, ec=0x55946da519c8) at vm_eval.c:102
#150 vm_call0_body (ec=0x55946da519c8, calling=calling@entry=0x7ffd6f6ccec0, ci=ci@entry=0x7ffd6f6cceb0, cc=cc@entry=0x7ffd6f6ccee0, argv=0x7fc7bdb4f6b8) at vm_eval.c:133
#151 0x000055946cf06c50 in vm_call0 (me=, argv=, argc=, id=, recv=, ec=) at vm_eval.c:60
#152 rb_vm_call (ec=, recv=, id=, argc=, argv=, me=) at vm_eval.c:209
#153 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946dba2780, cc=, calling=, reg_cfp=0x7fc7bdc4e7c0, ec=0x55946da519c8) at vm_insnhelper.c:1928
#154 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e7c0, calling=, ci=0x55946dba2780, cc=) at vm_insnhelper.c:1944
#155 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4e7c0, calling=, ci=, cc=) at vm_insnhelper.c:2417
#156 0x000055946cf0cb05 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:716
#157 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#158 0x000055946cf118d1 in rb_iseq_eval (iseq=iseq@entry=0x55946dfed3a8) at vm.c:2046
#159 0x000055946cdd2164 in rb_load_internal0 (ec=ec@entry=0x55946da519c8, fname=fname@entry=94095988939080, wrap=wrap@entry=0) at load.c:611
#160 0x000055946cdd41f1 in rb_require_internal (fname=94095988939160, fname@entry=94095988939200, safe=0) at load.c:992
#161 0x000055946cdd4493 in rb_require_safe (safe=, fname=94095988939200) at load.c:1038
#162 rb_f_require (obj=, fname=94095988939200) at load.c:820
#163 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946dffa920, cc=, calling=, reg_cfp=0x7fc7bdc4e948, ec=0x55946da519c8) at vm_insnhelper.c:1928
#164 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e948, calling=, ci=0x55946dffa920, cc=) at vm_insnhelper.c:1944
#165 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4e948, calling=, ci=, cc=) at vm_insnhelper.c:2417
#166 0x000055946cf0b5c2 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:779
#167 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#168 0x000055946cf118d1 in rb_iseq_eval (iseq=iseq@entry=0x55946dfee438) at vm.c:2046
#169 0x000055946cdd2164 in rb_load_internal0 (ec=ec@entry=0x55946da519c8, fname=fname@entry=94095993039280, wrap=wrap@entry=0) at load.c:611
#170 0x000055946cdd41f1 in rb_require_internal (fname=fname@entry=94095993043840, safe=0) at load.c:992
#171 0x000055946cdd4493 in rb_require_safe (safe=, fname=94095993043840) at load.c:1038
#172 rb_f_require (obj=, fname=94095993043840) at load.c:820
#173 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946ea12160, cc=, calling=, reg_cfp=0x7fc7bdc4e9b8, ec=0x55946da519c8) at vm_insnhelper.c:1928
#174 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e9b8, calling=, ci=0x55946ea12160, cc=) at vm_insnhelper.c:1944
#175 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4e9b8, calling=, ci=, cc=) at vm_insnhelper.c:2417
#176 0x000055946cf0b5c2 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:779
#177 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#178 0x000055946cf118d1 in rb_iseq_eval (iseq=iseq@entry=0x55946e3d7c48) at vm.c:2046
#179 0x000055946cdd2164 in rb_load_internal0 (ec=ec@entry=0x55946da519c8, fname=fname@entry=94095988920840, wrap=) at load.c:611
#180 0x000055946cdd2850 in rb_load_internal (wrap=0, fname=94095988920840) at load.c:642
#181 rb_f_load (argc=, argv=) at load.c:710
#182 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946e7c96e0, cc=, calling=, reg_cfp=0x7fc7bdc4ea28, ec=0x55946da519c8) at vm_insnhelper.c:1928
#183 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4ea28, calling=, ci=0x55946e7c96e0, cc=) at vm_insnhelper.c:1944
#184 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4ea28, calling=, ci=, cc=) at vm_insnhelper.c:2417
#185 0x000055946cf0b5c2 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:779
#186 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#187 0x000055946cf035fc in invoke_block (captured=0x7fc7bdc4eae8, opt_pc=, type=, cref=0x0, self=94095998891400, iseq=0x55946e4dae10, ec=0x55946da519c8) at vm.c:1005
#188 invoke_iseq_block_from_c (ec=0x55946da519c8, captured=0x7fc7bdc4eae8, self=94095998891400, argc=, argv=, passed_block_handler=0, cref=0x0, is_lambda=0) at vm.c:1057
#189 0x000055946cf04699 in invoke_block_from_c_bh (argc=, passed_block_handler=, cref=, is_lambda=, force_blockarg=, argv=, block_handler=, ec=) at vm.c:1075
#190 vm_yield (argc=1, argv=0x7ffd6f6ce8e8, ec=) at vm.c:1120
#191 rb_yield_0 (argv=0x7ffd6f6ce8e8, argc=1) at vm_eval.c:980
#192 rb_yield_1 (val=94095988924840) at vm_eval.c:986
#193 rb_yield (val=) at vm_eval.c:996
#194 0x000055946cf2113d in rb_ary_each (ary=94095988920960) at array.c:1820
#195 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946e421000, cc=, calling=, reg_cfp=0x7fc7bdc4ead0, ec=0x55946da519c8) at vm_insnhelper.c:1928
#196 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4ead0, calling=, ci=0x55946e421000, cc=) at vm_insnhelper.c:1944
#197 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4ead0, calling=, ci=, cc=) at vm_insnhelper.c:2417
#198 0x000055946cf0cb05 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:716
#199 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#200 0x000055946cf118d1 in rb_iseq_eval (iseq=iseq@entry=0x55946e35f2c0) at vm.c:2046
#201 0x000055946cdd2164 in rb_load_internal0 (ec=ec@entry=0x55946da519c8, fname=fname@entry=94095992643280, wrap=) at load.c:611
#202 0x000055946cdd2850 in rb_load_internal (wrap=0, fname=94095992643280) at load.c:642
#203 rb_f_load (argc=, argv=) at load.c:710
#204 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946e24bb20, cc=, calling=, reg_cfp=0x7fc7bdc4ec58, ec=0x55946da519c8) at vm_insnhelper.c:1928
#205 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4ec58, calling=, ci=0x55946e24bb20, cc=) at vm_insnhelper.c:1944
#206 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4ec58, calling=, ci=, cc=) at vm_insnhelper.c:2417
#207 0x000055946cf0b5c2 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:779
#208 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#209 0x000055946cf118d1 in rb_iseq_eval (iseq=iseq@entry=0x55946e3a7390) at vm.c:2046
#210 0x000055946cdd2164 in rb_load_internal0 (ec=ec@entry=0x55946da519c8, fname=fname@entry=94095993616120, wrap=) at load.c:611
#211 0x000055946cdd2850 in rb_load_internal (wrap=0, fname=94095993616120) at load.c:642
#212 rb_f_load (argc=, argv=) at load.c:710
#213 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946e6a00d0, cc=, calling=, reg_cfp=0x7fc7bdc4ecc8, ec=0x55946da519c8) at vm_insnhelper.c:1928
#214 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4ecc8, calling=, ci=0x55946e6a00d0, cc=) at vm_insnhelper.c:1944
#215 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4ecc8, calling=, ci=, cc=) at vm_insnhelper.c:2417
#216 0x000055946cf0b5c2 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:779
#217 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#218 0x000055946cf118d1 in rb_iseq_eval (iseq=iseq@entry=0x55946e470100) at vm.c:2046
#219 0x000055946cdd2164 in rb_load_internal0 (ec=ec@entry=0x55946da519c8, fname=fname@entry=94095993672200, wrap=) at load.c:611
#220 0x000055946cdd2850 in rb_load_internal (wrap=0, fname=94095993672200) at load.c:642
#221 rb_f_load (argc=, argv=) at load.c:710
#222 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946e3306a0, cc=, calling=, reg_cfp=0x7fc7bdc4efa0, ec=0x55946da519c8) at vm_insnhelper.c:1928
#223 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4efa0, calling=, ci=0x55946e3306a0, cc=) at vm_insnhelper.c:1944
#224 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4efa0, calling=, ci=, cc=) at vm_insnhelper.c:2417
#225 0x000055946cf0b5c2 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:779
#226 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#227 0x000055946cf119d5 in rb_iseq_eval_main (iseq=iseq@entry=0x55946e4bbba0) at vm.c:2057
#228 0x000055946cd83d54 in ruby_exec_internal (n=0x55946e4bbba0) at eval.c:247
#229 0x000055946cd87fdf in ruby_exec_node (n=0x55946e4bbba0) at eval.c:311
#230 ruby_run_node (n=) at eval.c:303
#231 0x000055946cd831bf in main (argc=22, argv=0x7ffd6f6d0148) at ./main.c:42

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62433 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 62433
Added by k0kubun (Takashi Kokubun) 4 months ago

mjit.c: fix deadlock on class serial increment

This is reported by @hasimo. Fixing a case like this:

#0 lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1 0x00007fc7bd824dbd in __GI
_pthread_mutex_lock (mutex=mutex@entry=0x55946d294440 ) at ../nptl/pthread_mutex_lock.c:80 4
#2 0x000055946cec54d9 in rb_native_mutex_lock (lock=lock@entry=0x55946d294440 ) at thread_pthread.c:211
#3 0x000055946cde10ca in CRITICAL_SECTION_START (msg=0x55946cfb5423 "mjit_gc_start_hook", level=4) at mjit.c:392
#4 mjit_gc_start_hook () at mjit.c:412
#5 0x000055946cda0dfe in gc_enter (event=0x55946cfaf91e "gc_rest", objspace=0x55946da51760) at gc.c:6623
#6 gc_rest (objspace=objspace@entry=0x55946da51760) at gc.c:6515
#7 0x000055946cd9f1cf in gc_rest (objspace=0x55946da51760) at gc.c:7841
#8 objspace_malloc_increase (objspace=objspace@entry=0x55946da51760, new_size=, old_size=old_size@entry=0, type=type@entry=MEMOP_TYPE_MALLOC, mem=0x7fc7a4439010) at gc.c:7842
#9 0x000055946cda1706 in objspace_malloc_fixup (size=, mem=0x7fc7a4439010, objspace=0x55946da51760) at gc.c:7910
#10 objspace_xmalloc0 (objspace=0x55946da51760, size=, size@entry=3145728) at gc.c:7939
#11 0x000055946cda3620 in ruby_xmalloc0 (size=3145728) at gc.c:8006
#12 ruby_xmalloc (size=size@entry=3145728) at gc.c:8015
#13 0x000055946ce93f4c in st_init_table_with_size (type=0x55946d28da30 , size=) at st.c:602
#14 0x000055946ce94287 in rebuild_table (tab=tab@entry=0x55946db669f0) at st.c:777
#15 0x000055946ce963f7 in rebuild_table_if_necessary (tab=0x55946db669f0) at st.c:1139
#16 st_add_direct_with_hash (hash=8577035585096733536, value=20, key=808451, tab=0x55946db669f0) at st.c:1207
#17 st_update (tab=0x55946db669f0, key=key@entry=808451, func=, arg=140726472841392) at st.c:1512
#18 0x000055946cda9e27 in tbl_update (optional_arg=, func=, key=, hash=) at hash.c:561
#19 rb_hash_aset (hash=94095983218480, key=key@entry=808451, val=val@entry=20) at hash.c:1654
#20 0x000055946cde243a in mjit_add_class_serial (class_serial=class_serial@entry=404225) at mjit.c:1414 3
#21 0x000055946cefcfab in rb_next_class_serial () at vm.c:321
#22 0x000055946cf48324 in class_alloc (klass=, flags=28) at class.c:178
#23 rb_include_class_new (module=module@entry=94096115733840, super=0) at class.c:820
#24 0x000055946cf487ac in include_modules_at (klass=klass@entry=94096135960920, c=, module=, module@entry=94096115734160, search_super=search_super@entry=1) at class.c:913
#25 0x000055946cf48ac8 in rb_include_module (klass=94096135960920, module=module@entry=94096115734160) at class.c:870
#26 0x000055946cd84993 in rb_mod_append_features (module=94096115734160, include=) at eval.c:1178
#27 0x000055946cf06829 in vm_call0_cfunc_with_frame (ci=0x7ffd6f6c9a20, cc=0x7ffd6f6c9ba0, argv=0x7ffd6f6c9ba0, calling=0x7ffd6f6c9a30, ec=0x55946da519c8) at vm_eval.c:87
#28 vm_call0_cfunc (argv=0x7ffd6f6c9ba0, cc=0x7ffd6f6c9ba0, ci=0x7ffd6f6c9a20, calling=0x7ffd6f6c9a30, ec=0x55946da519c8) at vm_eval.c:102
#29 vm_call0_body (ec=ec@entry=0x55946da519c8, calling=calling@entry=0x7ffd6f6c9ae0, ci=ci@entry=0x7ffd6f6c9ad0, cc=cc@entry=0x7ffd6f6c9b00, argv=argv@entry=0x7ffd6f6c9ba0) at vm_eval.c:133
#30 0x000055946cf074b2 in vm_call0 (me=, argv=0x7ffd6f6c9ba0, argc=1, id=4849, recv=94096115734160, ec=0x55946da519c8) at vm_eval.c:60
#31 rb_call0 (ec=0x55946da519c8, recv=94096115734160, mid=4849, mid@entry=94096135960920, argc=argc@entry=1, argv=argv@entry=0x7ffd6f6c9ba0, scope=scope@entry=CALL_FCALL, self=94096135960920) at vm_eval.c:302
#32 0x000055946cf07b9b in rb_call (scope=CALL_FCALL, argv=0x7ffd6f6c9ba0, argc=1, mid=94096135960920, recv=) at vm_eval.c:595
#33 rb_funcallv (recv=, mid=mid@entry=4849, argc=argc@entry=1, argv=argv@entry=0x7ffd6f6c9ba0) at vm_eval.c:825
#34 0x000055946cd848a7 in rb_mod_include (argc=0, argv=0x7fc7bdb4fce8, module=94096135960920) at eval.c:1203
#35 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x5594710c06b0, cc=, calling=, reg_cfp=0x7fc7bdc4df00, ec=0x55946da519c8) at vm_insnhelper.c:1928
#36 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4df00, calling=, ci=0x5594710c06b0, cc=) at vm_insnhelper.c:1944
#37 0x000055946cf0b5c2 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:779
#38 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#39 0x000055946cf035fc in invoke_block (captured=0x7ffd6f6ca0a0, opt_pc=, type=, cref=0x559476c23930, self=94096135960920, iseq=0x559471335ee0, ec=0x55946da519c8) at vm.c:1005
#40 invoke_iseq_block_from_c (ec=0x55946da519c8, captured=0x7ffd6f6ca0a0, self=94096135960920, argc=, argv=, passed_block_handler=0, cref=0x559476c23930, is_lambda=0) at vm.c:1057
#41 0x000055946cf04520 in invoke_block_from_c_bh (ec=ec@entry=0x55946da519c8, block_handler=, argc=argc@entry=1, argv=argv@entry=0x7ffd6f6ca108, cref=, is_lambda=, is_lambda@entry=0, force_blockarg=0, passed_block_handler=0) at vm.c:1075
#42 0x000055946cf04958 in vm_yield_with_cref (is_lambda=0, cref=, argv=0x7ffd6f6ca108, argc=1, ec=0x55946da519c8) at vm.c:1112
#43 yield_under (under=94096135960920, self=, argc=argc@entry=1, argv=argv@entry=0x7ffd6f6ca108) at vm_eval.c:1572
#44 0x000055946cf04b12 in rb_mod_module_exec (argc=argc@entry=1, argv=argv@entry=0x7ffd6f6ca108, mod=) at vm_eval.c:1770
#45 0x000055946ce00fc6 in rb_mod_initialize (module=94096135960920) at object.c:1978
#46 0x000055946cf06829 in vm_call0_cfunc_with_frame (ci=0x7ffd6f6ca130, cc=0x7fc7bdb4fc98, argv=0x7fc7bdb4fc98, calling=0x7ffd6f6ca140, ec=0x55946da519c8) at vm_eval.c:87
#47 vm_call0_cfunc (argv=0x7fc7bdb4fc98, cc=0x7fc7bdb4fc98, ci=0x7ffd6f6ca130, calling=0x7ffd6f6ca140, ec=0x55946da519c8) at vm_eval.c:102
#48 vm_call0_body (ec=ec@entry=0x55946da519c8, calling=calling@entry=0x7ffd6f6ca1f0, ci=ci@entry=0x7ffd6f6ca1e0, cc=cc@entry=0x7ffd6f6ca210, argv=argv@entry=0x7fc7bdb4fc98) at vm_eval.c:133
#49 0x000055946cf074b2 in vm_call0 (me=, argv=0x7fc7bdb4fc98, argc=0, id=3057, recv=94096135960920, ec=0x55946da519c8) at vm_eval.c:60
#50 rb_call0 (ec=0x55946da519c8, recv=recv@entry=94096135960920, mid=mid@entry=3057, argc=argc@entry=3057, argv=argv@entry=0x0, scope=scope@entry=CALL_FCALL, self=94095983466120) at vm_eval.c:302
#51 0x000055946cf07b9b in rb_call (scope=CALL_FCALL, argv=0x0, argc=3057, mid=3057, recv=94096135960920) at vm_eval.c:595
#52 rb_funcallv (recv=recv@entry=94096135960920, mid=mid@entry=3057, argc=argc@entry=0, argv=argv@entry=0x7fc7bdb4fc98) at vm_eval.c:825
#53 0x000055946cd89673 in rb_obj_call_init (obj=obj@entry=94096135960920, argc=argc@entry=0, argv=argv@entry=0x7fc7bdb4fc98) at eval.c:1590
#54 0x000055946ce048a1 in rb_class_s_new (argc=0, argv=0x7fc7bdb4fc98, klass=) at object.c:2153
#55 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x559471339c80, cc=, calling=, reg_cfp=0x7fc7bdc4dfa8, ec=0x55946da519c8) at vm_insnhelper.c:1928
#56 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4dfa8, calling=, ci=0x559471339c80, cc=) at vm_insnhelper.c:1944
#57 0x000055946cf0cb05 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:716
#58 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#59 0x000055946cf03274 in invoke_bmethod (ec=ec@entry=0x55946da519c8, iseq=iseq@entry=0x55946f15cbc0, self=self@entry=94096115734640, me=me@entry=0x559475664e28, type=type@entry=572653825, opt_pc=0, captured=0x55947158e8a0) at vm.c:1026
#60 0x000055946cf03534 in invoke_iseq_block_from_c (ec=0x55946da519c8, captured=0x55947158e8a0, self=94096115734640, argc=, argv=, passed_block_handler=0, cref=0x0, is_lambda=1) at vm.c:1060
#61 0x000055946cf036ce in invoke_block_from_c_proc (ec=, proc=, self=, argc=1, argv=, passed_block_handler=, is_lambda=) at vm.c:1150
#62 0x000055946cf03811 in vm_invoke_bmethod (block_handler=, argv=, argc=1, self=, proc=, ec=0x55946da519c8) at vm.c:1175
#63 vm_call_bmethod_body (ci=, cc=0x55946f625960, argv=, calling=0x7ffd6f6ca9b0, ec=0x55946da519c8) at vm_insnhelper.c:1971
#64 vm_call_bmethod (ec=0x55946da519c8, cfp=0x7fc7bdc4e0c0, calling=0x7ffd6f6ca9b0, ci=, cc=0x55946f625960) at vm_insnhelper.c:1988
#65 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4e0c0, calling=, ci=, cc=) at vm_insnhelper.c:2417
#66 0x000055946cf0e63e in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:797
#67 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#68 0x000055946cf06767 in vm_call0_body (ec=ec@entry=0x55946da519c8, calling=calling@entry=0x7ffd6f6cad00, ci=ci@entry=0x7ffd6f6cacf0, cc=cc@entry=0x7ffd6f6cad20, argv=argv@entry=0x7ffd6f6cadb0) at vm_eval.c:129
#69 0x000055946cf074b2 in vm_call0 (me=, argv=0x7ffd6f6cadb0, argc=1, id=3681, recv=94096115734640, ec=0x55946da519c8) at vm_eval.c:60
#70 rb_call0 (ec=0x55946da519c8, recv=recv@entry=94096115734640, mid=3681, argc=argc@entry=1, argv=argv@entry=0x7ffd6f6cad90, scope=scope@entry=CALL_FCALL, self=94095983452880) at vm_eval.c:302
#71 0x000055946cf07b9b in rb_call (scope=CALL_FCALL, argv=0x7ffd6f6cad90, argc=1, mid=, recv=94096115734640) at vm_eval.c:595
#72 rb_funcallv (recv=recv@entry=94096115734640, mid=, argc=argc@entry=1, argv=argv@entry=0x7ffd6f6cadb0) at vm_eval.c:825
#73 0x000055946cf477d2 in rb_class_inherited (super=super@entry=94096115734640, klass=klass@entry=94096135961440) at class.c:625
#74 0x000055946cf0f796 in vm_declare_class (super=, cbase=94096094868200, flags=, id=847387) at vm_insnhelper.c:3134
#75 vm_define_class (super=, cbase=, flags=, id=847387) at vm_insnhelper.c:3167
#76 vm_find_or_create_class_by_id (super=, cbase=, flags=, id=847387) at vm_insnhelper.c:3196
#77 vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:685
#78 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#79 0x000055946cf118d1 in rb_iseq_eval (iseq=iseq@entry=0x559471f1b548) at vm.c:2046
#80 0x000055946cdd2164 in rb_load_internal0 (ec=ec@entry=0x55946da519c8, fname=fname@entry=94096135872160, wrap=wrap@entry=0) at load.c:611
#81 0x000055946cdd41f1 in rb_require_internal (fname=94096135872400, fname@entry=94096135872440, safe=0) at load.c:992
#82 0x000055946cdd4493 in rb_require_safe (safe=, fname=94096135872440) at load.c:1038
#83 rb_f_require (obj=, fname=94096135872440) at load.c:820
#84 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x5594708700a0, cc=, calling=, reg_cfp=0x7fc7bdc4e168, ec=0x55946da519c8) at vm_insnhelper.c:1928
#85 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e168, calling=, ci=0x5594708700a0, cc=) at vm_insnhelper.c:1944
#86 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4e168, calling=, ci=, cc=) at vm_insnhelper.c:2417
#87 0x000055946cf0e63e in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:797
#88 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#89 0x000055946cf035fc in invoke_block (captured=0x7fc7bdc4e490, opt_pc=, type=, cref=0x0, self=94096096426480, iseq=0x55946e49f0b8, ec=0x55946da519c8) at vm.c:1005
#90 invoke_iseq_block_from_c (ec=0x55946da519c8, captured=0x7fc7bdc4e490, self=94096096426480, argc=, argv=, passed_block_handler=0, cref=0x0, is_lambda=0) at vm.c:1057
#91 0x000055946cf04699 in invoke_block_from_c_bh (argc=, passed_block_handler=, cref=, is_lambda=, force_blockarg=, argv=, block_handler=, ec=) at vm.c:1075
#92 vm_yield (argc=1, argv=0x7ffd6f6cb938, ec=) at vm.c:1120
#93 rb_yield_0 (argv=0x7ffd6f6cb938, argc=1) at vm_eval.c:980
#94 rb_yield_1 (val=94096130169040) at vm_eval.c:986
#95 rb_yield (val=) at vm_eval.c:996
#96 0x000055946cf2113d in rb_ary_each (ary=94096076222560) at array.c:1820
#97 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946ed0d090, cc=, calling=, reg_cfp=0x7fc7bdc4e478, ec=0x55946da519c8) at vm_insnhelper.c:1928
#98 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e478, calling=, ci=0x55946ed0d090, cc=) at vm_insnhelper.c:1944
#99 0x000055946cf0cb05 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:716
#100 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#101 0x000055946cf035fc in invoke_block (captured=0x7fc7bdc4e500, opt_pc=, type=, cref=0x0, self=94096096426480, iseq=0x55946e49f298, ec=0x55946da519c8) at vm.c:1005
#102 invoke_iseq_block_from_c (ec=0x55946da519c8, captured=0x7fc7bdc4e500, self=94096096426480, argc=, argv=, passed_block_handler=0, cref=0x0, is_lambda=0) at vm.c:1057
#103 0x000055946cf04699 in invoke_block_from_c_bh (argc=, passed_block_handler=, cref=, is_lambda=, force_blockarg=, argv=, block_handler=, ec=) at vm.c:1075
#104 vm_yield (argc=1, argv=0x7ffd6f6cbdf8, ec=) at vm.c:1120
#105 rb_yield_0 (argv=0x7ffd6f6cbdf8, argc=1) at vm_eval.c:980
#106 rb_yield_1 (val=94096095502480) at vm_eval.c:986
#107 rb_yield (val=) at vm_eval.c:996
#108 0x000055946cf2113d in rb_ary_each (ary=94096095328480) at array.c:1820
#109 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946e8552a0, cc=, calling=, reg_cfp=0x7fc7bdc4e4e8, ec=0x55946da519c8) at vm_insnhelper.c:1928
#110 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e4e8, calling=, ci=0x55946e8552a0, cc=) at vm_insnhelper.c:1944
#111 0x000055946cf0cb05 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:716
#112 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#113 0x000055946cf06767 in vm_call0_body (ec=ec@entry=0x55946da519c8, calling=calling@entry=0x7ffd6f6cc2d0, ci=ci@entry=0x7ffd6f6cc2c0, cc=cc@entry=0x7ffd6f6cc2f0, argv=argv@entry=0x7ffd6f6cc390) at vm_eval.c:129
#114 0x000055946cf074b2 in vm_call0 (me=, argv=0x7ffd6f6cc390, argc=0, id=135807, recv=94096096186440, ec=0x55946da519c8) at vm_eval.c:60
#115 rb_call0 (ec=0x55946da519c8, recv=94096096186440, mid=135807, argc=, argv=argv@entry=0x8, scope=scope@entry=CALL_PUBLIC, self=94095993048320) at vm_eval.c:302
#116 0x000055946cf0a31a in rb_call (scope=CALL_PUBLIC, argv=0x8, argc=, mid=, recv=) at vm_eval.c:595
#117 rb_funcall_with_block (recv=, mid=, argc=argc@entry=0, argv=argv@entry=0x7ffd6f6cc390, passed_procval=passed_procval@entry=8) at vm_eval.c:857
#118 0x000055946ceb319c in rb_sym_proc_call (mid=, argc=argc@entry=1, argv=argv@entry=0x7ffd6f6cc388, passed_proc=passed_proc@entry=8) at string.c:10480
#119 0x000055946cf0477c in vm_yield_with_symbol (block_handler=0, argv=0x7ffd6f6cc388, argc=1, symbol=, ec=) at vm_insnhelper.c:2573
#120 invoke_block_from_c_bh (argc=, passed_block_handler=, cref=, is_lambda=, force_blockarg=, argv=, block_handler=, ec=) at vm.c:1084
#121 vm_yield (argc=1, argv=0x7ffd6f6cc388, ec=) at vm.c:1120
#122 rb_yield_0 (argv=0x7ffd6f6cc388, argc=1) at vm_eval.c:980
#123 rb_yield_1 (val=94096096186440) at vm_eval.c:986
#124 rb_yield (val=) at vm_eval.c:996
#125 0x000055946cf2113d in rb_ary_each (ary=94095993048320) at array.c:1820
#126 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x5594744d8280, cc=, calling=, reg_cfp=0x7fc7bdc4e590, ec=0x55946da519c8) at vm_insnhelper.c:1928
#127 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e590, calling=, ci=0x5594744d8280, cc=) at vm_insnhelper.c:1944
#128 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4e590, calling=, ci=, cc=) at vm_insnhelper.c:2417
#129 0x000055946cf0cb05 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:716
#130 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#131 0x000055946cf035fc in invoke_block (captured=0x7ffd6f6cc8e0, opt_pc=, type=, cref=0x559474604128, self=94096096426480, iseq=0x5594745027e8, ec=0x55946da519c8) at vm.c:1005
#132 invoke_iseq_block_from_c (ec=0x55946da519c8, captured=0x7ffd6f6cc8e0, self=94096096426480, argc=, argv=, passed_block_handler=0, cref=0x559474604128, is_lambda=0) at vm.c:1057
#133 0x000055946cf04520 in invoke_block_from_c_bh (ec=ec@entry=0x55946da519c8, block_handler=, argc=argc@entry=1, argv=argv@entry=0x7fc7bdb4f7f8, cref=, is_lambda=, is_lambda@entry=0, force_blockarg=0, passed_block_handler=0) at vm.c:1075
#134 0x000055946cf04958 in vm_yield_with_cref (is_lambda=0, cref=, argv=0x7fc7bdb4f7f8, argc=1, ec=0x55946da519c8) at vm.c:1112
#135 yield_under (under=94096093646040, self=, argc=1, argv=0x7fc7bdb4f7f8) at vm_eval.c:1572
#136 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946e5cd230, cc=, calling=, reg_cfp=0x7fc7bdc4e600, ec=0x55946da519c8) at vm_insnhelper.c:1928
#137 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e600, calling=, ci=0x55946e5cd230, cc=) at vm_insnhelper.c:1944
#138 0x000055946cf0cb05 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:716
#139 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#140 0x000055946cf035fc in invoke_block (captured=0x5594744c4fb0, opt_pc=, type=, cref=0x0, self=94095990659320, iseq=0x55946e192aa0, ec=0x55946da519c8) at vm.c:1005
#141 invoke_iseq_block_from_c (ec=0x55946da519c8, captured=0x5594744c4fb0, self=94095990659320, argc=, argv=, passed_block_handler=0, cref=0x0, is_lambda=0) at vm.c:1057
#142 0x000055946cf04699 in invoke_block_from_c_bh (argc=, passed_block_handler=, cref=, is_lambda=, force_blockarg=, argv=, block_handler=, ec=) at vm.c:1075
#143 vm_yield (argc=1, argv=0x7ffd6f6ccdc8, ec=) at vm.c:1120
#144 rb_yield_0 (argv=0x7ffd6f6ccdc8, argc=1) at vm_eval.c:980
#145 rb_yield_1 (val=94096094867920) at vm_eval.c:986
#146 rb_yield (val=) at vm_eval.c:996
#147 0x000055946cf2113d in rb_ary_each (ary=94096094867160) at array.c:1820
#148 0x000055946cf06829 in vm_call0_cfunc_with_frame (ci=0x7ffd6f6cce00, cc=0x7ffd6f6cce70, argv=0x7fc7bdb4f6b8, calling=0x7ffd6f6cce50, ec=0x55946da519c8) at vm_eval.c:87
#149 vm_call0_cfunc (argv=0x7fc7bdb4f6b8, cc=0x7ffd6f6cce70, ci=0x7ffd6f6cce00, calling=0x7ffd6f6cce50, ec=0x55946da519c8) at vm_eval.c:102
#150 vm_call0_body (ec=0x55946da519c8, calling=calling@entry=0x7ffd6f6ccec0, ci=ci@entry=0x7ffd6f6cceb0, cc=cc@entry=0x7ffd6f6ccee0, argv=0x7fc7bdb4f6b8) at vm_eval.c:133
#151 0x000055946cf06c50 in vm_call0 (me=, argv=, argc=, id=, recv=, ec=) at vm_eval.c:60
#152 rb_vm_call (ec=, recv=, id=, argc=, argv=, me=) at vm_eval.c:209
#153 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946dba2780, cc=, calling=, reg_cfp=0x7fc7bdc4e7c0, ec=0x55946da519c8) at vm_insnhelper.c:1928
#154 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e7c0, calling=, ci=0x55946dba2780, cc=) at vm_insnhelper.c:1944
#155 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4e7c0, calling=, ci=, cc=) at vm_insnhelper.c:2417
#156 0x000055946cf0cb05 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:716
#157 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#158 0x000055946cf118d1 in rb_iseq_eval (iseq=iseq@entry=0x55946dfed3a8) at vm.c:2046
#159 0x000055946cdd2164 in rb_load_internal0 (ec=ec@entry=0x55946da519c8, fname=fname@entry=94095988939080, wrap=wrap@entry=0) at load.c:611
#160 0x000055946cdd41f1 in rb_require_internal (fname=94095988939160, fname@entry=94095988939200, safe=0) at load.c:992
#161 0x000055946cdd4493 in rb_require_safe (safe=, fname=94095988939200) at load.c:1038
#162 rb_f_require (obj=, fname=94095988939200) at load.c:820
#163 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946dffa920, cc=, calling=, reg_cfp=0x7fc7bdc4e948, ec=0x55946da519c8) at vm_insnhelper.c:1928
#164 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e948, calling=, ci=0x55946dffa920, cc=) at vm_insnhelper.c:1944
#165 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4e948, calling=, ci=, cc=) at vm_insnhelper.c:2417
#166 0x000055946cf0b5c2 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:779
#167 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#168 0x000055946cf118d1 in rb_iseq_eval (iseq=iseq@entry=0x55946dfee438) at vm.c:2046
#169 0x000055946cdd2164 in rb_load_internal0 (ec=ec@entry=0x55946da519c8, fname=fname@entry=94095993039280, wrap=wrap@entry=0) at load.c:611
#170 0x000055946cdd41f1 in rb_require_internal (fname=fname@entry=94095993043840, safe=0) at load.c:992
#171 0x000055946cdd4493 in rb_require_safe (safe=, fname=94095993043840) at load.c:1038
#172 rb_f_require (obj=, fname=94095993043840) at load.c:820
#173 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946ea12160, cc=, calling=, reg_cfp=0x7fc7bdc4e9b8, ec=0x55946da519c8) at vm_insnhelper.c:1928
#174 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4e9b8, calling=, ci=0x55946ea12160, cc=) at vm_insnhelper.c:1944
#175 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4e9b8, calling=, ci=, cc=) at vm_insnhelper.c:2417
#176 0x000055946cf0b5c2 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:779
#177 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#178 0x000055946cf118d1 in rb_iseq_eval (iseq=iseq@entry=0x55946e3d7c48) at vm.c:2046
#179 0x000055946cdd2164 in rb_load_internal0 (ec=ec@entry=0x55946da519c8, fname=fname@entry=94095988920840, wrap=) at load.c:611
#180 0x000055946cdd2850 in rb_load_internal (wrap=0, fname=94095988920840) at load.c:642
#181 rb_f_load (argc=, argv=) at load.c:710
#182 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946e7c96e0, cc=, calling=, reg_cfp=0x7fc7bdc4ea28, ec=0x55946da519c8) at vm_insnhelper.c:1928
#183 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4ea28, calling=, ci=0x55946e7c96e0, cc=) at vm_insnhelper.c:1944
#184 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4ea28, calling=, ci=, cc=) at vm_insnhelper.c:2417
#185 0x000055946cf0b5c2 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:779
#186 0x000055946cf02f4c in vm_exec (ec=ec@entry=0x55946da519c8) at vm.c:1804
#187 0x000055946cf035fc in invoke_block (captured=0x7fc7bdc4eae8, opt_pc=, type=, cref=0x0, self=94095998891400, iseq=0x55946e4dae10, ec=0x55946da519c8) at vm.c:1005
#188 invoke_iseq_block_from_c (ec=0x55946da519c8, captured=0x7fc7bdc4eae8, self=94095998891400, argc=, argv=, passed_block_handler=0, cref=0x0, is_lambda=0) at vm.c:1057
#189 0x000055946cf04699 in invoke_block_from_c_bh (argc=, passed_block_handler=, cref=, is_lambda=, force_blockarg=, argv=, block_handler=, ec=) at vm.c:1075
#190 vm_yield (argc=1, argv=0x7ffd6f6ce8e8, ec=) at vm.c:1120
#191 rb_yield_0 (argv=0x7ffd6f6ce8e8, argc=1) at vm_eval.c:980
#192 rb_yield_1 (val=94095988924840) at vm_eval.c:986
#193 rb_yield (val=) at vm_eval.c:996
#194 0x000055946cf2113d in rb_ary_each (ary=94095988920960) at array.c:1820
#195 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946e421000, cc=, calling=, reg_cfp=0x7fc7bdc4ead0, ec=0x55946da519c8) at vm_insnhelper.c:1928
#196 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4ead0, calling=, ci=0x55946e421000, cc=) at vm_insnhelper.c:1944
#197 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4ead0, calling=, ci=, cc=) at vm_insnhelper.c:2417
#198 0x000055946cf0cb05 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:716
#199 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#200 0x000055946cf118d1 in rb_iseq_eval (iseq=iseq@entry=0x55946e35f2c0) at vm.c:2046
#201 0x000055946cdd2164 in rb_load_internal0 (ec=ec@entry=0x55946da519c8, fname=fname@entry=94095992643280, wrap=) at load.c:611
#202 0x000055946cdd2850 in rb_load_internal (wrap=0, fname=94095992643280) at load.c:642
#203 rb_f_load (argc=, argv=) at load.c:710
#204 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946e24bb20, cc=, calling=, reg_cfp=0x7fc7bdc4ec58, ec=0x55946da519c8) at vm_insnhelper.c:1928
#205 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4ec58, calling=, ci=0x55946e24bb20, cc=) at vm_insnhelper.c:1944
#206 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4ec58, calling=, ci=, cc=) at vm_insnhelper.c:2417
#207 0x000055946cf0b5c2 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:779
#208 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#209 0x000055946cf118d1 in rb_iseq_eval (iseq=iseq@entry=0x55946e3a7390) at vm.c:2046
#210 0x000055946cdd2164 in rb_load_internal0 (ec=ec@entry=0x55946da519c8, fname=fname@entry=94095993616120, wrap=) at load.c:611
#211 0x000055946cdd2850 in rb_load_internal (wrap=0, fname=94095993616120) at load.c:642
#212 rb_f_load (argc=, argv=) at load.c:710
#213 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946e6a00d0, cc=, calling=, reg_cfp=0x7fc7bdc4ecc8, ec=0x55946da519c8) at vm_insnhelper.c:1928
#214 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4ecc8, calling=, ci=0x55946e6a00d0, cc=) at vm_insnhelper.c:1944
#215 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4ecc8, calling=, ci=, cc=) at vm_insnhelper.c:2417
#216 0x000055946cf0b5c2 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:779
#217 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#218 0x000055946cf118d1 in rb_iseq_eval (iseq=iseq@entry=0x55946e470100) at vm.c:2046
#219 0x000055946cdd2164 in rb_load_internal0 (ec=ec@entry=0x55946da519c8, fname=fname@entry=94095993672200, wrap=) at load.c:611
#220 0x000055946cdd2850 in rb_load_internal (wrap=0, fname=94095993672200) at load.c:642
#221 rb_f_load (argc=, argv=) at load.c:710
#222 0x000055946cefb61f in vm_call_cfunc_with_frame (ci=0x55946e3306a0, cc=, calling=, reg_cfp=0x7fc7bdc4efa0, ec=0x55946da519c8) at vm_insnhelper.c:1928
#223 vm_call_cfunc (ec=0x55946da519c8, reg_cfp=0x7fc7bdc4efa0, calling=, ci=0x55946e3306a0, cc=) at vm_insnhelper.c:1944
#224 0x000055946cf03ea3 in vm_call_method (ec=0x55946da519c8, cfp=0x7fc7bdc4efa0, calling=, ci=, cc=) at vm_insnhelper.c:2417
#225 0x000055946cf0b5c2 in vm_exec_core (ec=ec@entry=0x55946da519c8, initial=initial@entry=0) at /tmp/ruby-build.20180216151216.13740/ruby-trunk/insns.def:779
#226 0x000055946cf02f4c in vm_exec (ec=0x55946da519c8) at vm.c:1804
#227 0x000055946cf119d5 in rb_iseq_eval_main (iseq=iseq@entry=0x55946e4bbba0) at vm.c:2057
#228 0x000055946cd83d54 in ruby_exec_internal (n=0x55946e4bbba0) at eval.c:247
#229 0x000055946cd87fdf in ruby_exec_node (n=0x55946e4bbba0) at eval.c:311
#230 ruby_run_node (n=) at eval.c:303
#231 0x000055946cd831bf in main (argc=22, argv=0x7ffd6f6d0148) at ./main.c:42

History

#1 Updated by rogerdpack (Roger Pack) almost 10 years ago

=begin
May have something to do with the terminal you're using
=end

#2 Updated by febuiles (Federico Builes) almost 10 years ago

=begin
Roger: This is part of the Rubyspecs test suite but that's why we push the items into it, do you think there's anything else we should check?
=end

#3 Updated by luislavena (Luis Lavena) almost 10 years ago

=begin
As Federico suggested, has nothing to do with the terminal emulation or console being used, but with the shared object being involved.

If you do a full GNU Readline linkage instead, the error goes away. I think is related to the macros it tries during the build process of the readline extension and the have_readline_header("editline/readline.h") and have_library("edit", "readline").
=end

#4 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
= summary

This problem was investigated.

As for GNU Readline's history_base and libedit's it, the treatment is different.
GNU Readline's history_base = libedit's history_base - 1.

= example

== GNU Readline

HIST_ENTRY *entry;

add_history("1");
add_history("2");
add_history("3");

entry = history_get(history_base);
printf("%s\n", entry->line); /* => 1 */

entry = history_get(history_base + 1);
printf("%s\n", entry->line); /* => 2 */

entry = history_get(history_base + 2);
printf("%s\n", entry->line); /* => 2 */

== Editline Library

HIST_ENTRY *entry;

add_history("1");
add_history("2");
add_history("3");

entry = history_get(history_base - 1);
printf("%s\n", entry->line); /* => 1 */

entry = history_get(history_base);
printf("%s\n", entry->line); /* => 2 */

entry = history_get(history_base + 1);
printf("%s\n", entry->line); /* => 3 */

= try

I created the patch for this problem.
Try the patch.

  1. Mac OSX 10.5(Leopard).
  2. apply patch to ruby 1.8.
  3. run configure with --enable-libedit.
  4. run make.
  5. run make install.
  6. run below command. $ ruby -rreadline -e 'puts Readline::VERSION; Readline::HISTORY.push("1", "2", "3"); Readline::HISTORY.each { |i| puts i }'

= environment

My environment.

  • Mac OSX: 10.5.3
  • ruby: ruby_1_8 branch(revision:18037, 2008-07-12 16:02:47 +0900 (Sat, 12 Jul 2008))
  • libedit: $NetBSD: readline.h,v 1.18 2006/08/21 12:45:30 christos Exp $

=end

#5 Updated by keita (Keita Yamaguchi) almost 10 years ago

=begin
山口と申します。

2008/7/17 Takao Kouji kouji@takao7.net:

どうも、ヒストリのインデックスの開始が、

  • GNU Readline は 1。(history_base と同じ)
  • libedit は 0。 という違いがあるようです。 このため、remove_historyなども同様に修正する必要がありました。 これは以下のコードで確認しました。

このコードを Ubuntu 8.04 の libedit で実行してみたのですが、
GNU ReadLine の結果と同一になりました。

% ./a.out
history_base: 1
added 1, 2, 3 to history
history_base: 1
history_length: 3
history_get(history_base): 1
history_get(0): NULL
history_get(1): 1
history_get(2): 2
history_get(3): 3

% ldd a.out
linux-gate.so.1 => (0xb7f91000)
libedit.so.2 => /usr/lib/libedit.so.2 (0xb7f53000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e04000)
libncurses.so.5 => /lib/libncurses.so.5 (0xb7dd3000)
/lib/ld-linux.so.2 (0xb7f92000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7dcf000)

それで不思議に思って少し調べてみました。
Ubuntu 8.04 の libedit は少し古くて libedit-2.9.cvs.20050518 といった感じです。
そこで http://www.thrysoee.dk/editline/ からダウンロードした
libedit-20080712-2.11.tar.gz を試したところ、
高尾さんの結果と同一になりました。

history_base: 1
added 1, 2, 3 to history
history_base: 1
history_length: 3
history_get(history_base): 2
history_get(0): 1
history_get(1): 2
history_get(2): 3
history_get(3): NULL

間違っていたら申し訳ないのですが、多分 2007/08/12 に入った
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libedit/readline.c.diff?r1=1.71&r2=1.72&sortby=date
の変更の影響ではないかと思われます。
特に

  • if (history(h, &ev, H_NEXT_EVENT, num))
  • if (history(h, &ev, H_NEXT_EVENT, num + 1))

のあたりが疑わしいと考えています。
これを元に戻してコンパイルし直したところ、
GNU Readline と同じ挙動になりました。

history_base: 1
added 1, 2, 3 to history
history_base: 1
history_length: 3
history_get(history_base): 1
history_get(0): NULL
history_get(1): 1
history_get(2): 2
history_get(3): 3

もしこれが正しいのだとすると、
libedit のバージョンによって挙動が変わることになるのではないかと思います。
ひょっとして Mac OSX のバージョンによっては古い libedit が入っていたりして、
高尾さんのパッチによって影響を受けてしまう可能性はありませんでしょうか。

私は Mac OSX 環境を持っていませんので調べることが出来ないのですが、
一応 10.4 あたりでも試してみた方が良いのではないかと思います。


山口慶太

=end

#6 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
高尾宏治です。

On 2008/07/17, at 5:38, Keita Yamaguchi wrote:

2008/7/17 Takao Kouji kouji@takao7.net:

どうも、ヒストリのインデックスの開始が、

  • GNU Readline は 1。(history_base と同じ)
  • libedit は 0。 という違いがあるようです。 このため、remove_historyなども同様に修正する必要がありました。 これは以下のコードで確認しました。

このコードを Ubuntu 8.04 の libedit で実行してみたのですが、
GNU ReadLine の結果と同一になりました。
(snip)
libedit のバージョンによって挙動が変わることになるのではないかと思います。
ひょっとして Mac OSX のバージョンによっては古い libedit が入っていたりして、
高尾さんのパッチによって影響を受けてしまう可能性はありませんでしょうか。

情報ありがとうございます。
libedit についてもう少し調査が必要ですね。

ヒストリに関する単体テストを書いてみて、
いろいろな環境でテストしてみたいと思います。

しかしながら、 libedit の各バージョンを試すのは面倒ですね。
Readline の初期化時に VERSION ではなく、
ヒストリの操作を試した結果、 offset を計算したほうがいいかもしれませんね。
# しかし、そうまでして libedit に対応する必要があるのだろうか。。。

=end

#7 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
高尾宏治です。

On 2008/07/17, at 9:21, M.Suzuki wrote:

私は Mac OSX 環境を持っていませんので調べることが出来ないのですが、
一応 10.4 あたりでも試してみた方が良いのではないかと思います。

試してみましたが、Mac OSX 10.4では(history_baseに関しては)
問題ないようです。

msuzuki$ uname -a
Darwin PowerBookG4.local 8.11.0 Darwin Kernel Version 8.11.0: Wed Oct
10 18:26:00 PDT 2007; root:xnu-792.24.17~1/RELEASE_PPC Power Macintosh
powerpc
msuzuki$ cc -o libedittest libedittest.c -ledit
msuzuki$ ./libedittest
history_base: 1 added 1, 2, 3 to history history_base: 1
history_length: 3
history_get(history_base): 1
history_get(0): NULL
history_get(1): NULL
history_get(2): NULL
history_get(3): NULL

history_get(0) から (3) までが全て NULL ですね。
これは奇妙ですね。
なんか Mac OSX 10.4 では Readline のヒストリの扱いが駄目な気がします。
これは回避できないかもしれません。
まいったな。

=end

#8 Updated by Anonymous almost 10 years ago

=begin
M.Suzukiと申します。

私は Mac OSX 環境を持っていませんので調べることが出来ないのですが、
一応 10.4 あたりでも試してみた方が良いのではないかと思います。

試してみましたが、Mac OSX 10.4では(history_baseに関しては)
問題ないようです。

msuzuki$ uname -a
Darwin PowerBookG4.local 8.11.0 Darwin Kernel Version 8.11.0: Wed Oct
10 18:26:00 PDT 2007; root:xnu-792.24.17~1/RELEASE_PPC Power Macintosh
powerpc
msuzuki$ cc -o libedittest libedittest.c -ledit
msuzuki$ ./libedittest
history_base: 1 added 1, 2, 3 to history history_base: 1
history_length: 3
history_get(history_base): 1
history_get(0): NULL
history_get(1): NULL
history_get(2): NULL
history_get(3): NULL

ちなみに、MacPortsのreadlineを使うと他と同じ結果になりました。

msuzuki$ cc -o libedittest libedittest.c -L/opt/local/lib -lreadline
msuzuki$ ./libedittest
history_base: 1
added 1, 2, 3 to history
history_base: 1
history_length: 3
history_get(history_base): 1
history_get(0): NULL
history_get(1): 1
history_get(2): 2
history_get(3): 3
--
M.Suzuki :: Idea -> Coffe -> (Code, Bug)
--

=end

#9 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
高尾宏治です。

# Subjectを変えます。

On 2008/07/16, at 15:33, Nobuyoshi Nakada wrote:

At Wed, 16 Jul 2008 11:45:06 +0900,
Shugo Maeda wrote in :

Ruby側でとりあえず対応するという点については異論はないのですが、
バグだとしたらバージョンによって挙動が変わったら嫌だなと思いました。

初期化のときにチェックするなら、バージョンが変わっても気にしなく
てすむと思います。

初期化の時にチェックするのも良さそうですね。
ただし、Readlineの拡張ライブラリの初期化時に、
毎回 libedit とリンクしているかどうかを確認するのは、
どうかということがあると思います。
これについては、Init_readline()で以下のような処理をすると思うのですが、
対したコストではないため、気にしなくても良いのかもしれません。

if (strncmp(rl_library_version, "EditLine wrapper",
strlen("EditLine wrapper")) == 0) {
/* libedit の場合の処理 /
}
else {
/
libedit の場合の処理 */
}

高尾君のパッチと大分趣が異なるような気がするのですが、どういう意図でしょうか。

history_baseの初期値を保存しておいて、そこからの差分で見るという
ことです。

自分がlibeditの挙動を理解していないだけかもしれないのですが、それで上手く
動くのでしょうか。
高尾君のパッチではたんにhistory_baseをhistory_base - 1にしているだけだった
ので、libeditではhistory_baseの値が1ずれているとかそういう話なのかなと思った
のですが。

そのズレの値を初期状態でとれないかと思ったのですが、初期値はずれ
ているわけではないとしたら的外れかもしれません。後は、
remove_history()があるならですが、のテストコード
を実行してみるとかしかないですね。

ついでにいえば、remove_history()やreplace_history_entry()も同じ
くindexをとるわけですが、こちらは問題ないんでしょうか。

問題がありました。
どうも、ヒストリのインデックスの開始が、

  • GNU Readline は 1。(history_base と同じ)
  • libedit は 0。 という違いがあるようです。 このため、remove_historyなども同様に修正する必要がありました。 これは以下のコードで確認しました。 ----- ここから ----- #include

#ifdef HAVE_EDITLINE_READLINE_H
#include
#else
#include
#include
#endif /* HAVE_EDITLINE_READLINE_H */

int main(int argc, char **argv)
{
HIST_ENTRY *entry;
int i;

using_history();

printf("history_base: %d\n", history_base);

add_history("1");
add_history("2");
add_history("3");

printf("added 1, 2, 3 to history\n");
printf("history_base: %d\n", history_base);
printf("history_length: %d\n", history_length);

entry = history_get(history_base);
printf("history_get(history_base): %s\n", entry->line);

for (i = 0; i <= history_length; i++) {
entry = history_get(i);
printf("history_get(%d): %s\n", i, entry ? entry->line : "NULL");
}

return 0;
}
----- ここまで -----

以下、GNU Readline、Mac OSX の libedit、
libedit の 20080712-2.11 で実行した結果です。
----- ここから -----
---- no212_on-macosx.gnu_readline ----
history_base: 1
added 1, 2, 3 to history
history_base: 1
history_length: 3
history_get(history_base): 1
history_get(0): NULL
history_get(1): 1
history_get(2): 2
history_get(3): 3
---- no212_on-macosx.editline ----
history_base: 1
added 1, 2, 3 to history
history_base: 1
history_length: 3
history_get(history_base): 2
history_get(0): 1
history_get(1): 2
history_get(2): 3
history_get(3): NULL
---- no212_on-macosx.editline_20080712-2.11 ----
history_base: 1
added 1, 2, 3 to history
history_base: 1
history_length: 3
history_get(history_base): 2
history_get(0): 1
history_get(1): 2
history_get(2): 3
history_get(3): NULL
----- ここまで -----

最後にこれまでの話などを考慮したパッチを作成しました。
実行時に libedit であれば index のオフセットを 0 に、
そうでない(GNU Readline であれば) オフセットを history_base に
設定するようにしています。

Mac OSX 10.5.4(昨日10.5.3からアップデートしました)の環境で、
動作を確認しています。

$ ~/local/bin/ruby19trunk -rreadline -ve 'puts Readline::VERSION; Readline::HISTORY.push("1", "2", "3"); Readline::HISTORY.each { |s| puts s }; p Readline::HISTORY[1]; Readline::HISTORY[1] = "A" ; p Readline::HISTORY[1]; Readline::HISTORY.delete_at(0); p Readline::HISTORY[0]; p Readline::HISTORY.length; p Readline::HISTORY.pop; p Readline::HISTORY.pop; p Readline::HISTORY.pop; '
ruby 1.9.0 (2008-07-16 revision 18071) [i686-darwin9.4.0]
EditLine wrapper
1
2
3
"2"
"A"
"A"
2
"3"
"A"
nil

----- ここから -----
Index: ext/readline/readline.c
===================================================================
--- ext/readline/readline.c (revision 18084)
+++ ext/readline/readline.c (working copy)
@@ -43,6 +43,8 @@
# define rl_completion_matches completion_matches
#endif

+static int history_offset = 0;
+
static char **readline_attempted_completion_function(const char *text,
int start, int end);

@@ -516,7 +518,7 @@
if (i < 0) {
i += history_length;
}

  • entry = history_get(history_base + i);
  • entry = history_get(i + history_offset); if (entry == NULL) { rb_raise(rb_eIndexError, "invalid index"); } @@ -536,7 +538,7 @@ if (i < 0) { i += history_length; }
  • entry = replace_history_entry(i, RSTRING_PTR(str), NULL);
  • entry = replace_history_entry(i + history_offset, RSTRING_PTR(str), NULL);
    if (entry == NULL) {
    rb_raise(rb_eIndexError, "invalid index");
    }
    @@ -578,7 +580,7 @@
    VALUE val;

    rb_secure(4);

  • entry = remove_history(index);

  • entry = remove_history(index + history_offset);
    if (entry) {
    val = rb_tainted_str_new2(entry->line);
    free(entry->line);
    @@ -624,7 +626,7 @@

    rb_secure(4);
    for (i = 0; i < history_length; i++) {

  •    entry = history_get(history_base + i);
    
  •    entry = history_get(i + history_offset);
      if (entry == NULL)
          break;
    

    rb_yield(rb_tainted_str_new2(entry->line));
    @@ -795,6 +797,10 @@
    rb_define_const(mReadline, "USERNAME_COMPLETION_PROC", ucomp);
    #if defined HAVE_RL_LIBRARY_VERSION
    rb_define_const(mReadline, "VERSION", rb_str_new2(rl_library_version));

  • if (strncmp(rl_library_version, "EditLine wrapper",

  •  strlen("EditLine wrapper")) != 0) {
    
  • history_offset = history_base;

  • }
    #else
    rb_define_const(mReadline, "VERSION", rb_str_new2("2.0 or prior version"));
    #endif

=end

#10 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
高尾宏治です。

On 2008/07/17, at 9:16, Takao Kouji wrote:

On 2008/07/17, at 5:38, Keita Yamaguchi wrote:

2008/7/17 Takao Kouji kouji@takao7.net:

どうも、ヒストリのインデックスの開始が、

  • GNU Readline は 1。(history_base と同じ)
  • libedit は 0。 という違いがあるようです。 このため、remove_historyなども同様に修正する必要がありました。 これは以下のコードで確認しました。

このコードを Ubuntu 8.04 の libedit で実行してみたのですが、
GNU ReadLine の結果と同一になりました。
(snip)
libedit のバージョンによって挙動が変わることになるのではないかと思います。
ひょっとして Mac OSX のバージョンによっては古い libedit が入っていたりして、
高尾さんのパッチによって影響を受けてしまう可能性はありませんでしょうか。

情報ありがとうございます。
libedit についてもう少し調査が必要ですね。

ヒストリに関する単体テストを書いてみて、
いろいろな環境でテストしてみたいと思います。

ということで、Readline::HISTORYに対する単体テストを作成しました。
Readline::HISTORYの全てのメソッドのテストを記述しています。
本メールの下部に記述します。

このテストを GNU Readline と Mac OSX 10.5 の libedit で
実行した結果を以下に示します。

----- ここから -----
GNU Readline
~/work/ruby/ruby_1_9 $ ./ruby19trunk -Iext/readline/gnu-readline test/readline/test_readline_history.rb
Loaded suite test/readline/test_readline_history
Started
.................
Finished in 0.004555 seconds.

17 tests, 159 assertions, 0 failures, 0 errors

libedit
~/work/ruby/ruby_1_9 $ ./ruby19trunk -Iext/readline/editline test/readline/test_readline_history.rb
Loaded suite test/readline/test_readline_history
Started
..F..FEF..EEFFF..
Finished in 0.017272 seconds.

1) Failure:
test_each(Readline::TestHistory)
[test/readline/test_readline_history.rb:144:in block in test_each'
test/readline/test_readline_history.rb:142:in
each'
test/readline/test_readline_history.rb:142:in `test_each']:
<"1:a"> expected but was
<"2:b">.

2) Failure:
test_get(Readline::TestHistory)
[test/readline/test_readline_history.rb:22:in block in test_get'
test/readline/test_readline_history.rb:21:in
each'
test/readline/test_readline_history.rb:21:in each_with_index'
test/readline/test_readline_history.rb:21:in
test_get']:
<"1:a"> expected but was
<"2:b">.

3) Error:
test_get_negative(Readline::TestHistory):
IndexError: invalid index
test/readline/test_readline_history.rb:29:in []'
test/readline/test_readline_history.rb:29:in
block in test_get
negative'
test/readline/test_readline_history.rb:28:in each'
test/readline/test_readline_history.rb:28:in
test_get
_negative'

4) Failure:
test_get_out_of_range(Readline::TestHistory)
[test/readline/test_readline_history.rb:37:in `block in test_get
out_of_range'
test/readline/test_readline_history.rb:36:in each'
test/readline/test_readline_history.rb:36:in
test_get
_out_of_range']:
i=<-6>.
exception expected but none was thrown.

5) Error:
test_push(Readline::TestHistory):
IndexError: invalid index
test/readline/test_readline_history.rb:85:in []'
test/readline/test_readline_history.rb:85:in
block in test_push'
test/readline/test_readline_history.rb:83:in times'
test/readline/test_readline_history.rb:83:in
test_push'

6) Error:
test_push_operator(Readline::TestHistory):
IndexError: invalid index
test/readline/test_readline_history.rb:93:in []'
test/readline/test_readline_history.rb:93:in
block in test_push
operator'
test/readline/test_readline_history.rb:91:in times'
test/readline/test_readline_history.rb:91:in
test_push
_operator'

7) Failure:
test_push_plural(Readline::TestHistory)
[test/readline/test_readline_history.rb:101:in `block in test_push
plural'
test/readline/test_readline_history.rb:100:in each'
test/readline/test_readline_history.rb:100:in
test_push
_plural']:
<"0"> expected but was
<"1">.

8) Failure:
test_set(Readline::TestHistory)
[test/readline/test_readline_history.rb:56:in block in test_set'
test/readline/test_readline_history.rb:53:in
times'
test/readline/test_readline_history.rb:53:in `test_set']:
<"set: 0"> expected but was
<"2:b">.

9) Failure:
test_set_out_of_range(Readline::TestHistory)
[test/readline/test_readline_history.rb:68:in `block in test_set
out_of_range'
test/readline/test_readline_history.rb:67:in each'
test/readline/test_readline_history.rb:67:in
test_set
_out_of_range']:
index=<-6>.
exception expected but none was thrown.

17 tests, 98 assertions, 6 failures, 3 errors
----- ここまで -----

これからテストが通るようにext/readline/readline.cを修正します。

以下、パッチ。
----- ここから -----
Index: test/readline/test_readline_history.rb
===================================================================
--- test/readline/test_readline_history.rb (revision 0)
+++ test/readline/test_readline_history.rb (revision 0)
@@ -0,0 +1,238 @@
+begin

  • require "readline" +rescue LoadError +else
  • require "test/unit" +end + +class Readline::TestHistory < Test::Unit::TestCase
  • include Readline +
  • def setup
  • clear_history
  • end
  • def test_to_s
  • assert_equal("HISTORY", HISTORY.to_s)
  • end +
  • def test_get
  • lines = push_history(5)
  • lines.each_with_index do |s, i|
  • assert_equal(s, HISTORY[i])
  • end
  • end +
  • def test_get__negative
  • lines = push_history(5)
  • (1..5).each do |i|
  • assert_equal(lines[-i], HISTORY[-i])
  • end
  • end +
  • def test_get__out_of_range
  • lines = push_history(5)
  • invalid_indexes = [5, 6, 100, -6, -7, -100]
  • invalid_indexes.each do |i|
  • assert_raise(IndexError, "i=<#{i}>") do
  • HISTORY[i]
  • end
  • end

  • invalid_indexes = [100_000_000_000_000_000_000,
  • -100_000_000_000_000_000_000]
  • invalid_indexes.each do |i|
  • assert_raise(RangeError, "i=<#{i}>") do
  • HISTORY[i]
  • end
  • end
  • end +
  • def test_set
  • lines = push_history(5)
  • 5.times do |i|
  • expected = "set: #{i}"
  • HISTORY[i] = expected
  • assert_equal(expected, HISTORY[i])
  • end
  • end +
  • def test_set__out_of_range
  • assert_raise(IndexError, "index=") do
  • HISTORY[0] = "set: 0"
  • end

  • lines = push_history(5)
  • invalid_indexes = [5, 6, 100, -6, -7, -100]
  • invalid_indexes.each do |i|
  • assert_raise(IndexError, "index=<#{i}>") do
  • HISTORY[i] = "set: #{i}"
  • end
  • end

  • invalid_indexes = [100_000_000_000_000_000_000,
  • -100_000_000_000_000_000_000]
  • invalid_indexes.each do |i|
  • assert_raise(RangeError, "index=<#{i}>") do
  • HISTORY[i] = "set: #{i}"
  • end
  • end
  • end +
  • def test_push
  • 5.times do |i|
  • assert_equal(HISTORY, HISTORY.push(i.to_s))
  • assert_equal(i.to_s, HISTORY[i])
  • end
  • assert_equal(5, HISTORY.length)
  • end +
  • def test_push__operator
  • 5.times do |i|
  • assert_equal(HISTORY, HISTORY << i.to_s)
  • assert_equal(i.to_s, HISTORY[i])
  • end
  • assert_equal(5, HISTORY.length)
  • end +
  • def test_push__plural
  • assert_equal(HISTORY, HISTORY.push("0", "1", "2", "3", "4"))
  • (0..4).each do |i|
  • assert_equal(i.to_s, HISTORY[i])
  • end
  • assert_equal(5, HISTORY.length) +
  • assert_equal(HISTORY, HISTORY.push("5", "6", "7", "8", "9"))
  • (5..9).each do |i|
  • assert_equal(i.to_s, HISTORY[i])
  • end
  • assert_equal(10, HISTORY.length)
  • end +
  • def test_pop
  • assert_equal(nil, HISTORY.pop)

  • lines = push_history(5)
  • (1..5).each do |i|
  • assert_equal(lines[-i], HISTORY.pop)
  • assert_equal(lines.length - i, HISTORY.length)
  • end

  • assert_equal(nil, HISTORY.pop)
  • end +
  • def test_shift
  • assert_equal(nil, HISTORY.shift)

  • lines = push_history(5)
  • (0..4).each do |i|
  • assert_equal(lines[i], HISTORY.shift)
  • assert_equal(lines.length - (i + 1), HISTORY.length)
  • end

  • assert_equal(nil, HISTORY.shift)
  • end +
  • def test_each
  • HISTORY.each do |s|
  • assert(false) # not reachable
  • end
  • lines = push_history(5)
  • i = 0
  • HISTORY.each do |s|
  • assert_equal(HISTORY[i], s)
  • assert_equal(lines[i], s)
  • i += 1
  • end
  • end +
  • def test_each__enumerator
  • e = HISTORY.each
  • assert_instance_of(Enumerable::Enumerator, e)
  • end +
  • def test_length
  • assert_equal(0, HISTORY.length)
  • push_history(1)
  • assert_equal(1, HISTORY.length)
  • push_history(4)
  • assert_equal(5, HISTORY.length)
  • clear_history
  • assert_equal(0, HISTORY.length)
  • end +
  • def test_empty_p
  • 2.times do
  • assert(HISTORY.empty?)
  • HISTORY.push("s")
  • assert_equal(false, HISTORY.empty?)
  • HISTORY.pop
  • assert(HISTORY.empty?)
  • end
  • end +
  • def test_delete_at
  • lines = push_history(5)
  • (0..4).each do |i|
  • assert_equal(lines[i], HISTORY.delete_at(0))
  • end
  • assert(HISTORY.empty?) +
  • lines = push_history(5)
  • (1..5).each do |i|
  • assert_equal(lines[lines.length - i], HISTORY.delete_at(-1))
  • end
  • assert(HISTORY.empty?) +
  • lines = push_history(5)
  • assert_equal(lines[0], HISTORY.delete_at(0))
  • assert_equal(lines[4], HISTORY.delete_at(3))
  • assert_equal(lines[1], HISTORY.delete_at(0))
  • assert_equal(lines[3], HISTORY.delete_at(1))
  • assert_equal(lines[2], HISTORY.delete_at(0))
  • assert(HISTORY.empty?)
  • end +
  • def test_delete_at__out_of_range
  • assert_raise(IndexError, "index=") do
  • HISTORY.delete_at(0)
  • end

  • lines = push_history(5)
  • invalid_indexes = [5, 6, 100, -6, -7, -100]
  • invalid_indexes.each do |i|
  • assert_raise(IndexError, "index=<#{i}>") do
  • HISTORY.delete_at(i)
  • end
  • end

  • invalid_indexes = [100_000_000_000_000_000_000,
  • -100_000_000_000_000_000_000]
  • invalid_indexes.each do |i|
  • assert_raise(RangeError, "index=<#{i}>") do
  • HISTORY.delete_at(i)
  • end
  • end
  • end +
  • private +
  • def push_history(num)
  • lines = []
  • num.times do |i|
  • s = "a"
  • i.times do
  • s = s.succ
  • end
  • lines.push("#{i + 1}:#{s}")
  • end
  • HISTORY.push(*lines)
  • return lines
  • end +
  • def clear_history
  • while HISTORY.pop
  • end
  • assert(HISTORY.empty?)
  • end +end if defined?(::Readline) && defined?(::Readline::HISTORY)

=end

#11 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
高尾宏治です。

On 2008/07/19, at 9:24, Takao Kouji wrote:

ということで、Readline::HISTORYに対する単体テストを作成しました。
Readline::HISTORYの全てのメソッドのテストを記述しています。

今回の問題に対応するためのパッチを作成しました。
# テストがあるっていいですね。

パッチの概要を次に述べます。

  • GNU Readline を使用した場合の挙動は一切変えません。(変えないように実装したつもりです。)
  • パッチの適用前のReadlineモジュールには、 EditLine(libedit) を使用する場合のみ次の問題があります。
    • libedit のバージョン (2.9より上?) によっては、 history_get 関数で指定するインデックスは 0 から始まる。 history_base からではない。 これが原因で、 Readline::HISTORY ではユーザからの最初の入力を取得できない。
    • history_get 関数で -1 を指定すると 0 番目の history を取得する。 GNU Readline では NULL である。 これが原因で、 Readline::HISTORY[-100] では IndexError 例外が発生しない。
    • replace_history_entry 関数で -1 を指定すると 0 番目の history を操作する。 GNU Readline では操作できない。 これが原因で、 Readline::HISTORY[-100] = "abc" などにより 0 番目の history を操作してしまう。
  • 上記を回避するため、次のことを行う。
    • Init_readline 関数で libedit かどうかを判定する。
    • libedit であれば、 history の操作時の最初のインデックスの番号が history_base か 0 かを調査する。
    • 上記の情報を hist_get (Readline::HISTORY[] -> string | nil) で使用する。
    • また、 hist_get や hist_set (Readline::HISTORY[index] = string) で Ruby で index が負の値かどうかチェックする。

なお、パッチの概要は前田さんとも情報共有できていると思うのですが、
実際のパッチの内容まではまだ見ていただいてない状態です。
お手数ですが、確認をお願いします。 > 前田さん

私の手元の環境である Mac OSXのlibedit、
Mac OSX で MacPorts で入れた GNU Readline 5.2 でしか
動作を確認できていません。
そこで、 で報告があった Ubuntu 8.04 の libedit や
Mac OSX 10.4 の libedit で試していただける方を募集します。

試す方法を以下に書きます。

  1. ruby の trunk を用意する。
  2. このメールのパッチと のパッチを当てる。 $ cd /path/to/ruby/trunk $ patch -p0 < /path/to/patch
  3. configure に --with-libedit を付けて実行する。 $ ./configure --with-libedit
  4. make
  5. 単体テストの実行。 $ ./ruby -I.ext/ -rreadline \ test/readline/test_readline_history.rb

上記のテストがパスできれば OK です。
パスできなかった場合は教えてください。がんばります。

以下、パッチです。
----- ここから -----
Index: readline.c
===================================================================
--- readline.c (revision 18084)
+++ readline.c (working copy)
@@ -29,6 +29,8 @@

static VALUE mReadline;

+#define EDIT_LINE_LIBRARY_VERSION "EditLine wrapper"
+
#define COMPLETION_PROC "completion_proc"
#define COMPLETION_CASE_FOLD "completion_case_fold"
static ID completion_proc, completion_case_fold;
@@ -43,6 +45,8 @@
# define rl_completion_matches completion_matches
#endif

+static int (*history_get_offset_func)(int);
+
static char **readline_attempted_completion_function(const char *text,
int start, int end);

@@ -505,10 +509,22 @@
return rb_str_new2("HISTORY");
}

+static int
+history_get_offset_history_base(int offset)
+{

  • return history_base + offset; +} + +static int +history_get_offset_0(int offset) +{
  • return offset; +} + static VALUE hist_get(VALUE self, VALUE index) {
  • HIST_ENTRY *entry;
  • HIST_ENTRY *entry = NULL;
    int i;

    rb_secure(4);
    @@ -516,7 +532,9 @@
    if (i < 0) {
    i += history_length;
    }

  • entry = history_get(history_base + i);

  • if (i >= 0) {

  • entry = history_get(history_get_offset_func(i));

  • }
    if (entry == NULL) {
    rb_raise(rb_eIndexError, "invalid index");
    }
    @@ -527,7 +545,7 @@
    hist_set(VALUE self, VALUE index, VALUE str)
    {
    #ifdef HAVE_REPLACE_HISTORY_ENTRY

  • HIST_ENTRY *entry;

  • HIST_ENTRY *entry = NULL;
    int i;

    rb_secure(4);
    @@ -536,7 +554,9 @@
    if (i < 0) {
    i += history_length;
    }

  • entry = replace_history_entry(i, RSTRING_PTR(str), NULL);

  • if (i >= 0) {

  • entry = replace_history_entry(i, RSTRING_PTR(str), NULL);

  • }
    if (entry == NULL) {
    rb_raise(rb_eIndexError, "invalid index");
    }
    @@ -581,7 +601,7 @@
    entry = remove_history(index);
    if (entry) {
    val = rb_tainted_str_new2(entry->line);

  •    free(entry->line);
    
  •    free((void *) entry->line);
      free(entry);
      return val;
    

    }
    @@ -624,7 +644,7 @@

    rb_secure(4);
    for (i = 0; i < history_length; i++) {

  •    entry = history_get(history_base + i);
    
  •    entry = history_get(history_get_offset_func(i));
      if (entry == NULL)
          break;
    

    rb_yield(rb_tainted_str_new2(entry->line));
    @@ -793,8 +813,17 @@
    rb_define_singleton_method(ucomp, "call",
    username_completion_proc_call, 1);
    rb_define_const(mReadline, "USERNAME_COMPLETION_PROC", ucomp);

  • history_get_offset_func = history_get_offset_history_base;
    #if defined HAVE_RL_LIBRARY_VERSION
    rb_define_const(mReadline, "VERSION", rb_str_new2(rl_library_version));

  • if (strncmp(rl_library_version, EDIT_LINE_LIBRARY_VERSION,

  •  strlen(EDIT_LINE_LIBRARY_VERSION)) == 0) {
    
  • add_history("1");

  • if (history_get(history_get_offset_func(0)) == NULL) {

  •  history_get_offset_func = history_get_offset_0;
    
  • }

  • clear_history();

  • }
    #else
    rb_define_const(mReadline, "VERSION", rb_str_new2("2.0 or prior version"));
    #endif

=end

#12 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
高尾宏治です。

間違えがありました。

On 2008/07/19, at 23:05, Takao Kouji wrote:

試す方法を以下に書きます。

  1. ruby の trunk を用意する。
  2. このメールのパッチと のパッチを当てる。 $ cd /path/to/ruby/trunk $ patch -p0 < /path/to/patch
  3. configure に --with-libedit を付けて実行する。 $ ./configure --with-libedit

--with-libeditではなく、--enable-libeditでした。
失礼しました。

  1. make
  2. 単体テストの実行。 $ ./ruby -I.ext/ -rreadline \ test/readline/test_readline_history.rb

上記のテストがパスできれば OK です。
パスできなかった場合は教えてください。がんばります。

=end

#13 Updated by keita (Keita Yamaguchi) almost 10 years ago

=begin
山口と申します。

2008/7/19 Takao Kouji kouji@takao7.net:

私の手元の環境である Mac OSXのlibedit、
Mac OSX で MacPorts で入れた GNU Readline 5.2 でしか
動作を確認できていません。
そこで、 で報告があった Ubuntu 8.04 の libedit や
Mac OSX 10.4 の libedit で試していただける方を募集します。

Ubuntu 8.04 において

  • GNU Readline 5.2
  • libedit(2.9.cvs.20050518)

に対するテストを実施致しましたので状況を報告致します。

  1. GNU Readline 5.2

keita% ./ruby -I .ext/i686-linux/ -rreadline
test/readline/test_readline_history.rb
Loaded suite test/readline/test_readline_history
Started
.................
Finished in 0.047366958 seconds.

17 tests, 159 assertions, 0 failures, 0 errors

以上、Ubuntu 8.04 の GNU Readline 5.2 では一切問題ありません。

  1. libedit(2.9.cvs.20050518)

Loaded suite test/readline/test_readline_history
Started
EEEEEEEEEEEEEEEEE
Finished in 0.001803326 seconds.

1) Error:
test_delete_at(Readline::TestHistory):
NotImplementedError: pop() function is unimplemented on this machine
test/readline/test_readline_history.rb:234:in pop'
test/readline/test_readline_history.rb:234:in
clear_history'
test/readline/test_readline_history.rb:12:in `setup'

以下17まで同様なので略しますが、以上のように全てのテストに失敗します。

このエラーの原因は、
setup から HISTORY.pop が呼ばれる際に最終的に remove_history が呼ばれるのですが、
remove_history は Ubuntu 8.04 の 2.9.cvs.20050518 版に存在しないからです
(libedit に remove_history が追加されたのは 2005/07/14 になります)。

参考までに --enable-libedit した場合に生成される extconf.h の内容は次のようになります。

keita% cat ext/readline/extconf.h
#ifndef EXTCONF_H
#define EXTCONF_H
#define HAVE_EDITLINE_READLINE_H 1
#define HAVE_RL_COMPLETION_MATCHES 1
#define HAVE_RL_DEPREP_TERM_FUNCTION 1
#define HAVE_RL_COMPLETION_APPEND_CHARACTER 1
#define HAVE_RL_BASIC_WORD_BREAK_CHARACTERS 1
#define HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS 1
#define HAVE_RL_COMPLETER_QUOTE_CHARACTERS 1
#define HAVE_RL_ATTEMPTED_COMPLETION_OVER 1
#define HAVE_RL_LIBRARY_VERSION 1
#endif

このように HAVE_REMOVE_HISTORY が存在しないため、
rb_remove_history において rb_notimplement が呼ばれます。
このためにテストの setup 時において1-17の全てが失敗します。

remove_history に限らず、
2.9.cvs.20050518 では他にもいくつかヒストリ系の関数が欠けているようです。
このため Ubuntu 8.04 のように古い libedit を使用している環境では、
ひょっとするとヒストリ系の操作はそもそもうまくいかないのかも知れません。

以上です。
現実的には Ubuntu における libedit の状況を考慮する
必要性は一切ないと思いますが、一応報告致します。


山口慶太

=end

#14 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
高尾宏治です。

On 2008/07/20, at 15:04, Keita Yamaguchi wrote:

Ubuntu 8.04 において

  • GNU Readline 5.2
  • libedit(2.9.cvs.20050518)

に対するテストを実施致しましたので状況を報告致します。

作業いただき、ありがとうございます。

  1. libedit(2.9.cvs.20050518)

Loaded suite test/readline/test_readline_history
Started
EEEEEEEEEEEEEEEEE
Finished in 0.001803326 seconds.

1) Error:
test_delete_at(Readline::TestHistory):
NotImplementedError: pop() function is unimplemented on this machine
test/readline/test_readline_history.rb:234:in pop'
test/readline/test_readline_history.rb:234:in
clear_history'
test/readline/test_readline_history.rb:12:in `setup'

以下17まで同様なので略しますが、以上のように全てのテストに失敗します。

このエラーの原因は、
setup から HISTORY.pop が呼ばれる際に最終的に remove_history が呼ばれるのですが、
remove_history は Ubuntu 8.04 の 2.9.cvs.20050518 版に存在しないからです
(libedit に remove_history が追加されたのは 2005/07/14 になります)。

remove_history がない環境があるのですね。
というか、Readlineモジュールはないのを想定した実装になっているので、
対応しないといけなかったですね。

そのような環境でのテスト内容を検討する必要がありますね。
選択肢としては以下のものを考えました。

  1. そのような環境では入力履歴のテストを行わない。
  2. remove_history のテストはしない。 clear_history が使えるかどうかを確認し、これを使うことで最低限のテストを行う。

いまのところ、後者で対応したいと考えています。
まずは、clear_history があるかどうかの確認してみます。
あるようならば、 Readline::HISTORY.clear メソッドを追加したいと考えています。
# この提案が通るかどうかは分かりませんが...

また、その他のReadline::HISTORYのメソッドも、
例外NotImplementErrorの発生を考慮したテストに修正します。

しかし、私はなかなか面倒な問題に手を出してしまったのですね。

=end

#15 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
高尾宏治です。

On 2008/07/22, at 12:55, M.Suzuki wrote:

試してみました。
(snip)
やっと目的(?)の結果が得られました。

msuzuki$ ./ruby -I.ext/powerpc-darwin8.11.0 -rreadline test/readline/test_readline_history.rb
Loaded suite test/readline/test_readline_history
Started
EEEEEEEEEEEEEEEEE
Finished in 0.014429 seconds.

1) Error:
test_delete_at(Readline::TestHistory):
NotImplementedError: pop() function is unimplemented on this machine
test/readline/test_readline_history.rb:234:in pop'
test/readline/test_readline_history.rb:234:in
clear_history'
test/readline/test_readline_history.rb:12:in `setup'
...

ext/readline/extconf.h の内容も念のため貼っておきます。

#ifndef EXTCONF_H
#define EXTCONF_H
#define HAVE_READLINE_READLINE_H 1
#define HAVE_RL_DEPREP_TERM_FUNCTION 1
#define HAVE_RL_COMPLETION_APPEND_CHARACTER 1
#define HAVE_RL_BASIC_WORD_BREAK_CHARACTERS 1
#define HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS 1
#define HAVE_RL_COMPLETER_QUOTE_CHARACTERS 1
#define HAVE_RL_LIBRARY_VERSION 1
#endif

定義関数は更に少ないです。かなり古いバージョンのようです。

同僚のはからいで、Mac OSX 10.4のアカウントをもらいました。
私の手元でも動作を確認してみます。

ただ、Readlineモジュールの入力履歴を扱うメソッドは、
例外NotImplementedErrorが発生するかもしれないので、
それに対応したテストを記述する必要がありました。
現在、この作業中です。

この作業が終わったら、パッチを本MLに報告する予定です。
Mac OSX 10.4の環境でもテストしてみます。

それと、Mac OSX 10.4 の ruby は、
Readlineモジュールを無効にしているのですね。
$ ruby -v -rreadline -e 'Readline'
ruby 1.8.2 (2004-12-25) [universal-darwin8.0]
ruby: No such file to load -- readline (LoadError)

=end

#16 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
高尾宏治です。

On 2008/07/23, at 23:14, Takao Kouji wrote:

ただ、Readlineモジュールの入力履歴を扱うメソッドは、
例外NotImplementedErrorが発生するかもしれないので、
それに対応したテストを記述する必要がありました。
現在、この作業中です。

この作業が終わったら、パッチを本MLに報告する予定です。

テストを修正しました。
本メールの下部にパッチを記述しています。
これまでのパッチをいったんrevertしてから試してください。

今回のパッチには、
$SAFE = 4のときの例外SecurityErrorが発生することを確認するためのテストを追加しています。
あと、入力履歴をクリアするReadline::HISTORY.clearメソッドを追加しています。

Mac OSX 10.4の環境でもテストしてみます。

まだ、Mac OSX 10.4でのテストはまで作業していません。
あとで作業する予定です。(が、作業していただけると助かります。)
しかしながら、の以下の記述から推測すると、
テストに失敗することが想定されます。

msuzuki$ uname -a
Darwin PowerBookG4.local 8.11.0 Darwin Kernel Version 8.11.0: Wed Oct
10 18:26:00 PDT 2007; root:xnu-792.24.17~1/RELEASE_PPC Power Macintosh
powerpc
msuzuki$ cc -o libedittest libedittest.c -ledit
msuzuki$ ./libedittest
history_base: 1 added 1, 2, 3 to history history_base: 1
history_length: 3
history_get(history_base): 1
history_get(0): NULL
history_get(1): NULL
history_get(2): NULL
history_get(3): NULL

Mac OSX 10.4の標準添付のrubyが
readlineモジュールをコンパイルしていないことから、
10.4環境でののReadline::HISTORYは無効にしても良いように思います。
無効といってもHISTORYを定義しないとか、
例外NotImplementedErrorが発生とか、いろいろ方法はあると思いますが、
具体的になにがいいかは検討できていません。

以上です。

----- ここから -----
Index: ext/readline/readline.c
===================================================================
--- ext/readline/readline.c (revision 18194)
+++ ext/readline/readline.c (working copy)
@@ -29,6 +29,8 @@

static VALUE mReadline;

+#define EDIT_LINE_LIBRARY_VERSION "EditLine wrapper"
+
#define COMPLETION_PROC "completion_proc"
#define COMPLETION_CASE_FOLD "completion_case_fold"
static ID completion_proc, completion_case_fold;
@@ -43,6 +45,8 @@
# define rl_completion_matches completion_matches
#endif

+static int (*history_get_offset_func)(int);
+
static char **readline_attempted_completion_function(const char *text,
int start, int end);

@@ -505,10 +509,22 @@
return rb_str_new2("HISTORY");
}

+static int
+history_get_offset_history_base(int offset)
+{

  • return history_base + offset; +} + +static int +history_get_offset_0(int offset) +{
  • return offset; +} + static VALUE hist_get(VALUE self, VALUE index) {
  • HIST_ENTRY *entry;
  • HIST_ENTRY *entry = NULL;
    int i;

    rb_secure(4);
    @@ -516,7 +532,9 @@
    if (i < 0) {
    i += history_length;
    }

  • entry = history_get(history_base + i);

  • if (i >= 0) {

  • entry = history_get(history_get_offset_func(i));

  • }
    if (entry == NULL) {
    rb_raise(rb_eIndexError, "invalid index");
    }
    @@ -527,7 +545,7 @@
    hist_set(VALUE self, VALUE index, VALUE str)
    {
    #ifdef HAVE_REPLACE_HISTORY_ENTRY

  • HIST_ENTRY *entry;

  • HIST_ENTRY *entry = NULL;
    int i;

    rb_secure(4);
    @@ -536,7 +554,9 @@
    if (i < 0) {
    i += history_length;
    }

  • entry = replace_history_entry(i, RSTRING_PTR(str), NULL);

  • if (i >= 0) {

  • entry = replace_history_entry(i, RSTRING_PTR(str), NULL);

  • }
    if (entry == NULL) {
    rb_raise(rb_eIndexError, "invalid index");
    }
    @@ -581,7 +601,7 @@
    entry = remove_history(index);
    if (entry) {
    val = rb_tainted_str_new2(entry->line);

  •    free(entry->line);
    
  •    free((void *) entry->line);
     free(entry);
     return val;
    

    }
    @@ -624,7 +644,7 @@

    rb_secure(4);
    for (i = 0; i < history_length; i++) {

  •    entry = history_get(history_base + i);
    
  •    entry = history_get(history_get_offset_func(i));
     if (entry == NULL)
         break;
    

    rb_yield(rb_tainted_str_new2(entry->line));
    @@ -662,6 +682,19 @@
    }

static VALUE
+hist_clear(VALUE self)
+{
+#ifdef HAVE_CLEAR_HISTORY

  • rb_secure(4);
  • clear_history();
  • return self; +#else
  • rb_notimplement();
  • return Qnil; /* not reached */ +#endif +} + +static VALUE filename_completion_proc_call(VALUE self, VALUE str) { VALUE result; @@ -782,6 +815,7 @@ rb_define_singleton_method(history,"size", hist_length, 0); rb_define_singleton_method(history,"empty?", hist_empty_p, 0); rb_define_singleton_method(history,"delete_at", hist_delete_at, 1);
  • rb_define_singleton_method(history,"clear", hist_clear, 0);
    rb_define_const(mReadline, "HISTORY", history);

    fcomp = rb_obj_alloc(rb_cObject);
    @@ -793,8 +827,19 @@
    rb_define_singleton_method(ucomp, "call",
    username_completion_proc_call, 1);
    rb_define_const(mReadline, "USERNAME_COMPLETION_PROC", ucomp);

  • history_get_offset_func = history_get_offset_history_base;
    #if defined HAVE_RL_LIBRARY_VERSION
    rb_define_const(mReadline, "VERSION", rb_str_new2(rl_library_version));
    +#if defined HAVE_CLEAR_HISTORY

  • if (strncmp(rl_library_version, EDIT_LINE_LIBRARY_VERSION,

  •  strlen(EDIT_LINE_LIBRARY_VERSION)) == 0) {
    
  • add_history("1");

  • if (history_get(history_get_offset_func(0)) == NULL) {

  •  history_get_offset_func = history_get_offset_0;
    
  • }

  • clear_history();

  • }
    +#endif
    #else
    rb_define_const(mReadline, "VERSION", rb_str_new2("2.0 or prior version"));
    #endif

    Index: ext/readline/extconf.rb

    --- ext/readline/extconf.rb (revision 18194)
    +++ ext/readline/extconf.rb (working copy)
    @@ -66,4 +66,5 @@
    have_readline_func("rl_emacs_editing_mode")
    have_readline_func("replace_history_entry")
    have_readline_func("remove_history")
    +have_readline_func("clear_history")
    create_makefile("readline")

    Index: test/readline/test_readline_history.rb

    --- test/readline/test_readline_history.rb (revision 0)
    +++ test/readline/test_readline_history.rb (revision 0)
    @@ -0,0 +1,313 @@
    +begin

  • require "readline"
    +=begin

  • class << Readline::HISTORY

  • def []=(index, str)

  •  raise NotImplementedError
    
  • end
    +

  • def pop

  •  raise NotImplementedError
    
  • end
    +

  • def shift

  •  raise NotImplementedError
    
  • end
    +

  • def delete_at(index)

  •  raise NotImplementedError
    
  • end

  • end
    +=end
    +
    +=begin

  • class << Readline::HISTORY

  • def clear

  •  raise NotImplementedError
    
  • end

  • end
    +=end
    +rescue LoadError
    +else

  • require "test/unit"
    +end
    +
    +class Readline::TestHistory < Test::Unit::TestCase

  • include Readline
    +

  • def setup

  • HISTORY.clear

  • end
    +

  • def test_safe_level_4

  • method_args =

  •  [
    
  •   ["[]", [0]],
    
  •   ["[]=", [0, "s"]],
    
  •   ["\<\<", ["s"]],
    
  •   ["push", ["s"]],
    
  •   ["pop", []],
    
  •   ["shift", []],
    
  •   ["length", []],
    
  •   ["delete_at", [0]],
    
  •   ["clear", []],
    
  •  ]
    
  • method_args.each do |method_name, args|

  •  assert_raises(SecurityError,
    
  •                "method=<#{method_name}>") do
    
  •    Thread.start {
    
  •      $SAFE = 4
    
  •      HISTORY.send(method_name.to_sym, *args)
    
  •      assert(true)
    
  •    }.join
    
  •  end
    
  • end
    +

  • assert_raises(SecurityError, NotImplementedError,

  •              "method=<each>") do
    
  •  Thread.start {
    
  •    $SAFE = 4
    
  •    HISTORY.each { |s|
    
  •      assert(true)
    
  •    }
    
  •  }.join
    
  • end

  • end

  • def test_to_s

  • assert_equal("HISTORY", HISTORY.to_s)

  • end
    +

  • def test_get

  • lines = push_history(5)

  • lines.each_with_index do |s, i|

  •  assert_equal(s, HISTORY[i])
    
  • end

  • end
    +

  • def test_get__negative

  • lines = push_history(5)

  • (1..5).each do |i|

  •  assert_equal(lines[-i], HISTORY[-i])
    
  • end

  • end
    +

  • def test_get__out_of_range

  • lines = push_history(5)

  • invalid_indexes = [5, 6, 100, -6, -7, -100]

  • invalid_indexes.each do |i|

  •  assert_raise(IndexError, "i=<#{i}>") do
    
  •    HISTORY[i]
    
  •  end
    
  • end

  • invalid_indexes = [100_000_000_000_000_000_000,

  •                   -100_000_000_000_000_000_000]
    
  • invalid_indexes.each do |i|

  •  assert_raise(RangeError, "i=<#{i}>") do
    
  •    HISTORY[i]
    
  •  end
    
  • end

  • end
    +

  • def test_set

  • begin

  •  lines = push_history(5)
    
  •  5.times do |i|
    
  •    expected = "set: #{i}"
    
  •    HISTORY[i] = expected
    
  •    assert_equal(expected, HISTORY[i])
    
  •  end
    
  • rescue NotImplementedError

  • end

  • end
    +

  • def test_set__out_of_range

  • assert_raises(IndexError, NotImplementedError, "index=") do

  •  HISTORY[0] = "set: 0"
    
  • end

  • lines = push_history(5)

  • invalid_indexes = [5, 6, 100, -6, -7, -100]

  • invalid_indexes.each do |i|

  •  assert_raises(IndexError, NotImplementedError, "index=<#{i}>") do
    
  •    HISTORY[i] = "set: #{i}"
    
  •  end
    
  • end

  • invalid_indexes = [100_000_000_000_000_000_000,

  •                   -100_000_000_000_000_000_000]
    
  • invalid_indexes.each do |i|

  •  assert_raise(RangeError, NotImplementedError, "index=<#{i}>") do
    
  •    HISTORY[i] = "set: #{i}"
    
  •  end
    
  • end

  • end
    +

  • def test_push

  • 5.times do |i|

  •  assert_equal(HISTORY, HISTORY.push(i.to_s))
    
  •  assert_equal(i.to_s, HISTORY[i])
    
  • end

  • assert_equal(5, HISTORY.length)

  • end
    +

  • def test_push__operator

  • 5.times do |i|

  •  assert_equal(HISTORY, HISTORY << i.to_s)
    
  •  assert_equal(i.to_s, HISTORY[i])
    
  • end

  • assert_equal(5, HISTORY.length)

  • end
    +

  • def test_push__plural

  • assert_equal(HISTORY, HISTORY.push("0", "1", "2", "3", "4"))

  • (0..4).each do |i|

  •  assert_equal(i.to_s, HISTORY[i])
    
  • end

  • assert_equal(5, HISTORY.length)
    +

  • assert_equal(HISTORY, HISTORY.push("5", "6", "7", "8", "9"))

  • (5..9).each do |i|

  •  assert_equal(i.to_s, HISTORY[i])
    
  • end

  • assert_equal(10, HISTORY.length)

  • end
    +

  • def test_pop

  • begin

  •  assert_equal(nil, HISTORY.pop)
    
  •  lines = push_history(5)
    
  •  (1..5).each do |i|
    
  •    assert_equal(lines[-i], HISTORY.pop)
    
  •    assert_equal(lines.length - i, HISTORY.length)
    
  •  end
    
  •  assert_equal(nil, HISTORY.pop)
    
  • rescue NotImplementedError

  • end

  • end
    +

  • def test_shift

  • begin

  •  assert_equal(nil, HISTORY.shift)
    
  •  lines = push_history(5)
    
  •  (0..4).each do |i|
    
  •    assert_equal(lines[i], HISTORY.shift)
    
  •    assert_equal(lines.length - (i + 1), HISTORY.length)
    
  •  end
    
  •  assert_equal(nil, HISTORY.shift)
    
  • rescue NotImplementedError

  • end

  • end
    +

  • def test_each

  • HISTORY.each do |s|

  •  assert(false) # not reachable
    
  • end

  • lines = push_history(5)

  • i = 0

  • HISTORY.each do |s|

  •  assert_equal(HISTORY[i], s)
    
  •  assert_equal(lines[i], s)
    
  •  i += 1
    
  • end

  • end
    +

  • def test_each__enumerator

  • e = HISTORY.each

  • assert_instance_of(Enumerable::Enumerator, e)

  • end
    +

  • def test_length

  • assert_equal(0, HISTORY.length)

  • push_history(1)

  • assert_equal(1, HISTORY.length)

  • push_history(4)

  • assert_equal(5, HISTORY.length)

  • HISTORY.clear

  • assert_equal(0, HISTORY.length)

  • end
    +

  • def test_empty_p

  • 2.times do

  •  assert(HISTORY.empty?)
    
  •  HISTORY.push("s")
    
  •  assert_equal(false, HISTORY.empty?)
    
  •  HISTORY.clear
    
  •  assert(HISTORY.empty?)
    
  • end

  • end
    +

  • def test_delete_at

  • begin

  •  lines = push_history(5)
    
  •  (0..4).each do |i|
    
  •    assert_equal(lines[i], HISTORY.delete_at(0))
    
  •  end
    
  •  assert(HISTORY.empty?)
    

    +

  •  lines = push_history(5)
    
  •  (1..5).each do |i|
    
  •    assert_equal(lines[lines.length - i], HISTORY.delete_at(-1))
    
  •  end
    
  •  assert(HISTORY.empty?)
    

    +

  •  lines = push_history(5)
    
  •  assert_equal(lines[0], HISTORY.delete_at(0))
    
  •  assert_equal(lines[4], HISTORY.delete_at(3))
    
  •  assert_equal(lines[1], HISTORY.delete_at(0))
    
  •  assert_equal(lines[3], HISTORY.delete_at(1))
    
  •  assert_equal(lines[2], HISTORY.delete_at(0))
    
  •  assert(HISTORY.empty?)
    
  • rescue NotImplementedError

  • end

  • end
    +

  • def test_delete_at__out_of_range

  • assert_raises(IndexError, NotImplementedError, "index=") do

  •  HISTORY.delete_at(0)
    
  • end

  • lines = push_history(5)

  • invalid_indexes = [5, 6, 100, -6, -7, -100]

  • invalid_indexes.each do |i|

  •  assert_raises(IndexError, NotImplementedError, "index=<#{i}>") do
    
  •    HISTORY.delete_at(i)
    
  •  end
    
  • end

  • invalid_indexes = [100_000_000_000_000_000_000,

  •                   -100_000_000_000_000_000_000]
    
  • invalid_indexes.each do |i|

  •  assert_raises(RangeError, NotImplementedError, "index=<#{i}>") do
    
  •    HISTORY.delete_at(i)
    
  •  end
    
  • end

  • end
    +

  • private
    +

  • def push_history(num)

  • lines = []

  • num.times do |i|

  •  s = "a"
    
  •  i.times do
    
  •    s = s.succ
    
  •  end
    
  •  lines.push("#{i + 1}:#{s}")
    
  • end

  • HISTORY.push(*lines)

  • return lines

  • end
    +end if defined?(::Readline) && defined?(::Readline::HISTORY) &&

  • (

  • begin

  • Readline::HISTORY.clear
    
  • rescue NotImplementedError

  • false
    
  • end

  • )

=end

#17 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
高尾宏治です。

On 2008/07/24, at 9:37, Takao Kouji wrote:

On 2008/07/23, at 23:14, Takao Kouji wrote:

ただ、Readlineモジュールの入力履歴を扱うメソッドは、
例外NotImplementedErrorが発生するかもしれないので、
それに対応したテストを記述する必要がありました。
現在、この作業中です。

この作業が終わったら、パッチを本MLに報告する予定です。

テストを修正しました。
本メールの下部にパッチを記述しています。

いろいろな環境でテストしようと考えたのですが、
なかなか時間が取れませんでした。
とりあえず、 Mac OSX 10.5の環境で
libeditと GNU Readline 5.2 で動作を確認しています。
trunk であれば先のパッチを適用後、コミットしていただいて、
広くいろんな方に使っていただいても良いように思いますが、
いかがでしょうか。 > 前田さん

# 本当は私がいろいろな環境で試していただけるようにしたかったのですが、
# 思ったよりも時間は取れないもののですね。。。

Readline::HISTORYのtestを追加しているため、
先のパッチをコミットしていたければ、
それなりにいろいろな環境でテストしていいただける可能性があると考えています。

それでは、ご検討よろしくお願いいたします。

それと、私は今後もReadlineモジュールをメンテナンスしていく意志があります。
現在、亀のように遅いですが rdoc を記述しています。
Readlineの日本語のリファレンスマニュアルは私が記述しました。

http://doc.loveruby.net/refm/api/view/class/Readline

Readlineモジュールのメンテナとして検討していただければ幸いです。

=end

#18 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
高尾宏治です。

On 2008/07/31, at 10:05, M.Suzuki wrote:

Mac OSX 10.4で新しいパッチをテストしてみました。

ありがとうございます。

msuzuki$ ./ruby --version
ruby 1.9.0 (2008-07-31 revision 0) [powerpc-darwin8.11.0]

msuzuki$ ./ruby -I.ext/powerpc-darwin8.11.0 / -rreadline
test/readline/test_readline_history.rb Loaded suite
test/readline/test_readline_history Started
....F...F....F....
Finished in 0.173369 seconds.

1) Failure:
test_empty_p(Readline::TestHistory)
[test/readline/test_readline_history.rb:237:in block in
test_empty_p' test/readline/test_readline_history.rb:236:in
times'
test/readline/test_readline_history.rb:236:in `test_empty_p']:
is not true.

2) Failure:
test_length(Readline::TestHistory)
[test/readline/test_readline_history.rb:226]: expected but was
.

なんか変な挙動をしていますね。
HISTORY.pushしたのにempty?がtrueのようですね。
つまり、libeditのadd_history関数を処理しても、
実際にはヒストリに追加されず、history_lengthが0のままのようです。
これは参った。これって対応できるのかな。

3) Failure:
test_safe_level_4(Readline::TestHistory)
[test/readline/test_readline_history.rb:56:in block in
test_safe_level_4' test/readline/test_readline_history.rb:55:in
each'
test/readline/test_readline_history.rb:55:in test_safe_level_4']:
method=<[]=>.
<SecurityError> exception expected but was
Class: <NotImplementedError>
Message: <"[]=() function is unimplemented on this machine">
---Backtrace---
test/readline/test_readline_history.rb:60:in
[]='
test/readline/test_readline_history.rb:60:in `block (3 levels) in

test_safe_level_4'

上記はテストのバグでした。
情報ありがとうございました。

やはり history 周りはダメっぽいですね。
そもそもライブラリがおかしい様なので、どうしようもないのかも。

GNU Readlineをインストールしてくださいってことでもいいかもしれませんね。

マニュアルの注意事項に載せておくとかFAQを作っておいた方が良いかも。

そうですね。
今、ReadlineのRDocを記述している最中なので、検討してみます。

ちなみに のパッチは行頭の空白が失われている(?)ので

そのままでは patch に読ませられませんでした。

大きなパッチではないので、+-以外の行にスペースを追加しましたが、

patch のオプションでなんとかなるのかな。。。

そうでしたか、失礼しました。
Mac OSX 10.5のMail.appを使用しているのですが、
コピペしたときにスペースが削られたのかもしれませんね。まいったな。

=end

#19 Updated by matz (Yukihiro Matsumoto) almost 10 years ago

=begin
まつもと ゆきひろです

In message "Re: Re: [Ruby 1.8 - Bug #212] Issues with Readline in Mac OS X"
on Thu, 31 Jul 2008 22:59:50 +0900, Takao Kouji kouji@takao7.net writes:

|> # ちなみに のパッチは行頭の空白が失われている(?)ので
|> # そのままでは patch に読ませられませんでした。
|> # 大きなパッチではないので、+-以外の行にスペースを追加しましたが、
|> # patch のオプションでなんとかなるのかな。。。
|
|そうでしたか、失礼しました。
|Mac OSX 10.5のMail.appを使用しているのですが、
|コピペしたときにスペースが削られたのかもしれませんね。まいったな。

patch に -l オプションを付けると空白の違いを無視してくれます。

=end

#20 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
高尾宏治です。

On 2008/08/01, at 10:05, M.Suzuki wrote:

なんか変な挙動をしていますね。
HISTORY.pushしたのにempty?がtrueのようですね。
つまり、libeditのadd_history関数を処理しても、
実際にはヒストリに追加されず、history_lengthが0のままのようです。
これは参った。これって対応できるのかな。

[ruby-dev-35557] の結果からも、history_get()の挙動がおかしいので、仕方な
いかと・・・

add_history()した結果、history_lengthが0になるだけマシとも...

たしかに仕方ないのかもしれません。

rubyでラップして独自に履歴機能を実装するという手も有りますが、
10.4は過去のバージョンですし、積極的に対応しなくても良いのではないかと個
人的には思います。

そうかもしれませんね。
libeditのバージョンがかなり古いようですので、
未対応ということにしましょうかね。

また、単体テストも修正せず、
テストに失敗することで「このバージョンはヒストリの操作に対応していません」
ということが分かって良いとも考えられます。

=end

#21 Updated by shugo (Shugo Maeda) almost 10 years ago

=begin
前田です。

2008/07/26 23:55 Takao Kouji kouji@takao7.net:

それと、私は今後もReadlineモジュールをメンテナンスしていく意志があります。
現在、亀のように遅いですが rdoc を記述しています。
Readlineの日本語のリファレンスマニュアルは私が記述しました。

http://doc.loveruby.net/refm/api/view/class/Readline

Readlineモジュールのメンテナとして検討していただければ幸いです。

まつもとさんとも相談して高尾君に引き取ってもらうことにしました。
# ついでにできればcursesも…。
というわけで、アカウントが出来たら自分でcommitしてください。

--
Shugo Maeda

=end

#22 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
高尾宏治です。

On 2008/08/01, at 15:43, Shugo Maeda wrote:

2008/07/26 23:55 Takao Kouji kouji@takao7.net:

それと、私は今後もReadlineモジュールをメンテナンスしていく意志があります。
現在、亀のように遅いですが rdoc を記述しています。
Readlineの日本語のリファレンスマニュアルは私が記述しました。

http://doc.loveruby.net/refm/api/view/class/Readline

Readlineモジュールのメンテナとして検討していただければ幸いです。

まつもとさんとも相談して高尾君に引き取ってもらうことにしました。

ついでにできればcursesも…。

というわけで、アカウントが出来たら自分でcommitしてください。

今日、前田さんにkoujiというアカウントを作成していただきました。
これからパッチを整理して、Mac OSXの環境と、
Debian GNU/Linux etch上でテストしたらコミットします。
# curses は今後の課題ということで...

あと、せっかくなので、簡単に自己紹介をしておきます。

アカウント名: kouji
名前: 高尾 宏治
所属: ネットワーク応用通信研究所
ひとこと:
会社では、目の前がまつもとさんの席で、
後ろが前田さんの席という贅沢(?)な環境で仕事をしています。
OSSに関する活動としてはGPassやsecurity-keeperを開発しています。
(開発していましたが正しいかも...)
あと、島根県松江市でRubyに関する勉強会を主催しています。

以上です。
先輩コミッタのみなさま、
これからよろしくお願いします。

=end

#23 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
高尾宏治です。

On 2008/08/01, at 22:01, Takao Kouji wrote:

これからパッチを整理して、Mac OSXの環境と、
Debian GNU/Linux etch上でテストしたらコミットします。

r18313にてコミットしました。

今回の不具合は、1.8系に対するバグ報告をもとに調査、対応しました。
1.8系へのバックポートの需要があるのではないかと思いますが、
1.8系へのバックポートについては、互換性などを考察して、
あらためて提案したいと考えています。

=end

#24 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
I fixed this bug in trunk's revision 18313.
Do you want to backport to 1.8?
=end

#25 Updated by febuiles (Federico Builes) almost 10 years ago

=begin
Kouji: I'm not able to follow the discussion in japanese but it'd be great if this change was backported.
=end

#26 Updated by kouji (Kouji Takao) almost 10 years ago

=begin
I created the patch for ruby 1.8 branch. The patch was attached. Please try it.

NOTE: This patch applyed Ruby failed RubySpec for Readline::HISTORY.
Because your reported problem was specification in RubySpec. hmm.

=end

#27 Updated by febuiles (Federico Builes) almost 10 years ago

=begin
The issue with the specs has been fixed by Arthur Schreiber in Rubyspec:947a6dc29, thanks for the patches!
=end

#28 Updated by naruse (Yui NARUSE) almost 10 years ago

  • Status changed from Open to Closed

=begin

=end

Also available in: Atom PDF