Bug #5808

"a = []; a << a; puts JSON.dump(a)" aborted

Added by Akira Tanaka over 2 years ago. Updated 8 months ago.

[ruby-dev:45048]
Status:Assigned
Priority:Normal
Assignee:Yui NARUSE
Category:-
Target version:-
ruby -v:ruby 2.0.0dev (2011-12-26 trunk 34127) [x86_64-linux] Backport:

Description

ふと a = []; a << a; puts JSON.dump(a) としてみたら、abort しました。

% ./ruby -rjson -ve 'a = []; a << a; puts JSON.dump(a)'
ruby 2.0.0dev (2011-12-26 trunk 34127) [x8664-linux]
/home/ruby/tcstate/lib/ruby/1.9.1/json/common.rb:216: stack level too deep (SystemStackError)
*** glibc detected *** ./ruby: double free or corruption (out): 0x00007fd5c0c18240 ***
======= Backtrace: =========
/lib/libc.so.6(+0x71ad6)[0x7fd5bdf81ad6]
/lib/libc.so.6(cfree+0x6c)[0x7fd5bdf8684c]
./ruby(+0x14053d)[0x7fd5bf0b253d]
./ruby(ruby
vmdestruct+0x66)[0x7fd5bf0b1e68]
./ruby(ruby
cleanup+0x386)[0x7fd5bef9401f]
./ruby(rubyrunnode+0x45)[0x7fd5bef941e5]
./ruby(+0x2088d)[0x7fd5bef9288d]
/lib/libc.so.6(_libcstartmain+0xfd)[0x7fd5bdf2ec4d]
./ruby(+0x20749)[0x7fd5bef92749]
======= Memory map: ========
7fd5b8000000-7fd5b8021000 rw-p 00000000 00:00 0
7fd5b8021000-7fd5bc000000 ---p 00000000 00:00 0
7fd5bcaf3000-7fd5bcb09000 r-xp 00000000 08:01 6627331 /lib/libgcc
s.so.1
7fd5bcb09000-7fd5bcd08000 ---p 00016000 08:01 6627331 /lib/libgccs.so.1
7fd5bcd08000-7fd5bcd09000 rw-p 00015000 08:01 6627331 /lib/libgcc
s.so.1
7fd5bcd09000-7fd5bcd11000 r-xp 00000000 08:01 14934439 /home/ruby/tcstate/lib/ruby/1.9.1/x8664-linux/json/ext/generator.so
7fd5bcd11000-7fd5bcf10000 ---p 00008000 08:01 14934439 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/json/ext/generator.so
7fd5bcf10000-7fd5bcf11000 rw-p 00007000 08:01 14934439 /home/ruby/tcstate/lib/ruby/1.9.1/x8664-linux/json/ext/generator.so
7fd5bcf11000-7fd5bcf12000 r-xp 00000000 08:01 14934499 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/utf32le.so
7fd5bcf12000-7fd5bd112000 ---p 00001000 08:01 14934499 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/utf32le.so
7fd5bd112000-7fd5bd113000 rw-p 00001000 08:01 14934499 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/utf32le.so
7fd5bd113000-7fd5bd114000 r-xp 00000000 08:01 14934502 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/utf32be.so
7fd5bd114000-7fd5bd314000 ---p 00001000 08:01 14934502 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/utf32be.so
7fd5bd314000-7fd5bd315000 rw-p 00001000 08:01 14934502 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/utf32be.so
7fd5bd315000-7fd5bd317000 r-xp 00000000 08:01 14934492 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/utf16le.so
7fd5bd317000-7fd5bd516000 ---p 00002000 08:01 14934492 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/utf16le.so
7fd5bd516000-7fd5bd517000 rw-p 00001000 08:01 14934492 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/utf16le.so
7fd5bd517000-7fd5bd519000 r-xp 00000000 08:01 14934483 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/utf16be.so
7fd5bd519000-7fd5bd718000 ---p 00002000 08:01 14934483 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/utf16be.so
7fd5bd718000-7fd5bd719000 rw-p 00001000 08:01 14934483 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/utf16be.so
7fd5bd719000-7fd5bd720000 r-xp 00000000 08:01 14934440 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/json/ext/parser.so
7fd5bd720000-7fd5bd91f000 ---p 00007000 08:01 14934440 /home/ruby/tcstate/lib/ruby/1.9.1/x8664-linux/json/ext/parser.so
7fd5bd91f000-7fd5bd920000 rw-p 00006000 08:01 14934440 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/json/ext/parser.so
7fd5bd920000-7fd5bd922000 r-xp 00000000 08:01 14934465 /home/ruby/tcstate/lib/ruby/1.9.1/x8664-linux/enc/trans/transdb.so
7fd5bd922000-7fd5bdb22000 ---p 00002000 08:01 14934465 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/trans/transdb.so
7fd5bdb22000-7fd5bdb23000 rw-p 00002000 08:01 14934465 /home/ruby/tcstate/lib/ruby/1.9.1/x8664-linux/enc/trans/transdb.so
7fd5bdb23000-7fd5bdb25000 r-xp 00000000 08:01 14934498 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/encdb.so
7fd5bdb25000-7fd5bdd24000 ---p 00002000 08:01 14934498 /home/ruby/tcstate/lib/ruby/1.9.1/x8664-linux/enc/encdb.so
7fd5bdd24000-7fd5bdd25000 rw-p 00001000 08:01 14934498 /home/ruby/tcstate/lib/ruby/1.9.1/x86
64-linux/enc/encdb.so
7fd5bdd25000-7fd5bdf10000 r--p 00000000 08:01 18989057 /usr/lib/locale/locale-archive
7fd5bdf10000-7fd5be068000 r-xp 00000000 08:01 6627339 /lib/libc-2.11.2.so
7fd5be068000-7fd5be267000 ---p 00158000 08:01 6627339 /lib/libc-2.11.2.so
7fd5be267000-7fd5be26b000 r--p 00157000 08:01 6627339 /lib/libc-2.11.2.so
7fd5be26b000-7fd5be26c000 rw-p 0015b000 08:01 6627339 /lib/libc-2.11.2.so
7fd5be26c000-7fd5be271000 rw-p 00000000 00:00 0
7fd5be271000-7fd5be2f1000 r-xp 00000000 08:01 6627348 /lib/libm-2.11.2.so
7fd5be2f1000-7fd5be4f1000 ---p 00080000 08:01 6627348 /lib/libm-2.11.2.so
7fd5be4f1000-7fd5be4f2000 r--p 00080000 08:01 6627348 /lib/libm-2.11.2.so
7fd5be4f2000-7fd5be4f3000 rw-p 00081000 08:01 6627348 /lib/libm-2.11.2.so
7fd5be4f3000-7fd5be4fb000 r-xp 00000000 08:01 6627350 /lib/libcrypt-2.11.2.so
7fd5be4fb000-7fd5be6fa000 ---p 00008000 08:01 6627350 /lib/libcrypt-2.11.2.so
7fd5be6fa000-7fd5be6fb000 r--p 00007000 08:01 6627350 /lib/libcrypt-2.11.2.so
7fd5be6fb000-7fd5be6fc000 rw-p 00008000 08:01 6627350 /lib/libcrypt-2.11.2.so
7fd5be6fc000-7fd5be72a000 rw-p 00000000 00:00 0
7fd5be72a000-7fd5be72c000 r-xp 00000000 08:01 6627338 /lib/libdl-2.11.2.so
7fd5be72c000-7fd5be92c000 ---p 00002000 08:01 6627338 /lib/libdl-2.11.2.so
7fd5be92c000-7fd5be92d000 r--p 00002000 08:01 6627338 /lib/libdl-2.11.2.so
7fd5be92d000-7fd5be92e000 rw-p 00003000 08:01 6627338 /lib/libdl-2.11.2.so
7fd5be92e000-7fd5be935000 r-xp 00000000 08:01 6627341 /lib/librt-2.11.2.so
7fd5be935000-7fd5beb34000 ---p 00007000 08:01 6627341 /lib/librt-2.11.2.so
7fd5beb34000-7fd5beb35000 r--p 00006000 08:01 6627341 /lib/librt-2.11.2.so
7fd5beb35000-7fd5beb36000 rw-p 00007000 08:01 6627341 /lib/librt-2.11.2.so
7fd5beb36000-7fd5beb4d000 r-xp 00000000 08:01 6627340 /lib/libpthread-2.11.2.so
7fd5beb4d000-7fd5bed4c000 ---p 00017000 08:01 6627340 /lib/libpthread-2.11.2.so
7fd5bed4c000-7fd5bed4d000 r--p 00016000 08:01 6627340 /lib/libpthread-2.11.2.so
7fd5bed4d000-7fd5bed4e000 rw-p 00017000 08:01 6627340 /lib/libpthread-2.11.2.so
7fd5bed4e000-7fd5bed52000 rw-p 00000000 00:00 0
7fd5bed52000-7fd5bed70000 r-xp 00000000 08:01 6627351 /lib/ld-2.11.2.so
7fd5bef57000-7fd5bef5c000 rw-p 00000000 00:00 0
7fd5bef68000-7fd5bef69000 rw-p 00000000 00:00 0
7fd5bef69000-7fd5bef6a000 ---p 00000000 00:00 0
7fd5bef6a000-7fd5bef6f000 rw-p 00000000 00:00 0
7fd5bef6f000-7fd5bef70000 r--p 0001d000 08:01 6627351 /lib/ld-2.11.2.so
7fd5bef70000-7fd5bef71000 rw-p 0001e000 08:01 6627351 /lib/ld-2.11.2.so
7fd5bef71000-7fd5bef72000 rw-p 00000000 00:00 0
7fd5bef72000-7fd5bf1ad000 r-xp 00000000 08:01 14797288 /home/ruby/tcstate/ruby/ruby
7fd5bf3ac000-7fd5bf3b2000 rw-p 0023a000 08:01 14797288 /home/ruby/tcstate/ruby/ruby
7fd5bf3b2000-7fd5bf3d0000 rw-p 00000000 00:00 0
7fd5c0bb3000-7fd5c0efa000 rw-p 00000000 00:00 0 [heap]
7fffaca6b000-7fffad26a000 rw-p 00000000 00:00 0 [stack]
7fffad3ff000-7fffad400000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
zsh: abort ./ruby -rjson -ve 'a = []; a << a; puts JSON.dump(a)'

History

#1 Updated by Yui NARUSE over 2 years ago

  • Status changed from Open to Assigned
  • Assignee set to Yui NARUSE

#2 Updated by Yui NARUSE over 2 years ago

うーん、よろしくは無いと思うんですが、これは速度のために意図的にやっているように思います。
循環参照をチェックしたい場合は、JSON.dump ではなく、JSON() を使ってください。

#3 Updated by Joel McCracken 8 months ago

I wonder what the correct behavior should be here? Recursive data structures are always tricky for serialization.

Edit: I should also mention that I just verified this bug's existence on 2.0.0-p0.

#4 Updated by Shyouhei Urabe 8 months ago

JoelMcCracken (Joel McCracken) wrote:

I wonder what the correct behavior should be here? Recursive data structures are always tricky for serialization.

I believe current situation is not the "correct" one, at least.

If it's a JSON spec that a recursive data structure cannot be represented, any error other than stack drain is much wiser.

#5 Updated by Akinori MUSHA 8 months ago

Oj and Yajl have no cycle detection or depth limit either.

Maybe it's worth contacting authors of all known JSON libraries, probably via the multi_json project.

Also available in: Atom PDF