Ruby Weekly is a weekly newsletter covering the latest Ruby and Rails news.

Hijack: Get A Live IRB Prompt For Any Existing Ruby Process

By Ari Brown / August 21, 2009

jackSometimes taking an app down for debugging purposes is just not an option. Luckily a new tool called Hijack can provide a live IRB prompt for an existing Ruby process in the same way that Erlang provides hot swapping of code (changing the definition of a system while the system is still up and running).

Hijack (it's still in a beta state, so be careful and don't use it in production yet!) lets you to pry your way into a running Ruby process, where it drops you into a live IRB session running over DRB. Gone are the days of stopping live applications just to make a minor update!

Using the GDB (GNU DeBugger), Hijack connects to the running Ruby process, injecting a small payload to start a DRB session which provides an IRB session:

$ ruby hijack 16451
        => Hijacking...
        => Mirroring: 100%
        => Hijacked 16451 (my_script.rb) (ruby 1.8.7 [i686-darwin9])
        >>

You may already be familiar with live-console which provides a similar functionality. The key difference, however, is that Hijack can "inject" itself into an existing Ruby process without needing the code to have included it explicitly. Developer Ian Leitch explains:

I've just changed Hijack so that you can hijack any Ruby process - no need for your target process to require any code before it can be hijacked. It does this by first injecting a payload using gdb, then it signals the process to start up a DRb server which the hijack client then connects to.

jslab.pngJumpstart Lab is running a JavaScript Master Class for Javascript & UI programmers with Thomas Fuchs (Scriptaculous, Prototype Core) and Amy Hoy (UI Expert) on 9/12 in Washington, DC. Save 10% with code "rubyinside"!

Comments

  1. Chris says:

    I don't understand the Erlang analogy, but there's a similar thing available for Cocoa by way of NuAnywhere: http://programming.nu/nuanywhere

  2. Bradly Feeley says:

    this is some slick willy!

  3. Sho says:

    Looks cool, but might help if the lib directory was included in the gem .. ; )

  4. Ian Leitch says:

    Sorry about that, gem should be fixed now :)

  5. Senthil says:

    That would be real cool, will check it out.

    can somebody post some tricks which they have tried with it

  6. Guoliang Cao says:

    I was trying to hijack our rails process and it got stuck after 'Hijacking...'

    Any idea?

    OSX 10.5.7
    ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin9]
    Rails 2.3.2

  7. Ian Leitch says:

    Was the process started with 'script/server'? If so it's a known bug. Use mongrel_rails start or thin start instead.

  8. awwaiid says:

    Fancy! We got that in perl doing similar things, http://search.cpan.org/~whitepage/Enbugger-2.009/lib/Enbugger.pod

  9. Josh Jore says:

    I wrote a similar thing for Perl awhile ago (and recently blogged http://use.perl.org/~jjore/journal/39325). The thing I never finished off was dealing with the fact the gdb has attached at an arbitrary instruction and not at a safe time. I spent a short bit of time trying to inform perl that a "signal" had arrived and to wait for the sighandler to run and use that as a break point. That'd get me back to safe signal handling and therefore a perfectly safe time to go launch the debugger.

    I'd set the global PL_sig_pending to true, then break on Perl_despatch_signals and try to convince Perl it was ok that there was no actual signal to handle. Didn't quite work.

    I suspect you've got the same problem here in Ruby. You should probably "set variable rb_trap_pending = 1" and break on rb_trap_exec or something like that.

  10. Guoliang Cao says:

    Thanks for looking.

    Yes, it was started with script/server.

    Now I can get it hijacked after running as 'mongrel_rails start'

  11. j_king says:

    Yet another Lisp feature re-implemented in a young programming language.

    They grow up so fast! ;)

    Really cool stuff though. The next step is to provide a SWANK-like server for running processes. Then you can connect irb to remote processes! Yet another thing Lisp already has.

    Great work though. Really pushing the boundaries.

Other Posts to Enjoy

Twitter Mentions