oracle / truffleruby

A high performance implementation of the Ruby programming language, built on GraalVM.
https://www.graalvm.org/ruby/
Other
3.01k stars 184 forks source link

rbtrace: rb_add_event_hook cannot be found #1993

Closed deepj closed 3 years ago

deepj commented 4 years ago
truffleruby 20.2.0-dev-79470c75, like ruby 2.6.5, GraalVM CE Native [x86_64-darwin]

To reproduce:

server.rb (taken from https://github.com/tmm1/rbtrace/blob/master/README.md):

require 'rbtrace'

class String
  def multiply_vowels(num)
    @test = 123
    gsub(/[aeiou]/){ |m| m*num }
  end
end

while true
  proc {
    Dir.chdir("/tmp") do
      Dir.pwd
      Process.pid
      'hello'.multiply_vowels(3)
      sleep rand*0.5
    end
  }.call
end
gem install rbtrace
ruby server.rb &
rbtrace -p 67278 -m sleep

NOTE: 67278 is the current PID of previous run server.rb script on my system. So you need to enter your current one on your system.

Error:

~/.gem/truffleruby/2.6.5/gems/rbtrace-0.4.12/ext/rbtrace.c:1073:in `rbtrace__receive': External LLVMFunction msgpack_unpack_next cannot be found. (LLVMLinkerException) (RuntimeError)
Translated to internal error
    from ~/.gem/truffleruby/2.6.5/gems/rbtrace-0.4.12/ext/rbtrace.c:1115:in `signal_handler_wrapper'
    from ~/.rubies/truffleruby-dev/lib/truffle/truffle/cext.rb:913:in `block in rb_proc_new'
    from server.rb:16:in `sleep'
    from server.rb:16:in `block (2 levels) in <main>'
    from server.rb:12:in `chdir'
    from server.rb:12:in `block in <main>'
    from server.rb:11:in `call'
    from server.rb:11:in `<main>'
eregon commented 4 years ago

Looks like msgpack is linked statically: https://github.com/tmm1/rbtrace/blob/4a1414c16353d319e6c510939ac5eeb847bcf544/ext/extconf.rb#L55

So we should try if it works when the toolchain is on the PATH and CC/CXX are set, similar to other issues related to static linking.

eregon commented 3 years ago

By prepending the toolchain to PATH like in #1974, then this happens:

ruby server.rb
107645
/home/eregon/code/truffleruby-ws/truffleruby/mxbuild/truffleruby-jvm/languages/ruby/lib/gems/gems/rbtrace-0.4.14/ext/rbtrace.c:532:in `event_hook_install': External LLVMFunction rb_add_event_hook cannot be found. (com.oracle.truffle.llvm.runtime.except.LLVMLinkerException) (RuntimeError)
Translated to internal error
    from /home/eregon/code/truffleruby-ws/truffleruby/mxbuild/truffleruby-jvm/languages/ruby/lib/gems/gems/rbtrace-0.4.14/ext/rbtrace.c:755:in `rbtracer_add'
    from /home/eregon/code/truffleruby-ws/truffleruby/mxbuild/truffleruby-jvm/languages/ruby/lib/gems/gems/rbtrace-0.4.14/ext/rbtrace.c:960:in `rbtrace__process_event'
    from /home/eregon/code/truffleruby-ws/truffleruby/mxbuild/truffleruby-jvm/languages/ruby/lib/gems/gems/rbtrace-0.4.14/ext/rbtrace.c:1080:in `rbtrace__receive'
    from /home/eregon/code/truffleruby-ws/truffleruby/mxbuild/truffleruby-jvm/languages/ruby/lib/gems/gems/rbtrace-0.4.14/ext/rbtrace.c:1119:in `signal_handler_wrapper'
    from /home/eregon/code/truffleruby-ws/truffleruby/mxbuild/truffleruby-jvm/languages/ruby/lib/truffle/truffle/cext.rb:948:in `block in rb_proc_new'
    from server.rb:18:in `sleep'
    from server.rb:18:in `block (2 levels) in <main>'
    from <internal:core> core/dir.rb:302:in `chdir'
    from server.rb:14:in `block in <main>'
    from server.rb:13:in `call'
    from server.rb:13:in `<main>'

and

rbtrace -p 107645 -m sleep
*** run `sudo sysctl kernel.msgmnb=1048576` to prevent losing events (currently: 16384 bytes)
*** attached to process 107645
<internal:core> core/type.rb:291:in `convert_type': no implicit conversion of nil into String (TypeError)
    from <internal:core> core/type.rb:271:in `rb_convert_type'
    from <internal:core> core/kernel.rb:171:in `StringValue'
    from <internal:core> core/exception.rb:401:in `new'
    from <internal:core> core/truffle/exception_operations.rb:20:in `build_exception_for_raise'
    from <internal:core> core/kernel.rb:691:in `raise'
    from /home/eregon/code/truffleruby-ws/truffleruby/mxbuild/truffleruby-jvm/languages/ruby/lib/gems/gems/rbtrace-0.4.14/lib/rbtrace/core_ext.rb:15:in `raise'
    from /home/eregon/code/truffleruby-ws/truffleruby/mxbuild/truffleruby-jvm/languages/ruby/lib/gems/gems/rbtrace-0.4.14/lib/rbtrace/msgq.rb:20:in `send_cmd'
    from /home/eregon/code/truffleruby-ws/truffleruby/mxbuild/truffleruby-jvm/languages/ruby/lib/gems/gems/rbtrace-0.4.14/lib/rbtrace/rbtracer.rb:327:in `send_cmd'
    from /home/eregon/code/truffleruby-ws/truffleruby/mxbuild/truffleruby-jvm/languages/ruby/lib/gems/gems/rbtrace-0.4.14/lib/rbtrace/rbtracer.rb:223:in `detach'
    from /home/eregon/code/truffleruby-ws/truffleruby/mxbuild/truffleruby-jvm/languages/ruby/lib/gems/gems/rbtrace-0.4.14/lib/rbtrace/cli.rb:552:in `run'
    from /home/eregon/code/truffleruby-ws/truffleruby/mxbuild/truffleruby-jvm/languages/ruby/lib/gems/gems/rbtrace-0.4.14/bin/rbtrace:5:in `<top (required)>'
    from <internal:core> core/kernel.rb:400:in `load'
    from <internal:core> core/kernel.rb:400:in `load'
    from /home/eregon/.rubies/truffleruby-jvm/bin/rbtrace:23:in `<main>'

i.e., TruffleRuby doesn't support rb_add_event_hook() yet, but the LLVMLinkerException is solved.

rb_add_event_hook() used in https://github.com/tmm1/rbtrace/blob/73f8bb563f2926c02aabd3b630bee0c4d9060421/ext/rbtrace.c#L532-L539

eregon commented 3 years ago

Even if we implement rb_add_event_hook(), I don't think rb_trace would be useful on TruffleRuby, since it calls this C function on every Ruby method call and return, which seems expensive and also in_event_hook assumes there is a global lock, which there isn't for Ruby code in TruffleRuby.

I'll close this because I don't think rb_trace can be really useful on TruffleRuby given the large overhead it would have. The functionality itself could be provided by guest safepoints which much lower overhead. There is already SIGALRM to dump Ruby backtraces of all threads, see https://github.com/oracle/truffleruby/blob/master/doc/user/debugging.md#printing-stacktraces-and-backtraces-of-a-running-process