P
Peter Zotov
Hi.
I am developing bindings for libconfig and discovered a strange bug in =20
irb1.9 (ruby 1.9.0 (2008-06-20 revision 17482) [i486-linux], irb =20
0.9.5(05/04/13); Debian GNU/Linux 5.0/lenny): ruby1.9 executes my =20
script nice, but irb crashes at some random place. Crash is affected =20
by most theoretically unlinked commands and may disappear even after =20
removing a comment (sic).
You can download my extension sources here =20
(http://files.whitequark.ru/libconfig-ruby.tbz2).
Crashing script:
--- BEGIN ---
require 'rconfig'
c =3D Config.new
c.read('test.cfg')
# =3D> false
c.append 'fixnum', Config::Fixnum.new(150)
# #<Config::Fixnum...>
f1 =3D Config::Fixnum.new(1)
c.append 'another_fixnum', f1
f2 =3D Config::Fixnum.new(256)
c.append 'next_fixnum', f2
p c.size
# =3D> 2
c.delete(f1) # by element
c.delete(0) # by index
c.delete('next_fixnum') # by name
# note: (at now) you cannot delete nested elements by Config#delete
# you can do c['nested.element'].parent.delete(c['nested.element'])
p c.size
# =3D> 0
l =3D Config::List.new
c.append 'the_list', l
l.append Config::String.new("abcdef")
l << Config::Float.new(3.14)
--- END ---
Sample log:
--- BEGIN ---
whitequark@hell:~$ tar xf libconfig-ruby.tbz2
whitequark@hell:~$ cd libconfig-ruby/ext/
whitequark@hell:~/libconfig-ruby/ext$ ruby1.9 extconf.rb
checking for rb_block_call() in ruby/ruby.h... yes
creating Makefile
whitequark@hell:~/libconfig-ruby/ext$ make
cc -I. -I/usr/include/ruby-1.9.0/i486-linux -I/usr/include/ruby-1.9.0 =20
-I. -DHAVE_RB_BLOCK_CALL -D_FILE_OFFSET_BITS=3D64 -fPIC =20
-fno-strict-aliasing -g -g -O2 -O2 -g -Wall -Wno-parentheses -fPIC =20
-o rconfig.o -c rconfig.c
cc -shared -o rconfig.so rconfig.o -L. -L/usr/lib -L. -rdynamic =20
-Wl,-export-dynamic -lruby1.9 -lconfig -lpthread -lrt -ldl =20
-lcrypt -lm -lc
whitequark@hell:~/libconfig-ruby/ext$ ruby1.9 crash.rb
3
whitequark@hell:~/libconfig-ruby/ext$ irb1.9 crash.rb
crash.rb(main):001:0> require 'rconfig'
=3D> true
crash.rb(main):002:0> c =3D Config.new
=3D> #<Config:0x9dd76d4 @config=3D#<Object:0x9dd76c0>>
crash.rb(main):003:0>
crash.rb(main):004:0* c.read('test.cfg')
=3D> false
crash.rb(main):005:0> # =3D> false
crash.rb(main):006:0*
crash.rb(main):007:0* c.append 'fixnum', Config::Fixnum.new(150)
=3D> #<Config::Fixnum:0x9dc0dd0 @setting=3D#<Object:0x9dc0d30>, =20
@value=3D150, @format=3D0>
crash.rb(main):008:0> # #<Config::Fixnum...>
crash.rb(main):009:0*
crash.rb(main):010:0* f1 =3D Config::Fixnum.new(1)
=3D> #<Config::Fixnum:0x9db6a9c @setting=3Dnil, @value=3D1, @format=3D0>
crash.rb(main):011:0> c.append 'another_fixnum', f1
=3D> #<Config::Fixnum:0x9db6a9c @setting=3D#<Object:0x9db11f0>, @value=3D1, =
=20
@format=3D0>
crash.rb(main):012:0>
crash.rb(main):013:0* f2 =3D Config::Fixnum.new(256)
=3D> #<Config::Fixnum:0x9daa828 @setting=3Dnil, @value=3D256, @format=3D0>
crash.rb(main):014:0> c.append 'next_fixnum', f2
=3D> #<Config::Fixnum:0x9daa828 @setting=3D#<Object:0x9da86f4>, =20
@value=3D256, @format=3D0>
crash.rb(main):015:0>
crash.rb(main):016:0* p c.size
3
=3D> 3
crash.rb(main):017:0> # =3D> 2
crash.rb(main):018:0*
crash.rb(main):019:0* c.delete(f1) # by element
=3D> nil
crash.rb(main):020:0> c.delete(0) # by index
=3D> nil
crash.rb(main):021:0> c.delete('next_fixnum') # by name
=3D> nil
crash.rb(main):022:0> # note: (at now) you cannot delete nested =20
elements by Config#delete
crash.rb(main):023:0* # you can do =20
c['nested.element'].parent.delete(c['nested.element'])
crash.rb(main):024:0*
crash.rb(main):025:0* p c.size
=3D> 0
crash.rb(main):026:0> # =3D> 0
crash.rb(main):027:0*
crash.rb(main):028:0* l =3D Config::List.new
=3D> #<Config::List:0x9ccb128 @list=3D[], @setting=3Dnil>
crash.rb(main):029:0> c.append 'the_list', l
=3D> #<Config::List:0x9ccb128 @list=3D[], @setting=3D#<Object:0x9cc91fc>>
crash.rb(main):030:0>
crash.rb(main):031:0* l.append Config::String.new("abcdef")
=3D> #<Config::String:0x9c7e92c @setting=3D#<Object:0x9c7e8c8>, =20
@value=3D"abcdef", @format=3D0>
crash.rb(main):032:0> l << Config::Float.new(3.14)
crash.rb:32: [BUG] Segmentation fault
ruby 1.9.0 (2008-06-20 revision 17482) [i486-linux]
-- control frame ----------
c:0024 p:---- s:0080 b:0080 l:000079 d:000079 CFUNC :<<
c:0023 p:0021 s:0076 b:0076 l:001f74 d:0002fc EVAL crash.rb:32
c:0022 p:---- s:0074 b:0074 l:000073 d:000073 FINISH :empty?
c:0021 p:---- s:0072 b:0072 l:000071 d:000071 CFUNC :eval
c:0020 p:0023 s:0065 b:0065 l:000064 d:000064 METHOD =20
/usr/lib/ruby/1.9.0/irb/workspace.rb:80
c:0019 p:0025 s:0058 b:0057 l:000056 d:000056 METHOD =20
/usr/lib/ruby/1.9.0/irb/context.rb:218
c:0018 p:0024 s:0052 b:0052 l:0007bc d:000051 BLOCK =20
/usr/lib/ruby/1.9.0/irb.rb:149
c:0017 p:0025 s:0044 b:0044 l:000043 d:000043 METHOD =20
/usr/lib/ruby/1.9.0/irb.rb:263
c:0016 p:0009 s:0039 b:0039 l:0007bc d:000038 BLOCK =20
/usr/lib/ruby/1.9.0/irb.rb:146
c:0015 p:0093 s:0035 b:0035 l:000022 d:000034 BLOCK =20
/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:243
c:0014 p:---- s:0034 b:0034 l:000033 d:000033 FINISH :block_given?
c:0013 p:---- s:0032 b:0032 l:000031 d:000031 CFUNC :loop
c:0012 p:0007 s:0029 b:0029 l:000022 d:000028 BLOCK =20
/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:230
c:0011 p:---- s:0029 b:0029 l:000028 d:000028 FINISH :each
c:0010 p:---- s:0027 b:0027 l:000026 d:000026 CFUNC :catch
c:0009 p:0017 s:0023 b:0023 l:000022 d:000022 METHOD =20
/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:229
c:0008 p:0034 s:0020 b:0020 l:0007bc d:0007bc METHOD =20
/usr/lib/ruby/1.9.0/irb.rb:145
c:0007 p:0009 s:0017 b:0017 l:001d6c d:000016 BLOCK =20
/usr/lib/ruby/1.9.0/irb.rb:69
c:0006 p:---- s:0017 b:0017 l:000016 d:000016 FINISH null)
c:0005 p:---- s:0015 b:0015 l:000014 d:000014 CFUNC :catch
c:0004 p:0152 s:0011 b:0011 l:001d6c d:001d6c METHOD =20
/usr/lib/ruby/1.9.0/irb.rb:68
c:0003 p:0033 s:0006 b:0006 l:000005 d:000005 TOP /usr/bin/irb1.9:12
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH rivate_class_method
c:0001 p:0000 s:0002 b:0002 l:000001 d:000001 TOP <dummy toplevel>:17
---------------------------
DBG> : "crash.rb:32:in `<<'"
DBG> : "crash.rb:32:in `irb_binding'"
DBG> : "/usr/lib/ruby/1.9.0/irb/workspace.rb:80:in `eval'"
DBG> : "/usr/lib/ruby/1.9.0/irb/workspace.rb:80:in `evaluate'"
DBG> : "/usr/lib/ruby/1.9.0/irb/context.rb:218:in `evaluate'"
DBG> : "/usr/lib/ruby/1.9.0/irb.rb:149:in `block (2 levels) in eval_input'"
DBG> : "/usr/lib/ruby/1.9.0/irb.rb:263:in `signal_status'"
DBG> : "/usr/lib/ruby/1.9.0/irb.rb:146:in `block in eval_input'"
DBG> : "/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:243:in `block (2 levels) =20
in each_top_level_statement'"
DBG> : "/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:230:in `loop'"
DBG> : "/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:230:in `block in =20
each_top_level_statement'"
DBG> : "/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:229:in `catch'"
DBG> : "/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:229:in `each_top_level_statement=
'"
DBG> : "/usr/lib/ruby/1.9.0/irb.rb:145:in `eval_input'"
DBG> : "/usr/lib/ruby/1.9.0/irb.rb:69:in `block in start'"
DBG> : "/usr/lib/ruby/1.9.0/irb.rb:68:in `catch'"
DBG> : "/usr/lib/ruby/1.9.0/irb.rb:68:in `start'"
DBG> : "/usr/bin/irb1.9:12:in `<main>'"
-- backtrace of native function call (Use addr2line) --
0xb7efac46
0xb7e243a9
0xb7e2441a
0xb7eaba56
0xb7f6e40c
0xb7ee5980
0xb7ef2b07
0xb7ef3a12
0xb7e56f2a
0xb7e013e5
0xb7f61434
0xb7ee6bfb
0xb7ee9b55
0xb7eec59e
0xb7ef1a84
0xb7ef2613
0xb7ef2a4e
0xb7ee6c30
0xb7ee9b55
0xb7eeb8b4
0xb7ef1a84
0xb7ef6add
0xb7e263c1
0xb7ee872c
0xb7ee6c12
0xb7ee9b55
0xb7eeb8b4
0xb7ef1a84
0xb7ef64a9
0xb7ee6c30
0xb7ee9b55
0xb7eeb8b4
0xb7ef1a84
0xb7ef64a9
0xb7ee6c30
0xb7ee9b55
0xb7eeb8b4
0xb7ef1a84
0xb7ef1cad
0xb7e26bd7
0xb7e28156
0x8048794
0xb7c17775
0x8048681
I am developing bindings for libconfig and discovered a strange bug in =20
irb1.9 (ruby 1.9.0 (2008-06-20 revision 17482) [i486-linux], irb =20
0.9.5(05/04/13); Debian GNU/Linux 5.0/lenny): ruby1.9 executes my =20
script nice, but irb crashes at some random place. Crash is affected =20
by most theoretically unlinked commands and may disappear even after =20
removing a comment (sic).
You can download my extension sources here =20
(http://files.whitequark.ru/libconfig-ruby.tbz2).
Crashing script:
--- BEGIN ---
require 'rconfig'
c =3D Config.new
c.read('test.cfg')
# =3D> false
c.append 'fixnum', Config::Fixnum.new(150)
# #<Config::Fixnum...>
f1 =3D Config::Fixnum.new(1)
c.append 'another_fixnum', f1
f2 =3D Config::Fixnum.new(256)
c.append 'next_fixnum', f2
p c.size
# =3D> 2
c.delete(f1) # by element
c.delete(0) # by index
c.delete('next_fixnum') # by name
# note: (at now) you cannot delete nested elements by Config#delete
# you can do c['nested.element'].parent.delete(c['nested.element'])
p c.size
# =3D> 0
l =3D Config::List.new
c.append 'the_list', l
l.append Config::String.new("abcdef")
l << Config::Float.new(3.14)
--- END ---
Sample log:
--- BEGIN ---
whitequark@hell:~$ tar xf libconfig-ruby.tbz2
whitequark@hell:~$ cd libconfig-ruby/ext/
whitequark@hell:~/libconfig-ruby/ext$ ruby1.9 extconf.rb
checking for rb_block_call() in ruby/ruby.h... yes
creating Makefile
whitequark@hell:~/libconfig-ruby/ext$ make
cc -I. -I/usr/include/ruby-1.9.0/i486-linux -I/usr/include/ruby-1.9.0 =20
-I. -DHAVE_RB_BLOCK_CALL -D_FILE_OFFSET_BITS=3D64 -fPIC =20
-fno-strict-aliasing -g -g -O2 -O2 -g -Wall -Wno-parentheses -fPIC =20
-o rconfig.o -c rconfig.c
cc -shared -o rconfig.so rconfig.o -L. -L/usr/lib -L. -rdynamic =20
-Wl,-export-dynamic -lruby1.9 -lconfig -lpthread -lrt -ldl =20
-lcrypt -lm -lc
whitequark@hell:~/libconfig-ruby/ext$ ruby1.9 crash.rb
3
whitequark@hell:~/libconfig-ruby/ext$ irb1.9 crash.rb
crash.rb(main):001:0> require 'rconfig'
=3D> true
crash.rb(main):002:0> c =3D Config.new
=3D> #<Config:0x9dd76d4 @config=3D#<Object:0x9dd76c0>>
crash.rb(main):003:0>
crash.rb(main):004:0* c.read('test.cfg')
=3D> false
crash.rb(main):005:0> # =3D> false
crash.rb(main):006:0*
crash.rb(main):007:0* c.append 'fixnum', Config::Fixnum.new(150)
=3D> #<Config::Fixnum:0x9dc0dd0 @setting=3D#<Object:0x9dc0d30>, =20
@value=3D150, @format=3D0>
crash.rb(main):008:0> # #<Config::Fixnum...>
crash.rb(main):009:0*
crash.rb(main):010:0* f1 =3D Config::Fixnum.new(1)
=3D> #<Config::Fixnum:0x9db6a9c @setting=3Dnil, @value=3D1, @format=3D0>
crash.rb(main):011:0> c.append 'another_fixnum', f1
=3D> #<Config::Fixnum:0x9db6a9c @setting=3D#<Object:0x9db11f0>, @value=3D1, =
=20
@format=3D0>
crash.rb(main):012:0>
crash.rb(main):013:0* f2 =3D Config::Fixnum.new(256)
=3D> #<Config::Fixnum:0x9daa828 @setting=3Dnil, @value=3D256, @format=3D0>
crash.rb(main):014:0> c.append 'next_fixnum', f2
=3D> #<Config::Fixnum:0x9daa828 @setting=3D#<Object:0x9da86f4>, =20
@value=3D256, @format=3D0>
crash.rb(main):015:0>
crash.rb(main):016:0* p c.size
3
=3D> 3
crash.rb(main):017:0> # =3D> 2
crash.rb(main):018:0*
crash.rb(main):019:0* c.delete(f1) # by element
=3D> nil
crash.rb(main):020:0> c.delete(0) # by index
=3D> nil
crash.rb(main):021:0> c.delete('next_fixnum') # by name
=3D> nil
crash.rb(main):022:0> # note: (at now) you cannot delete nested =20
elements by Config#delete
crash.rb(main):023:0* # you can do =20
c['nested.element'].parent.delete(c['nested.element'])
crash.rb(main):024:0*
crash.rb(main):025:0* p c.size
=3D> 0
crash.rb(main):026:0> # =3D> 0
crash.rb(main):027:0*
crash.rb(main):028:0* l =3D Config::List.new
=3D> #<Config::List:0x9ccb128 @list=3D[], @setting=3Dnil>
crash.rb(main):029:0> c.append 'the_list', l
=3D> #<Config::List:0x9ccb128 @list=3D[], @setting=3D#<Object:0x9cc91fc>>
crash.rb(main):030:0>
crash.rb(main):031:0* l.append Config::String.new("abcdef")
=3D> #<Config::String:0x9c7e92c @setting=3D#<Object:0x9c7e8c8>, =20
@value=3D"abcdef", @format=3D0>
crash.rb(main):032:0> l << Config::Float.new(3.14)
crash.rb:32: [BUG] Segmentation fault
ruby 1.9.0 (2008-06-20 revision 17482) [i486-linux]
-- control frame ----------
c:0024 p:---- s:0080 b:0080 l:000079 d:000079 CFUNC :<<
c:0023 p:0021 s:0076 b:0076 l:001f74 d:0002fc EVAL crash.rb:32
c:0022 p:---- s:0074 b:0074 l:000073 d:000073 FINISH :empty?
c:0021 p:---- s:0072 b:0072 l:000071 d:000071 CFUNC :eval
c:0020 p:0023 s:0065 b:0065 l:000064 d:000064 METHOD =20
/usr/lib/ruby/1.9.0/irb/workspace.rb:80
c:0019 p:0025 s:0058 b:0057 l:000056 d:000056 METHOD =20
/usr/lib/ruby/1.9.0/irb/context.rb:218
c:0018 p:0024 s:0052 b:0052 l:0007bc d:000051 BLOCK =20
/usr/lib/ruby/1.9.0/irb.rb:149
c:0017 p:0025 s:0044 b:0044 l:000043 d:000043 METHOD =20
/usr/lib/ruby/1.9.0/irb.rb:263
c:0016 p:0009 s:0039 b:0039 l:0007bc d:000038 BLOCK =20
/usr/lib/ruby/1.9.0/irb.rb:146
c:0015 p:0093 s:0035 b:0035 l:000022 d:000034 BLOCK =20
/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:243
c:0014 p:---- s:0034 b:0034 l:000033 d:000033 FINISH :block_given?
c:0013 p:---- s:0032 b:0032 l:000031 d:000031 CFUNC :loop
c:0012 p:0007 s:0029 b:0029 l:000022 d:000028 BLOCK =20
/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:230
c:0011 p:---- s:0029 b:0029 l:000028 d:000028 FINISH :each
c:0010 p:---- s:0027 b:0027 l:000026 d:000026 CFUNC :catch
c:0009 p:0017 s:0023 b:0023 l:000022 d:000022 METHOD =20
/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:229
c:0008 p:0034 s:0020 b:0020 l:0007bc d:0007bc METHOD =20
/usr/lib/ruby/1.9.0/irb.rb:145
c:0007 p:0009 s:0017 b:0017 l:001d6c d:000016 BLOCK =20
/usr/lib/ruby/1.9.0/irb.rb:69
c:0006 p:---- s:0017 b:0017 l:000016 d:000016 FINISH null)
c:0005 p:---- s:0015 b:0015 l:000014 d:000014 CFUNC :catch
c:0004 p:0152 s:0011 b:0011 l:001d6c d:001d6c METHOD =20
/usr/lib/ruby/1.9.0/irb.rb:68
c:0003 p:0033 s:0006 b:0006 l:000005 d:000005 TOP /usr/bin/irb1.9:12
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH rivate_class_method
c:0001 p:0000 s:0002 b:0002 l:000001 d:000001 TOP <dummy toplevel>:17
---------------------------
DBG> : "crash.rb:32:in `<<'"
DBG> : "crash.rb:32:in `irb_binding'"
DBG> : "/usr/lib/ruby/1.9.0/irb/workspace.rb:80:in `eval'"
DBG> : "/usr/lib/ruby/1.9.0/irb/workspace.rb:80:in `evaluate'"
DBG> : "/usr/lib/ruby/1.9.0/irb/context.rb:218:in `evaluate'"
DBG> : "/usr/lib/ruby/1.9.0/irb.rb:149:in `block (2 levels) in eval_input'"
DBG> : "/usr/lib/ruby/1.9.0/irb.rb:263:in `signal_status'"
DBG> : "/usr/lib/ruby/1.9.0/irb.rb:146:in `block in eval_input'"
DBG> : "/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:243:in `block (2 levels) =20
in each_top_level_statement'"
DBG> : "/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:230:in `loop'"
DBG> : "/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:230:in `block in =20
each_top_level_statement'"
DBG> : "/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:229:in `catch'"
DBG> : "/usr/lib/ruby/1.9.0/irb/ruby-lex.rb:229:in `each_top_level_statement=
'"
DBG> : "/usr/lib/ruby/1.9.0/irb.rb:145:in `eval_input'"
DBG> : "/usr/lib/ruby/1.9.0/irb.rb:69:in `block in start'"
DBG> : "/usr/lib/ruby/1.9.0/irb.rb:68:in `catch'"
DBG> : "/usr/lib/ruby/1.9.0/irb.rb:68:in `start'"
DBG> : "/usr/bin/irb1.9:12:in `<main>'"
-- backtrace of native function call (Use addr2line) --
0xb7efac46
0xb7e243a9
0xb7e2441a
0xb7eaba56
0xb7f6e40c
0xb7ee5980
0xb7ef2b07
0xb7ef3a12
0xb7e56f2a
0xb7e013e5
0xb7f61434
0xb7ee6bfb
0xb7ee9b55
0xb7eec59e
0xb7ef1a84
0xb7ef2613
0xb7ef2a4e
0xb7ee6c30
0xb7ee9b55
0xb7eeb8b4
0xb7ef1a84
0xb7ef6add
0xb7e263c1
0xb7ee872c
0xb7ee6c12
0xb7ee9b55
0xb7eeb8b4
0xb7ef1a84
0xb7ef64a9
0xb7ee6c30
0xb7ee9b55
0xb7eeb8b4
0xb7ef1a84
0xb7ef64a9
0xb7ee6c30
0xb7ee9b55
0xb7eeb8b4
0xb7ef1a84
0xb7ef1cad
0xb7e26bd7
0xb7e28156
0x8048794
0xb7c17775
0x8048681