dcsimg

Hijack: Living on the Edge of (Ruby and) Rails, Part 4

Hijack can debug most any running Ruby process. Here's a hands-on introduction.

The previous three installments of this series looked at new features in Edge Rails and other very recent releases of the popular Web development framework. Tomorrow’s installment looks at some next-generation gems and next week’s regular column looks at nested forms, an addition sure to please every Rails developer, from newbie to master.

Today’s installment is something of a spur, because I had intended to write about a different topic. However, today’s topic is very clever, certainly on the edge—a first alpha—and useful nonetheless.

Debug Anything with Hijack

I’m a big fan of irb and the Ruby debugger, and use both to explore code and find and fix bugs in Ruby and Rails projects. For a Ruby script, install the ruby-debug gem and then invoke the script with the debugger, rdebug.

$ sudo gem install ruby-debug
Successfully installed ruby-debug-0.10.3
1 gem installed
Installing ri documentation for ruby-debug-0.10.3...
Installing RDoc documentation for ruby-debug-0.10.3...
$ which rdebug
/usr/bin/rdebug
$ rdebug some_script.rb

It’s also very easy to debug a Rails application: Sprinkle the statement…

debugger

… liberally throughout your code and invoke the server with…

$ ./script/server --debugger

Whenever your Rails application hits a debugger statement, ZAP!, the application suspends, presenting a prompt where you can poke and prod variables, instances, and classes, and step through statements. After you address the defect, either remove the debugger statements or omit the --debugger option. In the latter case, debugger statements are simply ignored (although the server reminds you of that with some vociferousness.)

Real world scenarios tend to be a little more challening. What happens when a bug appears after a certain period or occurs only intermittently? Short of divine intervention, your logs, the application database, and anecdotal evidence may be your only clues to the culprit.

But like Prometheus, who stole fire from Zeus and returned it to man, developer Ian Leitch has granted we mere mortals a little bit of omniscience. Leitch’s Hijack can attach to almost any running Ruby process, interrupt its execution, and let your peer in as if you were truly all-powerful. You can swap in code on-the-fly, too, to add a debugger call wherever you need it.

Hijack works with common scripts and can attach to the Mongrel daemon and Thin, too. However, it does not yet work with the Mongrel script (./script/server) included with every Rails project, nor with the Rails script runner. Leitch has plans to address these shortcomings in the near future. As he said in an email to me, “Hijack was little more than an experiment up until a few days ago when someone mentioned it on Twitter.”

As a demonstration, let’s attach to a small Rails application and use the available techniques to usurp execution and debug the code. The test machine is a MacBook running Mac OS X Leopard, Edge Rails, and the GNU Debugger, Apple version gdb-966.

Using Hijack with Debugger Statements

Using Hijack is simple. First, install it. Hijack adds a gem and a command-line utility called hijack.

$ gem sources -a http://gems.github.com
$ sudo gem install ileitch-hijack
$ which hijack
/usr/bin/hijack

For this initial example, I’ve left a breakpoint in one of my Rails validators. Typically, mongrel_rails ignores such a statement. However, once I hijack the process, the application goes into limbo when it meanders across line 1.

def validate_novelty
  debugger

  self.errors.add_to_base( 'This location is already defined' ) unless Location.
  find(:first, :conditions =>
    { :group_id => group.id, :room => room, :aisle => aisle, :bin => bin } ).nil?
end

To continue, install the ruby-debug gem (if you do not yet have it) and launch your application with mongrel_rails start.

$ sudo gem install ruby-debug
$ cd ~/Projects/warehouse
$ mongrel_rails start
** Starting Mongrel listening at 0.0.0.0:3000
** Starting Rails with development environment...
** Rails loaded.
** Loading any Rails specific GemPlugins
** Signals ready.  TERM => stop.  USR2 => restart.  INT => stop (no restart).
** Rails signals registered.  HUP => reload (without restart).  It might not work well.
** Mongrel 1.1.5 available at 0.0.0.0:3000
** Use CTRL-C to stop.

Next, attach to the Mongrel process. Use ps or jobs to find its process ID and invoke Hijack.

$ ps ux | grep Mongrel
7563 s003  S+     0:04.37 /System/Library/Frameworks/Ruby.framework/
  Versions/1.8/usr/bin/ruby /usr/bin/mongrel_rails start
$ hijack 7563
=> Hijacked 7563 (/usr/bin/mongrel_rails) (ruby 1.8.6 [universal-darwin9.0])
>>

When the Hijack prompt appears, type two commands: hijack_debug_mode followed by hijack_debug_start. (I omitted the former several times in preparing this post, with unpredictable results.)

>> hijack_debug_mode
=> true
>> hijack_debug_start
Connected.

According to Leitch, the two commands break the hijacking process into two steps intentionally. The first command, hijack_debug_mode, requires ruby-debug and then stops by design so you can insert your breakpoint(s). The next command, hijack_debug_start, connects hijack to the application. (Specifically, hijack connects to a remote debugger which proxies for the application.) debugger calls fire only when the application is connected.

At this point, you are connected and ready to debug. Whenever the application hits the breakpoint, Hijack drops to the debugger. Examine variables and look at backtraces as needed; when finished type continue to resume normal processing.

Connected.
(rdb:20) p self
#<Location id: nil, group_id: 1, room: "sds", aisle: "dsds", bin: "dsdsd", created_at: nil, updated_at: nil>
(rdb:20) continue

Under the hood, Hijack uses the GNU Debugger, or gdb, to inject code that starts a Distributed Ruby (DRb) server. Once DRb is up and running, gdb is no longer needed and Hijack communicates directly with DRb. You must run Hijack on the same machine as the process being scrutinized; you must also run Hijack as the same user as the target process. Both limitations protect your processes from, well, being hijacked for nefarious purposes.

Hijack Running Code

In addition to affecting the execution of a running process, you can also change its code on-the-fly. You can replace both class methods and instance methods.

To replace code, start your server and hijack and type hijack_debug_mode. At the prompt, enter any code you want to “inject”. The general template to replace a class method is:

Klass.class_eval do
  class << self
    def some_class_method
      ...
      debugger
      ...
    end
  end
end

class_eval evaluates the block within the context of the named class, here Klass. The meta-class class << self affects the class methods for Klass. Hence, you can override any class method simply be redefining it. Leitch provides this example.

Start your Rails application and start Hijack. Type hijack_debug_mode and then paste the following code at the prompt.

ActionController::Dispatcher.class_eval do
  class << self
    def dispatch_with_debugger(cgi, session_options, output)
      debugger
      dispatch_without_debugger(cgi, session_options, output)
    end

    alias_method :dispatch_without_debugger, :dispatch
    alias_method :dispatch, :dispatch_with_debugger
  end
end

Now, if you point your browser to the application, it suspends execution within the dispatch method, which is a reasonable starting point to debug most anything.

The general template to replace instance methods looks like this:

Qlass.class_eval do
  def some_instance_method
    ...
    debugger
    ...
  end
end

Returning to my first example, if debugger wasn't already present, I could inject what I wanted with Hijack.

$ hijack 9377
=> Hijacked 9377 (/usr/bin/mongrel_rails) (ruby 1.8.6 [universal-darwin9.0])
>> hijack_debug_mode
=> true
>> Location.class_eval do
?>   def validate_novelty
>>     debugger
>>
?>     self.errors.add_to_base( 'This location is already defined' ) unless Location.
?>       find(:first, :conditions => { :group_id => group.id, :room => room, :aisle => aisle, :bin => bin } ).nil?
>>   end
>> end
=> nil
>> hijack_debug_start
Connected.

When I use the application to subsequently invoke the validator validate_novelty, Hijack drops to the debugger prompt.

(rdb:8)

Grand Theft Ruby

Hijack is in a nascent stage, but already has proven to be a very valuable tool. Expect lots of new features in the next release: pulling people from cars, shooting at cops, and outrunning John Law. Just kidding. This isn't Grand Theft Ruby. Still, the name is catchy.

My thanks to Ian Leitch for midnight tech support.

Happy tinkering.

Comments on "Hijack: Living on the Edge of (Ruby and) Rails, Part 4"

Shop for NBA jerseys at the official NBA Store! We carry the widest variety of golden state warriors jerseys, and youth sizes. Keep checking back for the arrivals of the NBA Nike Jersey!
nba jerseys cheap

Hijack: Living on the Edge of (Ruby and) Rails, Part 4 | Linux Magazine

Paragraph writing is also a fun, if you be familiar with afterward you
can write if not it is complex to write.

I relish, result in I discovered just what I used to be looking for.
You’ve ended my 4 day lengthy hunt! God Bless you man.
Have a nice day. Bye

The second greatest weighing 317.four carats and is named Cullinon II and is ready on the middle of Great Britain’s Imperial
State Crown.

Feel free to surf to my website Jewellery website

British vintage jewellery which is manufactured from 15 carat gold might be hallmarked with the number 15 and.625.

My homepage; Joma Jewellery UK; Zoe,

1Hnku4 coxsoagxranq, [url=http://rurzahlyvtjf.com/]rurzahlyvtjf[/url], [link=http://wmhnyivdeswt.com/]wmhnyivdeswt[/link], http://uzsgiojzweeq.com/

People in each teams mentioned they suffered less pain.
There was no difference between those that had been truly
sporting ionized bracelets and those who were not.

Here is my blog post: Hot Tomato tote (Gena)

In addition, as the vendor you’re accountable for the prices related to promoting your jewelry, such as advertising images
and a fee, and these will scale back your profit.
Bonhams andamp; Butterfields will take lower value items to checklist in their
auction catalogues.

Here is my web page :: Sence jewellery Copenhagen; Sylvia,

You may have one of the largest jewelry collections of all your folks, however for those who can’t find the piece you need within 10 seconds, you’ll probably skip the accessories that day and just go together with your normal baubles.

my weblog … Hultquist Jewellery Collection Autumn Winter 2015 (Nola)

Though, to profit from the best deals you need do inclusive do
research of online market. Start by calling dealerships and
asking the finance director if they use a traditional FICO credit
score to make their lending decision or if they use the FICO Auto Industry Option score.
In previous years getting car loan was rough and hectic but it is
not the case these days.

Also visit my weblog :: cash car loans (Shay)

One of our guests not long ago advised the following website.

We prefer to honor numerous other world wide web websites on the web, even when they aren?t linked to us, by linking to them. Underneath are some webpages really worth checking out.

I simply want to tell you that I am just all new to weblog and really enjoyed your blog site. Most likely I’m going to bookmark your blog . You actually have terrific stories. With thanks for sharing your blog.

Excellent way of describing, and pleasant post to take information concerning my presentation subject
matter, which i am going to convey in institution of
higher education.

Feel free to surf to my web blog: sell bulk auto paper feeder

Hi there would you mind letting me know which hosting company you’re using?
I’ve loaded your blog in 3 different browsers and I must say this blog loads a lot quicker then most.
Can you suggest a good internet hosting provider at a fair
price? Kudos, I appreciate it!

While this may not be the best time to apply for a car loan because
of your credit, you can make the most out of the situation by using your bad credit car loan to
improve your credit score. While searching for the
most reliable online subprime loans for buying cars, check the rate of interest
before finalizing the deal. Many people don’t realize how much the
interest on a loan adds up.

Review my web-site; used car loans interest rates (Rochelle)

Hey! I just wanted to ask if you ever have any trouble with hackers?
My last blog (wordpress) was hacked and I ended up losing months of hard work due to no backup.
Do you have any solutions to prevent hackers?

Every after inside a whilst we opt for blogs that we read. Listed below would be the most up-to-date websites that we select.

Every when in a while we decide on blogs that we study. Listed below would be the latest web sites that we pick out.

Usually posts some extremely interesting stuff like this. If you are new to this site.

Sites of interest we’ve a link to.

Leave a Reply