13

我想观察 YARV 执行的 Ruby 字节码,事后。

我怎样才能得到这个?

这里的其他人告诉这是不可能的。不过有hotruby框架好像是执行ruby字节码的,所以很纳闷……

非常感谢!

4

3 回答 3

15

您可以使用解释器很好地将一块 Ruby 代码编译为字节码(当然,只有 Ruby MRI 1.9 可以工作,因为它是唯一使用 YARV 虚拟机的实现),并获得其 Ruby-ish 表示:

ruby-1.9.2-p180 :007 > require 'pp'
 => true
ruby-1.9.2-p180 :008 > pp RubyVM::InstructionSequence.compile('puts "hello world"').to_a
["YARVInstructionSequence/SimpleDataFormat",
 1,
 2,
 1,
 {:arg_size=>0, :local_size=>1, :stack_max=>2},
 "<compiled>",
 "<compiled>",
 nil,
 1,
 :top,
 [],
 0,
 [],
 [1,
  [:trace, 1],
  [:putnil],
  [:putstring, "hello world"],
  [:send, :puts, 1, nil, 8, 0],
  [:leave]]]

这正是 HotRuby 所做的:它使用 MRI 作为解析器和 AST-to-YARV 转换器,然后只执行 JavaScript 中的代码。

您可以使用该方法获取现有方法的字节码RubyVM::InstructionSequence.disasm。它需要 aProc作为参数,因此首先使用 . 将您的方法转换为块object.method(:name).to_proc

我不太清楚你所说的“验尸”是什么意思。在异常处理程序中?在 Ruby 与 SEGV 崩溃之后?后者几乎不可能,因为损坏的解释器无法成功运行任何 Ruby 代码。你需要为此做一个 C 扩展,并做很多肮脏的 hack。通过在异常处理程序中使用这个技巧是完全可能的。

于 2011-08-01T09:13:14.833 回答
2

据我了解,RubyVM::InstructionSequence.compile是你需要的。

于 2011-08-01T09:10:34.290 回答
0

要获得更具可读性的输出,您可以使用disasmaftercompile

[17] pry(main)> code = <<STR
[17] pry(main)* puts "Hello World"
[17] pry(main)* STR
=> "puts \"Hello World\"\n"
[19] pry(main)> puts RubyVM::InstructionSequence.compile(code).disasm
== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
0000 trace            1                                               (   1)
0002 putself
0003 putstring        "Hello World"
0005 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>
0007 leave
=> nil
[20] pry(main)>
于 2019-02-03T09:22:25.017 回答