これと 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
これってスレッド安全ではない。
最近のコメント