Monday, April 03, 2006

Workin' in the coal mine

Sometimes, it doesn't look like there's anything as dark and forbidding as a coal mine, unless it's the inside of Ruby's C implementation. Recently, Sean Carley and I have been poking around in there while we work on checkr. Fortunately, zenspider and Eric Hodel have been a wonderful pair of guides for us. We started working with case statements, and we quickly ran into big problems. It turns out that parse_tree doesn't deal well with things like
case;
when foo == 1; puts "it was one"
when foo == 2; puts "it was two"
end
Digging into it has meant grabbing gdb, gprof, and looking at lots of parse_tree output. It's turned Sean into another fan of unit_diff. It's also given me a chance to figure out a lot more about C than I thought possible in such a short time. Who would have thought that this would have been part of troubleshooting a Ruby issue:

$ gdb ~/ruby-debug/bin/ruby
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, 
and you are welcome to change it and/or distribute copies of it 
under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" 
for details.
This GDB was configured as "i586-suse-linux"...Using host libthread_db/library/lib/tls/libthread_db.so.1".

(gdb) set args 'good_case.rb'

(gdb) b eval.c :2949
Breakpoint 1 at 0x8056ea2: file eval.c, line 2949.

(gdb) run
Starting program: /home/eylerpm/ruby-debug/bin/ruby 'good_case.rb'
1

Program exited normally.

(gdb) set args 'case.rb'
(gdb) run
Starting program: /home/eylerpm/ruby-debug/bin/ruby 'case.rb'

Breakpoint 1, rb_eval (self=1075685744, n=0x401cb024) at eval.c:2949
2949            while (node) {

(gdb) c
Continuing.

Breakpoint 1, rb_eval (self=1075685744, n=0x401cb024) at eval.c:2949
2949            while (node) {

(gdb) c
Continuing.

Breakpoint 1, rb_eval (self=1075685744, n=0x401cb024) at eval.c:2949
2949            while (node) {

(gdb) c
Continuing.
nothing matched

Program exited normally.

(gdb)
But it turned out to be just the key Sean and zenspider needed to track down the issue in parse_tree.

1 comment:

Sean said...

You aren't kidding, Pat. That debugging session is the proof I needed that in eval.c different pieces of code were handling the "case val;when" and the "case;when" situations.