Debugging Ruby 1.9.3 applications in Eclipse

September 3, 2012

Debugging Ruby code in Eclipse should be easy. After all, there is Aptana Studio which integrates the Ruby debugger, and RVM to manage the Ruby installations. Or so I thought. The problem is that I cannot work without a debugger. Using print statements to trace program flow makes me loose hair, and trial-and-error F5ing in  the web browser can hardly be called systematic solving of a programming problem. So I had to make it work. After several hours of setup and configuration, running into the next problem, searching the web again, retrying, and consuming caffeine overdoses in the process, debugging eventually  worked. To save those trying after me from running into the same trouble, the steps that finally succeeded are documented below. The following instructions have been verified on Ubuntu 12.04 32bit.

Set up Ruby 1.9.3 using RVM

To prepare Ruby to be installed (and compiled) locally, it is important to diligently walk through the steps rvm itself lists, especially about platform packages that need to be installed. Building gems sometimes fails without helpful diagnostics if required packages are missing:

$ >rvm requirements
... (read this!)
$ >/usr/bin/apt-get install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion pkg-config

Installing Ruby itself using RVM is indeed simple enough, and a pleasant experience:

$ >curl -L https://get.rvm.io | bash -s stable --ruby
$ >source ~/.rvm/scripts/rvm
$ >rvm install 1.9.3

The trouble starts in the next step. To be able to debug Ruby applications from within IDEs, three gems are required, namely ruby-debug-base, ruby-debug and ruby-debug-ide (do not install them just yet, the first two are f00bared). The problem with these is that for quite a while now, there is a known bug with ruby-debug that prevents it from loading because of a missing symbol “ruby_current_thread“:

$ >irb
1.9.3p194 :001> require 'ruby-debug'
.../lib/ruby_debug.so: undefined symbol: ruby_current_thread - ...
$ >

There are lots of discussions on the web about how to solve this. The only solution that actually worked for me was this one: There is a fork of ruby-debug simply called debugger, that replaces ruby-debug-base and ruby-debug (but not ruby-debug-ide). It is part of the Gem collection by now, so install it and ruby-debug-ide as gems:

$ >rvm pkg install zlib
$ >gem install debugger
$ >gem install ruby-debug-ide

After installing these, ruby-debug can be loaded in scripts:

$ >irb
1.9.3p194 :001 > require 'ruby-debug'
> true
1.9.3p194 :002 >

Setting up Eclipse and Aptana Radrails

Installing a working JDK

I had to install a working Oracle JDK since the OpenJDK shipped with Ubuntu kept crashing with Eclipse. Instructions on how to install the Oracle JDK can be found <a title=“Oracle JDK installation instructions” here.

Developing and debugging Ruby in Eclipse

Eclipse can be downloaded from http://www.eclipse.org. It has been said many times, but repeating it does not hurt – download Eclipse and install it locally for your user account. Do not use the distro packages of Eclipse.

Unpack the Eclipse tarball to a directory that is writable for the current user. Then install Aptana RadRails as described here.

Fixing the debugger

But the woes are not over yet. Basic debugging works, but as soon as any more complex statements are executed, Eclipse reports the following error:

Exception in DebugThread loop: undefined method `is_binary_data?' for "#":String

Oh boy. Some more web searching reveals that the cuplrit is the is_binary_data? method of the string class that has been deprecated after Ruby 1.9.1. but is still used in the debugger module. Stackoverflow has the fix for that one: Edit ruby-debug/xml_printer.rb, and add the following code at the very end, after the end of the module Debugger block:

class String
  def is_binary_data?
    ( self.count( "^ -~", "^rn" ).fdiv(self.size) > 0.3 || self.index( "x00" ) ) unless empty?
  end
end

I found the file at _$HOME/.rvm/gems/ruby-1.9.3-p194/gems/ruby-debug-ide-0.4.16/lib/ruby-debug/xmlprinter.rb.

Summary

After setting up Ruby using RVM, selecting the correct (the working) debugger gem, after fixing the missing method in the debugger code and after fiddling to install a working JRE, debugging Ruby code finally works from within the Eclipse IDE. Since other IDEs use the ruby-debug-ide gem as well, this HOWTO should partly be applicable to those too. After it turned out to be so time consuming to get this all to work, one cannot but wonder if Ruby developers are actually debugging their code? 🙂

Image credit: Yuko Honda, Ruby latte, license