This is very cool.
Just one observation: when running over DRb, you have to be very careful not
to type anything in the session which causes another breakpoint to trigger,
as it seems to get rather confused.
For example, in your Person example, at the second breakpoint typing 'name'
instead of '@name' causes a nested breakpoint call. This works just fine for
a directly-connected session:
$ ruby test.rb
Executing break point "Person#initialize" at test.rb:7 in `initialize'
irb(#<Person:0x8130f5c>):001:0> exit
Executing break point "Person#name" at test.rb:13 in `name'
irb(#<Person:0x8130f5c>):001:0> @name
=> "Random Person"
irb(#<Person:0x8130f5c>):002:0> name
Executing break point "Person#name" at test.rb:13 in `name'
irb(#<Person:0x8130f5c>):001:0> name
Executing break point "Person#name" at test.rb:13 in `name'
irb(#<Person:0x8130f5c>):001:0> exit
=> "Random Person"
irb(#<Person:0x8130f5c>):002:0> exit
=> "Random Person"
irb(#<Person:0x8130f5c>):003:0> exit
Name: Random Person
But not over DRb (it hangs at the nested breakpoint). Interestingly, I even
managed to make Ruby dump core in the program which was under test. Gory
details below.
I wonder if a 'console' model would work better; that is, run a private IRB
session in the object under test, and then just connect its input/output
stream? The debug session could accept a telnet connection, or communicate
over a socket or a pair of named pipes.
Also, if it could display +/-5 lines of source code context, that would be
very pleasant. But perhaps then it's getting too close to an IDE 
Regards,
Brian.
[brian@vaio lib]$ ruby test.rb &
[1] 71708
[brian@vaio lib]$ ruby breakpoint-client.rb
Executing break point "Person#initialize" at test.rb:7 in `initialize'
irb(#<DRb::DRbUnknown:0x8110728>):001:0> exit
Executing break point "Person#name" at test.rb:13 in `name'
irb(#<DRb::DRbUnknown:0x82e93e8>):001:0> @name
=> "Random Person"
irb(#<Person:0x8130c8c>):002:0> name
<< nothing happens here until I press ctrl-C >>
^CIRB::Abort: abort then interrupt!!
from /usr/local/lib/ruby/1.8/irb.rb:81:in `load'
from /usr/local/lib/ruby/1.8/drb/drb.rb:611:in `recv_reply'
from /usr/local/lib/ruby/1.8/drb/drb.rb:865:in `recv_reply'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1104:in `send_message'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1015:in `method_missing'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1014:in `open'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1014:in `method_missing'
from /usr/local/lib/ruby/1.8/irb/context.rb:198:in `old_evaluate'
from ./breakpoint.rb:239:in `evaluate'
from /usr/local/lib/ruby/1.8/irb.rb:148:in `eval_input'
from /usr/local/lib/ruby/1.8/irb.rb:145:in `signal_status'
from /usr/local/lib/ruby/1.8/irb.rb:145:in `eval_input'
from /usr/local/lib/ruby/1.8/irb.rb:144:in `each_top_level_statement'
from /usr/local/lib/ruby/1.8/irb/ruby-lex.rb:220:in `loop'
from /usr/local/lib/ruby/1.8/irb/ruby-lex.rb:220:in `each_top_level_statement'
from /usr/local/lib/ruby/1.8/irb/ruby-lex.rb:219:in `catch'
... 6 levels...
from breakpoint-client.rb:22:in `call'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1434:in `__send__'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1434:in `perform_without_block'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1395:in `perform'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1468:in `main_loop'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1464:in `loop'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1464:in `main_loop'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1460:in `start'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1460:in `main_loop'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1327:in `run'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1324:in `start'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1324:in `run'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1249:in `initialize'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1505:in `new'
from /usr/local/lib/ruby/1.8/drb/drb.rb:1505:in `start_service'
from breakpoint-client.rb:16irb(#<Person:0x8130c8c>):003:0> @name
=> "Random Person"
irb(#<Person:0x8130c8c>):004:0> Name: Random Person
./breakpoint.rb:148: [BUG] Segmentation fault
ruby 1.8.2 (2004-07-29) [i386-freebsd4]
No connection to breakpoint service at druby://localhost:42531:
(connection closed)
Reconnecting in 10 seconds...
^C
<< no response to ^C so I had to do ^Z >>
^Z[1] Abort trap (core dumped) ruby test.rb
[2]+ Stopped ruby breakpoint-client.rb
[brian@vaio lib]$ kill %2
[2]+ Terminated ruby breakpoint-client.rb
[brian@vaio lib]$ jobs
[brian@vaio lib]$ gdb -c ruby.core ruby
GNU gdb 4.18 (FreeBSD)
Copyright 1998 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 "i386-unknown-freebsd"...
(no debugging symbols found)...
Core was generated by `ruby'.
Program terminated with signal 6, Abort trap.
Reading symbols from /usr/local/lib/libruby18.so.18...
(no debugging symbols found)...done.
Reading symbols from /usr/lib/libcrypt.so.2...(no debugging symbols found)...
done.
Reading symbols from /usr/lib/libm.so.2...(no debugging symbols found)...done.
Reading symbols from /usr/lib/libc.so.4...(no debugging symbols found)...done.
Reading symbols from /usr/local/lib/ruby/1.8/i386-freebsd4/readline.so...
(no debugging symbols found)...done.
Reading symbols from /usr/lib/libreadline.so.4...
(no debugging symbols found)...done.
Reading symbols from /usr/lib/libncurses.so.5...(no debugging symbols found)...
done.
Reading symbols from /usr/local/lib/ruby/1.8/i386-freebsd4/socket.so...
(no debugging symbols found)...done.
Reading symbols from /usr/local/lib/ruby/1.8/i386-freebsd4/fcntl.so...
(no debugging symbols found)...done.
Reading symbols from /usr/libexec/ld-elf.so.1...(no debugging symbols found)...
done.
#0 0x28190084 in kill () from /usr/lib/libc.so.4
(gdb) bt
#0 0x28190084 in kill () from /usr/lib/libc.so.4
#1 0x281d197a in abort () from /usr/lib/libc.so.4
#2 0x280827d1 in rb_bug () from /usr/local/lib/libruby18.so.18
#3 0x280e6e82 in sigsegv () from /usr/local/lib/libruby18.so.18
#4 0xbfbfffac in ?? ()
#5 0x2809127f in eval () from /usr/local/lib/libruby18.so.18
#6 0x2809166e in rb_f_eval () from /usr/local/lib/libruby18.so.18
#7 0x2808fb22 in rb_call0 () from /usr/local/lib/libruby18.so.18
#8 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#9 0x2808abd4 in rb_eval () from /usr/local/lib/libruby18.so.18
#10 0x2809015a in rb_call0 () from /usr/local/lib/libruby18.so.18
#11 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#12 0x2808abd4 in rb_eval () from /usr/local/lib/libruby18.so.18
#13 0x2808b54e in rb_eval () from /usr/local/lib/libruby18.so.18
#14 0x2809015a in rb_call0 () from /usr/local/lib/libruby18.so.18
#15 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#16 0x28090778 in rb_f_send () from /usr/local/lib/libruby18.so.18
#17 0x2808fb22 in rb_call0 () from /usr/local/lib/libruby18.so.18
#18 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#19 0x2808a9af in rb_eval () from /usr/local/lib/libruby18.so.18
#20 0x2809015a in rb_call0 () from /usr/local/lib/libruby18.so.18
#21 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#22 0x2808ac4c in rb_eval () from /usr/local/lib/libruby18.so.18
#23 0x2808b60e in rb_eval () from /usr/local/lib/libruby18.so.18
#24 0x28089fd6 in rb_eval () from /usr/local/lib/libruby18.so.18
#25 0x2809015a in rb_call0 () from /usr/local/lib/libruby18.so.18
#26 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#27 0x2808a9af in rb_eval () from /usr/local/lib/libruby18.so.18
#28 0x28089de1 in rb_eval () from /usr/local/lib/libruby18.so.18
---Type <return> to continue, or q <return> to quit---
#29 0x2808b504 in rb_eval () from /usr/local/lib/libruby18.so.18
#30 0x2808a11c in rb_eval () from /usr/local/lib/libruby18.so.18
#31 0x2808dceb in rb_yield_0 () from /usr/local/lib/libruby18.so.18
#32 0x2808e11e in rb_f_loop () from /usr/local/lib/libruby18.so.18
#33 0x2808fb51 in rb_call0 () from /usr/local/lib/libruby18.so.18
#34 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#35 0x2808abd4 in rb_eval () from /usr/local/lib/libruby18.so.18
#36 0x28089a8a in rb_eval () from /usr/local/lib/libruby18.so.18
#37 0x2808dceb in rb_yield_0 () from /usr/local/lib/libruby18.so.18
#38 0x2809a129 in rb_thread_yield () from /usr/local/lib/libruby18.so.18
#39 0x28099e47 in rb_thread_start_0 () from /usr/local/lib/libruby18.so.18
#40 0x2809a252 in rb_thread_start () from /usr/local/lib/libruby18.so.18
#41 0x2808fb22 in rb_call0 () from /usr/local/lib/libruby18.so.18
#42 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#43 0x2808a9af in rb_eval () from /usr/local/lib/libruby18.so.18
#44 0x28089a8a in rb_eval () from /usr/local/lib/libruby18.so.18
#45 0x2809015a in rb_call0 () from /usr/local/lib/libruby18.so.18
#46 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#47 0x2808ac4c in rb_eval () from /usr/local/lib/libruby18.so.18
#48 0x28089666 in rb_eval () from /usr/local/lib/libruby18.so.18
#49 0x2808a11c in rb_eval () from /usr/local/lib/libruby18.so.18
#50 0x2808dceb in rb_yield_0 () from /usr/local/lib/libruby18.so.18
#51 0x2809a129 in rb_thread_yield () from /usr/local/lib/libruby18.so.18
#52 0x28099e47 in rb_thread_start_0 () from /usr/local/lib/libruby18.so.18
#53 0x2809a252 in rb_thread_start () from /usr/local/lib/libruby18.so.18
#54 0x2808fb22 in rb_call0 () from /usr/local/lib/libruby18.so.18
#55 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#56 0x2808a9af in rb_eval () from /usr/local/lib/libruby18.so.18
#57 0x28089a8a in rb_eval () from /usr/local/lib/libruby18.so.18
---Type <return> to continue, or q <return> to quit---
#58 0x2809015a in rb_call0 () from /usr/local/lib/libruby18.so.18
#59 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#60 0x2808ac4c in rb_eval () from /usr/local/lib/libruby18.so.18
#61 0x2808b60e in rb_eval () from /usr/local/lib/libruby18.so.18
#62 0x2809015a in rb_call0 () from /usr/local/lib/libruby18.so.18
#63 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#64 0x280908d5 in rb_funcall2 () from /usr/local/lib/libruby18.so.18
#65 0x2809309c in rb_obj_call_init () from /usr/local/lib/libruby18.so.18
#66 0x280b850b in rb_class_new_instance () from /usr/local/lib/libruby18.so.18
#67 0x2808fb22 in rb_call0 () from /usr/local/lib/libruby18.so.18
#68 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#69 0x2808a9af in rb_eval () from /usr/local/lib/libruby18.so.18
#70 0x2808b60e in rb_eval () from /usr/local/lib/libruby18.so.18
#71 0x2809015a in rb_call0 () from /usr/local/lib/libruby18.so.18
#72 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#73 0x2808a9af in rb_eval () from /usr/local/lib/libruby18.so.18
#74 0x2809015a in rb_call0 () from /usr/local/lib/libruby18.so.18
#75 0x280905e4 in rb_call () from /usr/local/lib/libruby18.so.18
#76 0x2808a9af in rb_eval () from /usr/local/lib/libruby18.so.18
#77 0x28086168 in eval_node () from /usr/local/lib/libruby18.so.18
#78 0x280866fe in ruby_exec () from /usr/local/lib/libruby18.so.18
#79 0x28086771 in ruby_run () from /usr/local/lib/libruby18.so.18
#80 0x80485df in main ()
#81 0x8048516 in _start ()
(gdb)