これと DL のいくつかのメソッドも。
ruby/dl を使うと ruby が簡単に落ちる。仕方がないことだけど。
$ cat t2.rb require "dl" sp = 'abc'.to_ptr sp.ptr.to_s $ ruby-1.8 -v t2.rb ruby 1.8.6 (2007-03-05 patchlevel 5000) [i686-linux] t2.rb:3: [BUG] Segmentation fault ruby 1.8.6 (2007-03-05) [i686-linux] zsh: abort ruby-1.8 -v t2.rb
これを防ぐアドホックな方法を考えてみた。
class DL::PtrData
alias __to_s to_s
def to_s(*args)
if size == 0 and (DL::PtrData.malloc(0).to_i - to_i).abs >= 100 * 1024**2
raise DL::DLError, "self seems to be an invalid pointer"
else
__to_s(*args)
end
end
end
スクリプトから C のポインタを安全に扱うなどという、都合の良い仕組みは可能だろうか?
ちなみに、1.9 でも同じように落ちる。
$ cat t3.rb
require 'dl'
sp = DL::CPtr.to_ptr('abc')
sp.ptr.to_s
$ ruby-1.9 -v t3.rb
ruby 1.9.0 (2007-02-27 patchlevel 0) [i686-linux]
-- stack frame ------------
0000 (0x404ef008): 00000004
0001 (0x404ef00c): 00000005
0002 (0x404ef010): 404d5bbc
0003 (0x404ef014): 00000004
0004 (0x404ef018): 00000001
0005 (0x404ef01c): 404d5ba8
0006 (0x404ef020): 00000004
0007 (0x404ef024): 00000001 <- lfp <- dfp
-- control frame ----------
c:0004 p:---- s:0008 b:0008 l:000007 d:000007 CFUNC :to_s
c:0003 p:0043 s:0005 b:0005 l:000004 d:000004 TOP t3.rb:3
c:0002 p:---- s:0002 b:0002 l:000001 d:000001 FINISH
c:0001 p:---- s:0000 b:-001 l:000000 d:000000 ------
---------------------------
DBG> : "t3.rb:3:in `<main>'"
-- backtrace of native function call (Use addr2line) --
0x80d303e
-------------------------------------------------------
[BUG] Segmentation fault
ruby 1.9.0 (2007-02-27) [i686-linux]
zsh: abort ruby-1.9 -v t3.rb
ところで、以下のスクリプトが落ちるのはバグのような気がする。
$ cat t2.rb
require "dl"
sp = ['a', 'b', 'c'].to_ptr
sp.to_a('S')
$ ruby-1.8 -v t2.rb
ruby 1.8.6 (2007-03-05 patchlevel 5000) [i686-linux]
t2.rb:3: [BUG] Segmentation fault
ruby 1.8.6 (2007-03-05) [i686-linux]
zsh: abort ruby-1.8 -v t2.rb
これってスレッド安全ではない。
最近のコメント