From: Akira Tanaka Date: 2012-02-19T12:27:05+09:00 Subject: [ruby-dev:45262] [ruby-trunk - Bug #6046][Open] Berkeley DB dbm_open in libc is called even if --with-dbm-type=gdbm_compat is specified on FreeBSD Issue #6046 has been reported by Akira Tanaka. ---------------------------------------- Bug #6046: Berkeley DB dbm_open in libc is called even if --with-dbm-type=gdbm_compat is specified on FreeBSD https://bugs.ruby-lang.org/issues/6046 Author: Akira Tanaka Status: Open Priority: Normal Assignee: Category: Target version: ruby -v: ruby 2.0.0dev (2012-02-19 trunk 34688) [x86_64-freebsd8.2] FreeBSD 8.2 で、--with-dbm-type=gdbm_compat として ext/dbm に GDBM を 使わせようとしたときに、(libc 中の) Berkeley DB の dbm_open を呼んで しまうようです。 再現手順は以下のとおりです。 % uname -a FreeBSD freebsd82-64 8.2-RELEASE-p3 FreeBSD 8.2-RELEASE-p3 #0: Tue Sep 27 18:45:57 UTC 2011 root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC amd64 % mkdir g % cd g % prefix=`pwd` % echo $prefix /home/akr/g % fetch ftp://ftp.jaist.ac.jp/pub/GNU/gdbm/gdbm-1.10.tar.gz % tar xf gdbm-1.10.tar.gz % ./configure --prefix=$prefix --enable-libgdbm-compat % make % make install % cd .. % export LD_RUN_PATH=$prefix/lib % svn co http://svn.ruby-lang.org/repos/ruby/trunk ruby % cd ruby % autoconf % ./configure --prefix=$prefix --with-opt-dir=$prefix --with-dbm-type=gdbm_compat % make % make install % ./ruby -v ruby 2.0.0dev (2012-02-19 trunk 34688) [x86_64-freebsd8.2] % ./ruby -rdbm -e 'DBM.open("a")' -e:1: [BUG] Segmentation fault ruby 2.0.0dev (2012-02-19 trunk 34688) [x86_64-freebsd8.2] -- Control frame information ----------------------------------------------- c:0004 p:---- s:0010 b:0010 l:000009 d:000009 CFUNC :open c:0003 p:0017 s:0006 b:0006 l:001d88 d:001f08 EVAL -e:1 c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH c:0001 p:0000 s:0002 b:0002 l:001d88 d:001d88 TOP -- Ruby level backtrace information ---------------------------------------- -e:1:in `
' -e:1:in `open' -- Other runtime information ----------------------------------------------- * Loaded script: -e * Loaded features: 0 enumerator.so 1 /home/akr/g/lib/ruby/2.0.0/x86_64-freebsd8.2/enc/encdb.so 2 /home/akr/g/lib/ruby/2.0.0/x86_64-freebsd8.2/enc/trans/transdb.so 3 /home/akr/g/lib/ruby/2.0.0/rubygems/defaults.rb 4 /home/akr/g/lib/ruby/2.0.0/x86_64-freebsd8.2/rbconfig.rb 5 /home/akr/g/lib/ruby/2.0.0/rubygems/deprecate.rb 6 /home/akr/g/lib/ruby/2.0.0/rubygems/exceptions.rb 7 /home/akr/g/lib/ruby/2.0.0/rubygems/custom_require.rb 8 /home/akr/g/lib/ruby/2.0.0/rubygems.rb 9 /home/akr/g/lib/ruby/2.0.0/x86_64-freebsd8.2/dbm.so [NOTE] You may have encountered a bug in the Ruby interpreter or extension libraries. Bug reports are welcome. For details: http://www.ruby-lang.org/bugreport.html zsh: abort (core dumped) ./ruby -rdbm -e 'DBM.open("a")' % ls -l a.* -rw-r--r-- 1 akr akr 0 Feb 19 12:07 a.db % file a.db a.db: empty まず、BUS Error が起きていますが、これは、libc の dbm_open を呼んでしまうのに、 dbm_pagfno は GDBM のものを呼んでしまうためです。 (dbm_pagfno は libc には入っていないので、選択の余地なく GDBM のが呼ばれます) 本質的な問題は、生成された a.db というファイル名からわかるように、 dbm_open は libc に入っている、Berkeley DB のものが呼ばれていることです。 (ファイルが空なのは dbm_close せずに BUS Error で終わっているからでしょう) ldd で調べると、dbm.so にはちゃんと GDBM がリンクされています。 % ldd .ext/x86_64-freebsd8.2/dbm.so .ext/x86_64-freebsd8.2/dbm.so: libgdbm_compat.so.4 => /home/akr/g/lib/libgdbm_compat.so.4 (0x800c00000) libgdbm.so.4 => /home/akr/g/lib/libgdbm.so.4 (0x800d03000) libthr.so.3 => /lib/libthr.so.3 (0x800e0b000) librt.so.1 => /usr/lib/librt.so.1 (0x800f24000) libcrypt.so.5 => /lib/libcrypt.so.5 (0x801029000) libm.so.5 => /lib/libm.so.5 (0x801142000) libc.so.7 => /lib/libc.so.7 (0x800647000) また、LD_PRELOAD で libgdbm_compat.so.4 を最初に読み込ませてやれば、 意図どおりに GDBM の dbm_open が呼ばれます。 % LD_PRELOAD=$prefix/lib/libgdbm_compat.so.4 ./ruby -rdbm -e 'DBM.open("a")' % ls -l a.* -rw-r--r-- 1 akr akr 16 Feb 19 12:10 a.dir -rw-r--r-- 1 akr akr 49152 Feb 19 12:10 a.pag % file a.* a.dir: GNU dbm 2.x database a.pag: data で、FreeBSD で、LD_PRELOAD とか変なことをせずに dbm.so から、GDBM の dbm_open を呼び出すにはどうしたらいいんでしょう? まぁ、FreeBSD で、GDBM を (gdbm 拡張でなく、わざわざ) dbm 拡張経由で 使うというのはまずない状況という気はするんですが。 -- http://bugs.ruby-lang.org/