Project

General

Profile

Bug #13319

Updated by nobu (Nobuyoshi Nakada) over 3 years ago

It looks like there is a latent GC issue somewhere that I can for example reproduce with ruby 2.3.3 and 2.2.6 when building with `-O2 -g`. -O2 -g. 
 valgrind reports a lot of cases like 

 ``` 
 ==24537== Invalid read of size 4 
 ==24537==      at 0x4C44E8: node_newnode (parse.y:8799) 
 ==24537==      by 0x4C44E8: ruby_yyparse (parse.y:3894) 
 ==24537==      by 0x4CD4C5: yycompile0 (parse.y:5542) 
 ==24537==      by 0x58527B: rb_suppress_tracing (vm_trace.c:407) 
 ==24537==      by 0x56353A: rb_iseq_compile_with_option (iseq.c:637) 
 ==24537==      by 0x578E79: eval_string_with_cref (vm_eval.c:1339) 
 ==24537==      by 0x579605: eval_under (vm_eval.c:1633) 
 ==24537==      by 0x579605: specific_eval (vm_eval.c:1657) 
 ==24537==      by 0x56A218: vm_call_cfunc_with_frame (vm_insnhelper.c:1642) 
 ==24537==      by 0x56A218: vm_call_cfunc (vm_insnhelper.c:1737) 
 ==24537==      by 0x5719B6: vm_exec_core (insns.def:994) 
 ==24537==      by 0x577AEE: vm_exec (vm.c:1650) 
 ==24537==      by 0x57C86B: invoke_block (vm.c:921) 
 ==24537==      by 0x57C86B: invoke_block_from_c_0 (vm.c:971) 
 ==24537==      by 0x57C86B: invoke_block_from_c_splattable (vm.c:988) 
 ==24537==      by 0x57C86B: vm_yield (vm.c:1023) 
 ==24537==      by 0x57C86B: rb_yield_0 (vm_eval.c:1013) 
 ==24537==      by 0x57C86B: rb_yield_1 (vm_eval.c:1019) 
 ==24537==      by 0x57C86B: rb_yield (vm_eval.c:1029) 
 ==24537==      by 0x41D68B: rb_ary_each (array.c:1815) 
 ==24537==      by 0x56A218: vm_call_cfunc_with_frame (vm_insnhelper.c:1642) 
 ==24537==      by 0x56A218: vm_call_cfunc (vm_insnhelper.c:1737) 
 ==24537==    Address 0x650978c is 172 bytes inside a block of size 272 free'd 
 ==24537==      at 0x4C2D27B: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) 
 ==24537==      by 0x47C1EC: objspace_xfree.isra.73 (gc.c:7716) 
 ==24537==      by 0x47A513: obj_free (gc.c:2156) 
 ==24537==      by 0x47A513: gc_page_sweep (gc.c:3392) 
 ==24537==      by 0x47A513: gc_sweep_step (gc.c:3571) 
 ==24537==      by 0x47AE17: gc_sweep (gc.c:3666) 
 ==24537==      by 0x47CB0D: gc_marks_continue (gc.c:5448) 
 ==24537==      by 0x47CB0D: heap_prepare (gc.c:1639) 
 ==24537==      by 0x47CB0D: heap_get_freeobj_from_next_freepage (gc.c:1657) 
 ==24537==      by 0x47CB0D: heap_get_freeobj (gc.c:1691) 
 ==24537==      by 0x47CB0D: newobj_slowpath (gc.c:1820) 
 ==24537==      by 0x47CB0D: newobj_slowpath_wb_unprotected (gc.c:1838) 
 ==24537==      by 0x47D0F4: newobj_of (gc.c:1864) 
 ==24537==      by 0x47D0F4: rb_node_newnode (gc.c:1900) 
 ==24537==      by 0x4C44E7: node_newnode (parse.y:8798) 
 ==24537==      by 0x4C44E7: ruby_yyparse (parse.y:3894) 
 ==24537==      by 0x4CD4C5: yycompile0 (parse.y:5542) 
 ==24537==      by 0x58527B: rb_suppress_tracing (vm_trace.c:407) 
 ==24537==      by 0x56353A: rb_iseq_compile_with_option (iseq.c:637) 
 ==24537==      by 0x578E79: eval_string_with_cref (vm_eval.c:1339) 
 ==24537==      by 0x579605: eval_under (vm_eval.c:1633) 
 ==24537==      by 0x579605: specific_eval (vm_eval.c:1657) 
 ==24537==    Block was alloc'd at 
 ==24537==      at 0x4C2E065: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) 
 ==24537==      by 0x47C536: objspace_xcalloc (gc.c:7752) 
 ==24537==      by 0x47C536: ruby_xcalloc (gc.c:7761) 
 ==24537==      by 0x47D73F: rb_data_typed_object_zalloc (gc.c:1961) 
 ==24537==      by 0x4BEC98: rb_parser_new (parse.y:10906) 
 ==24537==      by 0x56351A: rb_iseq_compile_with_option (iseq.c:637) 
 ==24537==      by 0x578E79: eval_string_with_cref (vm_eval.c:1339) 
 ==24537==      by 0x579605: eval_under (vm_eval.c:1633) 
 ==24537==      by 0x579605: specific_eval (vm_eval.c:1657) 
 ==24537==      by 0x56A218: vm_call_cfunc_with_frame (vm_insnhelper.c:1642) 
 ==24537==      by 0x56A218: vm_call_cfunc (vm_insnhelper.c:1737) 
 ==24537==      by 0x5719B6: vm_exec_core (insns.def:994) 
 ==24537==      by 0x577AEE: vm_exec (vm.c:1650) 
 ==24537==      by 0x57C86B: invoke_block (vm.c:921) 
 ==24537==      by 0x57C86B: invoke_block_from_c_0 (vm.c:971) 
 ==24537==      by 0x57C86B: invoke_block_from_c_splattable (vm.c:988) 
 ==24537==      by 0x57C86B: vm_yield (vm.c:1023) 
 ==24537==      by 0x57C86B: rb_yield_0 (vm_eval.c:1013) 
 ==24537==      by 0x57C86B: rb_yield_1 (vm_eval.c:1019) 
 ==24537==      by 0x57C86B: rb_yield (vm_eval.c:1029) 
 ==24537==      by 0x41D68B: rb_ary_each (array.c:1815) 
 ==24537== 
 ``` 

 suspiciously the blocks are all freed via `rb_node_newnode` rb_node_newnode which has a 
 `/* /* TODO: node also should be wb protected */` */ comment which looks like 
 a latent correctness issue? 

 I have disabled asm `SET_MACHINE_STACK_END` SET_MACHINE_STACK_END to no avail (it doesn't look 
 safe with respect to instruction scheduling). 

 Without valgrind the issue manifests itself as corrupt glibc heap. 
 It occurs on x86_64-linux, ppc64le-linux and i586-linux for me. 

 It does not reproduce (easily) when compiling with `-O3` -O3 but I suspect 
 it's related to GC of objects on the stack / kept live via the stack. 

 Failure during build: 

 ``` 
 gcc-7 -O2 -g    -L. -fstack-protector -rdynamic -Wl,-export-dynamic -fstack-protector -pie    main.o dmydln.o miniinit.o dmyext.o miniprelude.o array.o bignum.o class.o compar.o complex.o dir.o dln_find.o encoding.o enum.o enumerator.o error.o eval.o load.o proc.o file.o gc.o hash.o inits.o io.o marshal.o math.o node.o numeric.o object.o pack.o parse.o process.o random.o range.o rational.o re.o regcomp.o regenc.o regerror.o regexec.o regparse.o regsyntax.o ruby.o safe.o signal.o sprintf.o st.o strftime.o string.o struct.o symbol.o time.o transcode.o util.o variable.o version.o compile.o debug.o iseq.o vm.o vm_dump.o vm_backtrace.o vm_trace.o thread.o cont.o    enc/ascii.o enc/us_ascii.o enc/unicode.o enc/utf_8.o enc/trans/newline.o explicit_bzero.o setproctitle.o strlcat.o strlcpy.o addr2line.o     -lpthread -lgmp -ldl -lcrypt -lm     -o miniruby 
 ./miniruby -I./lib -I. -I.ext/common    ./tool/generic_erb.rb -c -o encdb.h ./template/encdb.h.tmpl ./enc enc 
 encdb.h updated 
 ./miniruby -I./lib -I. -I.ext/common    ./tool/mkconfig.rb -timestamp=.rbconfig.time \ 
         -arch=x86_64-linux -version=2.3.3 \ 
         -install_name=ruby \ 
         -so_name=ruby rbconfig.rb 
 rbconfig.rb updated 
 ./miniruby -I./lib -I. -I.ext/common    ./enc/make_encmake.rb --builtin-encs="enc/ascii.o enc/us_ascii.o enc/unicode.o enc/utf_8.o" --builtin-transes="enc/trans/newline.o" --module    enc.mk 
 /tmp/home:rguenther:branches:devel:languages:ruby/ruby2.3/ruby-ruby_2_3/lib/fileutils.rb:1747: [BUG] Segmentation fault at 0x0006ba0000000f 
 ruby 2.3.3p246 (2017-02-14) [x86_64-linux] 

 -- Control frame information ----------------------------------------------- 
 c:0011 p:---- s:0040 e:000039 CFUNC    :module_eval 
 c:0010 p:0030 s:0034 e:000033 BLOCK    /tmp/home:rguenther:branches:devel:languages:ruby/ruby2.3/ruby-ruby_2_3/lib/fileutils.rb:1747 [FINISH] 
 c:0009 p:---- s:0031 e:000030 CFUNC    :each 
 c:0008 p:0065 s:0028 e:000027 CLASS    /tmp/home:rguenther:branches:devel:languages:ruby/ruby2.3/ruby-ruby_2_3/lib/fileutils.rb:1746 
 c:0007 p:2099 s:0026 e:000025 CLASS    /tmp/home:rguenther:branches:devel:languages:ruby/ruby2.3/ruby-ruby_2_3/lib/fileutils.rb:1741 
 c:0006 p:0009 s:0024 e:000023 TOP      /tmp/home:rguenther:branches:devel:languages:ruby/ruby2.3/ruby-ruby_2_3/lib/fileutils.rb:88 [FINISH] 
 c:0005 p:---- s:0022 e:000021 CFUNC    :require 
 c:0004 p:0017 s:0018 e:000017 TOP      /tmp/home:rguenther:branches:devel:languages:ruby/ruby2.3/ruby-ruby_2_3/lib/mkmf.rb:7 [FINISH] 
 c:0003 p:---- s:0016 e:000015 CFUNC    :load 
 c:0002 p:0082 s:0012 E:0023e0 EVAL     ./enc/make_encmake.rb:8 [FINISH] 
 c:0001 p:0000 s:0002 E:0004d0 (none) [FINISH] 

 -- Ruby level backtrace information ---------------------------------------- 
 ./enc/make_encmake.rb:8:in `<main>' 
 ./enc/make_encmake.rb:8:in `load' 
 /tmp/home:rguenther:branches:devel:languages:ruby/ruby2.3/ruby-ruby_2_3/lib/mkmf.rb:7:in `<top (required)>' 
 /tmp/home:rguenther:branches:devel:languages:ruby/ruby2.3/ruby-ruby_2_3/lib/mkmf.rb:7:in `require' 
 /tmp/home:rguenther:branches:devel:languages:ruby/ruby2.3/ruby-ruby_2_3/lib/fileutils.rb:88:in `<top (required)>' 
 /tmp/home:rguenther:branches:devel:languages:ruby/ruby2.3/ruby-ruby_2_3/lib/fileutils.rb:1741:in `<module:FileUtils>' 
 /tmp/home:rguenther:branches:devel:languages:ruby/ruby2.3/ruby-ruby_2_3/lib/fileutils.rb:1746:in `<module:DryRun>' 
 /tmp/home:rguenther:branches:devel:languages:ruby/ruby2.3/ruby-ruby_2_3/lib/fileutils.rb:1746:in `each' 
 /tmp/home:rguenther:branches:devel:languages:ruby/ruby2.3/ruby-ruby_2_3/lib/fileutils.rb:1747:in `block in <module:DryRun>' 
 /tmp/home:rguenther:branches:devel:languages:ruby/ruby2.3/ruby-ruby_2_3/lib/fileutils.rb:1747:in `module_eval' 

 -- Machine register context ------------------------------------------------ 
  RIP: 0x0000559d83d5272c RBP: 0x00000000000000cf RSP: 0x00007ffe166d5e88 
  RAX: 0x0000000000000000 RBX: 0x0000000000008a61 RCX: 0x0000559d85715a10 
  RDX: 0x000006ba0000000f RDI: 0x0000559d8570fd40 RSI: 0x0000000000008a61 
   R8: 0x0000000000000031    R9: 0x0000559d85715a10 R10: 0x0000000000000000 
  R11: 0x0000000000008a61 R12: 0x0000559d85715ef0 R13: 0x00007ffe166d6178 
  R14: 0x0000559d83e4f4e0 R15: 0x00007ffe166d5fb2 EFL: 0x0000000000010202 

 -- C level backtrace information ------------------------------------------- 
 *** Error in `./miniruby': corrupted double-linked list: 0x0000559d8570f7c0 *** 

 uncommon.mk:654: recipe for target 'enc.mk' failed 
 ``` 

Back