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.
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.
ReplyDelete