I'd like to achieve the following:
Build a Ruby command line utility that registers some set_trace_func events, then invokes whatever ruby-executable argument you pass to it (say rspec
). The registered events then carry over to the command invoked.
Pseudo code of myutility
:
set_trace_func() # Set some events here
exec(ARGV.join(' ')) # Execute argument passed
Then call as myutility rspec
.
My objective here is to actually register trace points on arbitrary commands (as long as they are using ruby shims).
Things I have tried:
exec
Does not work, for obvious reasons (it replaces the process entirely). I can use some form of IPC, but that assumes control over the command I am invoking with my utility. This is not the case; I'd like to accept arbitrary Ruby-executable arguments.
Is this possible? One thing I have not looked at closely is drb, but that too assumes some interference with outside arguments.
You can inject some code into ruby process by adding arguments to ruby interpreter, so your utility can be split in two parts - runner and payload. Payload is just another script, it registers for set_trace_func
etc. upon require, and runner inject the former into target script like so:
exec('/usr/bin/env', 'ruby', '-r', payload_full_filename, *ARGV)
This will make ruby to require
your payload into process first and then proceed with running target script itself (payload will run even if target script cannot compile)