为了问另一个问题,我一遍又一遍地加载和重新加载同一个文件。我注意到有相当一部分时间load
会失败,没有任何明显的原因。这ruby 1.9.3p448 (2013-06-27) [i386-mingw32]
几乎与 metasploit 打包在一起。
这是 irb 会话的记录(源文件附加在下面)——对于这个记录,我什么也没做,只是按一下up-arrow
键并按回车键,load
以大约一秒的间隔重复相同的命令:
C:\test-ruby>
C:\test-ruby>irb
irb(main):001:0> load 'test-pack.rb'
=> true
irb(main):002:0> load 'test-pack.rb'
RuntimeError:
from test-pack.rb:11:in `<top (required)>'
from (irb):2:in `load'
from (irb):2
from C:/metasploit/ruby/bin/irb:12:in `<main>'
irb(main):003:0> load 'test-pack.rb'
=> true
irb(main):004:0> load 'test-pack.rb'
=> true
irb(main):005:0> load 'test-pack.rb'
=> true
irb(main):006:0> load 'test-pack.rb'
RuntimeError:
from test-pack.rb:11:in `<top (required)>'
from (irb):6:in `load'
from (irb):6
from C:/metasploit/ruby/bin/irb:12:in `<main>'
irb(main):007:0> load 'test-pack.rb'
RuntimeError:
from test-pack.rb:11:in `<top (required)>'
from (irb):7:in `load'
from (irb):7
from C:/metasploit/ruby/bin/irb:12:in `<main>'
irb(main):008:0> load 'test-pack.rb'
=> true
irb(main):009:0> load 'test-pack.rb'
=> true
irb(main):010:0> load 'test-pack.rb'
RuntimeError:
from test-pack.rb:11:in `<top (required)>'
from (irb):10:in `load'
from (irb):10
from C:/metasploit/ruby/bin/irb:12:in `<main>'
irb(main):011:0> load 'test-pack.rb'
=> true
irb(main):012:0> load 'test-pack.rb'
=> true
irb(main):013:0> load 'test-pack.rb'
=> true
irb(main):014:0> load 'test-pack.rb'
=> true
irb(main):015:0> load 'test-pack.rb'
=> true
irb(main):016:0> load 'test-pack.rb'
=> true
irb(main):017:0> load 'test-pack.rb'
=> true
irb(main):018:0> load 'test-pack.rb'
=> true
irb(main):019:0> load 'test-pack.rb'
=> true
irb(main):020:0> load 'test-pack.rb'
=> true
irb(main):021:0> load 'test-pack.rb'
RuntimeError:
from test-pack.rb:11:in `<top (required)>'
from (irb):21:in `load'
from (irb):21
from C:/metasploit/ruby/bin/irb:12:in `<main>'
irb(main):022:0> load 'test-pack.rb'
=> true
irb(main):023:0> load 'test-pack.rb'
=> true
irb(main):024:0> load 'test-pack.rb'
=> true
irb(main):025:0> load 'test-pack.rb'
=> true
irb(main):026:0> load 'test-pack.rb'
=> true
irb(main):027:0>
这是 test-pack.rb 代码——这个文件的第 11 行恰好是这一fail unless $bits.encoding == $ptr.encoding
行(至少有人认为应该是确定性的):
$save = "xyz\0"
$ptr = [$save].pack("p")
$ptrs = [$ptr, $ptr]
$bits = ""
$bits << $ptr
fail unless $bits == $ptr
fail unless $bits.encoding == $ptr.encoding
def x(s)
s.bytes.to_a.map {|p| ("0" + p.to_s(16))[-2,2]}.reverse.join(".")
end
def see(tag, p)
puts "f#{tag} #{x(p)} #{p.encoding} #{p.class} #{x([p.object_id].pack("I"))}"
p.unpack("p")[0]
end
def f1
see 1, $bits[0, 4]
end
def f2
p = $bits[0, 4]
see 2, p
end
def f3
p = $bits[0, 4].dup
see 3, p
end
def f4
p = $bits[0, 4].bytes.to_a.join
see 4, p
end
def f5
p = $bits[0, 4].bytes.to_a.join.force_encoding("ASCII-8BIT")
see 5, p
end
def f6
p = $bits[0, 4].bytes.to_a.pack("CCCC")
see 13, p
end
def f7
see 7, $ptr.clone
end
def f11
see 11, $ptr
end
def f12
p = $ptr
see 12, p
end
def f13
see 13, $ptrs[0]
end
def f14
see 14, $ptrs[1]
end
def f15
see 15, $ptr.dup
end
def f16
see 16, $ptrs[1].dup
end
def f17
see 17, $ptrs[1].clone
end