├── test ├── data │ ├── quit.right │ ├── dollar-0.right │ ├── dollar-0a.right │ ├── dollar-0b.right │ ├── info-var-bug2.cmd │ ├── noquit.right │ ├── break_loop_bug.cmd │ ├── history.right │ ├── source.cmd │ ├── test-init-osx.right │ ├── test-init.right │ ├── output.cmd │ ├── quit.cmd │ ├── info-var-bug2.right │ ├── linetrace.cmd │ ├── pm-bug.cmd │ ├── test-init-cygwin.right │ ├── post-mortem-next.cmd │ ├── catch3.cmd │ ├── method.cmd │ ├── methodsig.cmd │ ├── post-mortem.cmd │ ├── jump2.cmd │ ├── info-thread.cmd │ ├── jump.cmd │ ├── finish.cmd │ ├── pm-bug.right │ ├── catch2.cmd │ ├── edit.cmd │ ├── list.cmd │ ├── raise.cmd │ ├── break_loop_bug.right │ ├── ctrl.cmd │ ├── post-mortem-next.right │ ├── next.cmd │ ├── stepping.cmd │ ├── source.right │ ├── catch.cmd │ ├── info.cmd │ ├── enable.cmd │ ├── frame.cmd │ ├── break_bad.cmd │ ├── help.cmd │ ├── method.right │ ├── display.cmd │ ├── methodsig.right │ ├── edit.right │ ├── trace.right │ ├── scope-var.cmd │ ├── output.right │ ├── condition.cmd │ ├── annotate.cmd │ ├── info-var.cmd │ ├── raise.right │ ├── help.right │ ├── jump2.right │ ├── linetrace.right │ ├── breakpoints.cmd │ ├── finish.right │ ├── break_bad.right │ ├── save.cmd │ ├── jump.right │ ├── emacs_basic.cmd │ ├── post-mortem-osx.right │ ├── post-mortem.right │ ├── next.right │ ├── catch3.right │ ├── display.right │ ├── stepping.right │ ├── enable.right │ ├── info-thread.right │ ├── catch.right │ ├── setshow.cmd │ ├── info-var.right │ ├── catch2.right │ ├── frame.right │ ├── save.right │ ├── condition.right │ ├── info.right │ ├── breakpoints.right │ ├── annotate.right │ ├── list.right │ ├── emacs_basic.right │ ├── setshow.right │ └── ctrl.right ├── .cvsignore ├── null.rb ├── output.rb ├── pm-bug.rb ├── raise.rb ├── bp_loop_issue.rb ├── info-var-bug2.rb ├── dollar-0.rb ├── rdebug-save.1 ├── pm.rb ├── classes.rb ├── next.rb ├── pm-catch.rb ├── jump.rb ├── config.yaml ├── gcd.rb ├── runall ├── jump2.rb ├── pm-catch2.rb ├── thread1.rb ├── pm-base.rb ├── base │ ├── catchpoint.rb │ ├── binding.rb │ ├── load.rb │ └── base.rb ├── gcd-dbg.rb ├── test-list.rb ├── test-next.rb ├── test-catch.rb ├── test-scope-var.rb ├── test-source.rb ├── test-catch2.rb ├── test-catch3.rb ├── test-enable.rb ├── test-breakpoints.rb ├── test-condition.rb ├── trunc-call.rb ├── test-info.rb ├── test-annotate.rb ├── test-setshow.rb ├── test-display.rb ├── test-emacs-basic.rb ├── test-raise.rb ├── test-edit.rb ├── test-stepping.rb ├── scope-var.rb ├── test-output.rb ├── gcd-dbg-nox.rb ├── test-quit.rb ├── test-save.rb ├── cli │ └── commands │ │ ├── catchpoint_test.rb │ │ └── unit │ │ └── regexp.rb ├── pm-catch3.rb ├── test-info-thread.rb ├── test-jump.rb ├── test-finish.rb ├── test-method.rb ├── test-break-bad.rb ├── test-frame.rb ├── info-var-bug.rb ├── test-trace.rb ├── test-dollar-0.rb ├── test-info-var.rb ├── test-init.rb ├── test-help.rb ├── test-ctrl.rb └── test-hist.rb ├── svn2cl_usermap ├── autogen.sh ├── doc ├── tri3.rb ├── triangle.rb ├── test-tri2.rb ├── primes.rb ├── hanoi.rb ├── .cvsignore ├── emacs-notes.txt └── Makefile.am ├── AUTHORS ├── runner.sh ├── cli └── ruby-debug │ ├── debugger.rb │ ├── commands │ ├── skip.rb │ ├── source.rb │ ├── reload.rb │ ├── quit.rb │ ├── tmate.rb │ ├── continue.rb │ ├── kill.rb │ ├── finish.rb │ ├── edit.rb │ ├── condition.rb │ ├── help.rb │ ├── catchpoint.rb │ ├── jump.rb │ ├── trace.rb │ ├── stepping.rb │ ├── method.rb │ ├── save.rb │ ├── list.rb │ ├── display.rb │ ├── control.rb │ └── irb.rb │ └── helper.rb ├── configure.ac ├── Makefile.am ├── rdbg.rb ├── emacs ├── test │ ├── test-gud.el │ ├── test-indent.el │ ├── test-shortkey.el │ ├── test-frames.el │ ├── test-fns.el │ └── test-annotate.el ├── rdebug-dbg.el ├── rdebug-error.el ├── rdebug-info.el └── rdebug-cmd.el ├── LICENSE ├── ext └── ruby_debug │ └── extconf.rb └── ruby-debug.gemspec /test/data/quit.right: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/.cvsignore: -------------------------------------------------------------------------------- 1 | config.private.yaml 2 | -------------------------------------------------------------------------------- /test/null.rb: -------------------------------------------------------------------------------- 1 | # Nothing here. Move along. 2 | -------------------------------------------------------------------------------- /test/output.rb: -------------------------------------------------------------------------------- 1 | puts "one" 2 | puts "two" 3 | -------------------------------------------------------------------------------- /test/pm-bug.rb: -------------------------------------------------------------------------------- 1 | a = 1 2 | @x = 2 3 | raise 4 | -------------------------------------------------------------------------------- /test/raise.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | raise "abc" 4 | -------------------------------------------------------------------------------- /test/bp_loop_issue.rb: -------------------------------------------------------------------------------- 1 | 1.upto(2) { 2 | sleep 0.01 3 | } 4 | -------------------------------------------------------------------------------- /test/data/dollar-0.right: -------------------------------------------------------------------------------- 1 | ./dollar-0.rb 2 | ./dollar-0.rb 3 | -------------------------------------------------------------------------------- /test/data/dollar-0a.right: -------------------------------------------------------------------------------- 1 | ./dollar-0.rb 2 | ./dollar-0.rb 3 | -------------------------------------------------------------------------------- /test/info-var-bug2.rb: -------------------------------------------------------------------------------- 1 | s = '<%= PRODUCT[:name] %>' 2 | y = 0 3 | -------------------------------------------------------------------------------- /test/data/dollar-0b.right: -------------------------------------------------------------------------------- 1 | ../test/dollar-0.rb 2 | ../test/dollar-0.rb 3 | -------------------------------------------------------------------------------- /test/data/info-var-bug2.cmd: -------------------------------------------------------------------------------- 1 | step 2 | info variables 3 | quit 4 | 5 | 6 | -------------------------------------------------------------------------------- /test/data/noquit.right: -------------------------------------------------------------------------------- 1 | The program has finished and will be restarted. 2 | -------------------------------------------------------------------------------- /svn2cl_usermap: -------------------------------------------------------------------------------- 1 | andersl:Anders Lindgren 2 | kent:Kent Sibilev 3 | rockyb:Rocky Bernstein 4 | -------------------------------------------------------------------------------- /test/data/break_loop_bug.cmd: -------------------------------------------------------------------------------- 1 | set debuggertesting on 2 | break 2 3 | cont 4 | cont 5 | cont 6 | -------------------------------------------------------------------------------- /test/dollar-0.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # A test to see that rdebug set's $0 properly. 3 | puts $0 4 | puts __FILE__ 5 | 6 | -------------------------------------------------------------------------------- /test/data/history.right: -------------------------------------------------------------------------------- 1 | list 2 | step 3 | show args 4 | show commands 5 | set history save on 6 | show history 7 | quit unconditionally 8 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Things to do after doing a clean SVN update to add the proper files. 3 | ln -vfs CHANGES NEWS 4 | autoreconf -i -s 5 | -------------------------------------------------------------------------------- /doc/tri3.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | def triangle(n) 3 | (0..n).inject do |sum, i| 4 | sum +=i 5 | end 6 | end 7 | puts triangle(3) 8 | 9 | -------------------------------------------------------------------------------- /test/data/source.cmd: -------------------------------------------------------------------------------- 1 | # Test the source command 2 | # rdebug-save has breakpoint commands 3 | set debuggertesting on 4 | source ./rdebug-save.1 5 | quit 6 | -------------------------------------------------------------------------------- /test/data/test-init-osx.right: -------------------------------------------------------------------------------- 1 | gcd-dbg.rb:18 2 | if a > b 3 | "./gcd-dbg.rb" 4 | Argument list to give program being debugged when it is started is "5". 5 | -------------------------------------------------------------------------------- /test/data/test-init.right: -------------------------------------------------------------------------------- 1 | gcd-dbg.rb:18 2 | if a > b 3 | (rdb:1) "./gcd-dbg.rb" 4 | (rdb:1) Argument list to give program being debugged when it is started is "5". 5 | (rdb:1) -------------------------------------------------------------------------------- /test/rdebug-save.1: -------------------------------------------------------------------------------- 1 | break gcd.rb:10 2 | break gcd.rb:12 if a > b 3 | set autoeval on 4 | set basename off 5 | set debuggertesting off 6 | set autolist off 7 | set autoirb off 8 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Author: 2 | Kent Sibilev 3 | 4 | Contributors: 5 | Markus Barchfeld 6 | R. Bernstein 7 | Anders Lindgren 8 | 9 | Contributor and maintainer: 10 | Mark Moseley 11 | -------------------------------------------------------------------------------- /runner.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ruby=${RUBY:-ruby} 4 | dir=`dirname $0` 5 | rdebug=${RDEBUG:-${dir}/bin/rdebug} 6 | $ruby -I${dir}/ext:${dir}/lib:${dir}/cli -- $rdebug $* 7 | exit $? 8 | -------------------------------------------------------------------------------- /cli/ruby-debug/debugger.rb: -------------------------------------------------------------------------------- 1 | # Module/Package to do the most-common thing: get into the debugger with 2 | # minimal fuss. Compare with: require "debug" 3 | require "ruby-debug" 4 | Debugger.start 5 | debugger -------------------------------------------------------------------------------- /test/pm.rb: -------------------------------------------------------------------------------- 1 | #!/ursr/bin/env ruby 2 | # Test Debugger.catchpoint and post-mortem handling 3 | def zero_div 4 | x = 5 5 | 1/0 6 | end 7 | x = 2 8 | zero_div 9 | raise RuntimeError 10 | x = 3 11 | 12 | -------------------------------------------------------------------------------- /test/data/output.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests the "starting" annotation 3 | # ******************************************************** 4 | step 5 | step 6 | quit 7 | -------------------------------------------------------------------------------- /test/classes.rb: -------------------------------------------------------------------------------- 1 | class Mine 2 | def initialize 3 | @myvar = 'init' 4 | end 5 | def mymethod(a, b=5, &block) 6 | end 7 | def self.classmeth 8 | end 9 | end 10 | me = Mine.new 11 | metoo = Mine(new) 12 | -------------------------------------------------------------------------------- /test/data/quit.cmd: -------------------------------------------------------------------------------- 1 | # *************************************************** 2 | # This tests the quit. 3 | # *************************************************** 4 | set debuggertesting on 5 | # FIXME need to test --no-quit. 6 | quit 7 | -------------------------------------------------------------------------------- /test/data/info-var-bug2.right: -------------------------------------------------------------------------------- 1 | ./info-var-bug2.rb:1 2 | s = '<%= PRODUCT[:name] %>' 3 | # step 4 | ./info-var-bug2.rb:2 5 | y = 0 6 | # info variables 7 | s = "<%= PRODUCT[:name] %>" 8 | self = main 9 | y = nil 10 | # quit 11 | -------------------------------------------------------------------------------- /test/next.rb: -------------------------------------------------------------------------------- 1 | def foo 2 | a = 1 3 | puts "Stop here" 4 | b = 2 5 | end 6 | 7 | a = 1 8 | if a == 1 9 | a += 2 10 | puts a 11 | end 12 | foo 13 | b = 2 14 | b += 2 15 | puts "one" 16 | c = 4 17 | puts "two" 18 | 19 | -------------------------------------------------------------------------------- /test/pm-catch.rb: -------------------------------------------------------------------------------- 1 | #!/ursr/bin/env ruby 2 | # Test Debugger.catchpoint and post-mortem handling 3 | def zero_div 4 | x = 5 5 | 1/0 6 | x = 6 7 | end 8 | x = 2 9 | puts zero_div 10 | raise RuntimeError 11 | x = 3 12 | 13 | -------------------------------------------------------------------------------- /test/jump.rb: -------------------------------------------------------------------------------- 1 | def foo 2 | j = 0 3 | [1,2,3,4,5].each { |i| 4 | j = i 5 | [10,11,12].each { |k| 6 | j = j + k 7 | puts j 8 | } 9 | } 10 | puts j 11 | end 12 | 13 | foo 14 | puts "done" 15 | -------------------------------------------------------------------------------- /test/data/linetrace.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests the 'linetrace' command. 3 | # ******************************************************** 4 | set basename on 5 | set linetrace on 6 | continue 7 | -------------------------------------------------------------------------------- /test/data/pm-bug.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests the edit command 3 | # ******************************************************** 4 | set debuggertesting on 5 | # Tracker #22118 6 | i v 7 | quit 8 | -------------------------------------------------------------------------------- /test/data/test-init-cygwin.right: -------------------------------------------------------------------------------- 1 | gcd-dbg.rb:18 2 | if a > b 3 | (rdb:1) p Debugger::PROG_SCRIPT 4 | "./gcd-dbg.rb" 5 | (rdb:1) show args 6 | Argument list to give program being debugged when it is started is "5". 7 | (rdb:1) quit unconditionally 8 | -------------------------------------------------------------------------------- /test/data/post-mortem-next.cmd: -------------------------------------------------------------------------------- 1 | # ****************************************************** 2 | # This tests running "next" over code that post-mortems 3 | # ****************************************************** 4 | set debuggertesting on 5 | next 2 6 | next 7 | quit 8 | 9 | -------------------------------------------------------------------------------- /test/data/catch3.cmd: -------------------------------------------------------------------------------- 1 | # *************************************************** 2 | # Test catch 3 | # *************************************************** 4 | set debuggertesting on 5 | set autoeval off 6 | set basename on 7 | c 8 | w 9 | p $var 10 | jump +4 11 | c 12 | -------------------------------------------------------------------------------- /doc/triangle.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Compute the n'th triangle number - the hard way 3 | # triangle(n) == (n * (n+1)) / 2 4 | def triangle(n) 5 | tri = 0 6 | 0.upto(n) do |i| 7 | tri += i 8 | end 9 | return tri 10 | end 11 | 12 | puts triangle(3) 13 | -------------------------------------------------------------------------------- /test/data/method.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests the 'method' command 3 | # ******************************************************** 4 | set debuggertesting on 5 | set autoeval off 6 | b 11 7 | c 8 | method Mine 9 | m iv me 10 | quit 11 | -------------------------------------------------------------------------------- /test/config.yaml: -------------------------------------------------------------------------------- 1 | # Do not commit personal changes here back to the repository. Create 2 | # config.private.yaml which, if exists, is preferred to this one. 3 | 4 | # either should be on the $PATH or use full path 5 | ruby: ruby 6 | 7 | # possibility to specify interpreter parameters 8 | #ruby_params: -w 9 | -------------------------------------------------------------------------------- /test/data/methodsig.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests the 'method' command 3 | # ******************************************************** 4 | set debuggertesting on 5 | set autoeval off 6 | b 3 7 | c 8 | method sig initialize 9 | method sig mymethod 10 | quit 11 | -------------------------------------------------------------------------------- /test/gcd.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # GCD. We assume positive numbers 4 | def gcd(a, b) 5 | # Make: a <= b 6 | if a > b 7 | a, b = [b, a] 8 | end 9 | 10 | return nil if a <= 0 11 | 12 | if a == 1 or b-a == 0 13 | return a 14 | end 15 | gcd(b-a, a) 16 | end 17 | 18 | gcd(3,5) 19 | -------------------------------------------------------------------------------- /test/data/post-mortem.cmd: -------------------------------------------------------------------------------- 1 | # *************************************************** 2 | # This tests post-mortem handling. 3 | # *************************************************** 4 | set debuggertesting on 5 | continue 6 | # Should have got a divide by 0 error 7 | info program 8 | where 9 | up 10 | p x 11 | help 12 | quit 13 | 14 | -------------------------------------------------------------------------------- /test/data/jump2.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests jump command 3 | # ******************************************************** 4 | set debuggertesting on 5 | set callstyle last 6 | set force off 7 | step 8 | step 9 | step 10 | step 11 | step 12 | step 13 | step 14 | step 15 | jump 20 16 | cont 17 | -------------------------------------------------------------------------------- /test/data/info-thread.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests basic info thread commands 3 | set debuggertesting on 4 | set callstyle last 5 | set autoeval off 6 | info threads terse 7 | info threads ver 8 | info thread 1 t 9 | info threads 10 | info thread 11 | help info thread 12 | help info threads 13 | q 14 | -------------------------------------------------------------------------------- /test/data/jump.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests jump command 3 | # ******************************************************** 4 | set debuggertesting on 5 | set callstyle last 6 | set force off 7 | break 7 8 | cont 9 | jump -1 10 | cont 11 | delete 1 12 | jump -1 13 | jump +1 14 | next 15 | jump 2 16 | cont 17 | -------------------------------------------------------------------------------- /test/data/finish.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests finish. 3 | # ******************************************************** 4 | set debuggertesting on 5 | set callstyle last 6 | set autoeval off 7 | break 6 8 | continue 9 | continue 10 | continue 11 | where 12 | finish 0 13 | where 14 | p a 15 | p b 16 | finish 17 | -------------------------------------------------------------------------------- /test/data/pm-bug.right: -------------------------------------------------------------------------------- 1 | pm-bug.rb:1 2 | a = 1 3 | # # ******************************************************** 4 | # # This tests the edit command 5 | # # ******************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # # Tracker #22118 9 | # i v 10 | a = nil 11 | self = main 12 | # quit 13 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_INIT(ruby-debug-extra, 0.10.4vc,) 2 | AC_CONFIG_SRCDIR(doc/ruby-debug.texi) 3 | AM_INIT_AUTOMAKE 4 | 5 | ## 6 | ## Find out where to install the debugger emacs lisp files 7 | ## 8 | AM_PATH_LISPDIR 9 | AM_CONDITIONAL(INSTALL_EMACS_LISP, test "x$lispdir" != "x") 10 | 11 | AC_CONFIG_FILES([doc/Makefile emacs/Makefile Makefile]) 12 | AC_OUTPUT 13 | -------------------------------------------------------------------------------- /test/data/catch2.cmd: -------------------------------------------------------------------------------- 1 | # *************************************************** 2 | # Test catch 3 | # *************************************************** 4 | set debuggertesting on 5 | set autoeval off 6 | set basename on 7 | catch ZeroDivisionError 8 | c 9 | sk 10 | break 27 11 | c 12 | jump -1 13 | break 4 14 | c 15 | p arg = nil 16 | c 17 | jump 7 18 | del 1 19 | c 20 | -------------------------------------------------------------------------------- /test/data/edit.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests the edit command 3 | # ******************************************************** 4 | set debuggertesting on 5 | # Edit using current line position. 6 | edit 7 | edit gcd.rb:5 8 | # File should not exist 9 | edit foo 10 | # Add space to the end of 'edit' 11 | edit 12 | quit 13 | -------------------------------------------------------------------------------- /test/data/list.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests the 'list' command. 3 | # ******************************************************** 4 | set basename on 5 | list 6 | list 7 | list 8 | list 9 | list - 10 | list - 11 | list - 12 | list - 13 | list 1 14 | list 20 15 | set listsize 5 16 | list 5 17 | list = 18 | list 3-4 19 | 20 | -------------------------------------------------------------------------------- /test/data/raise.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests that the debugger doesn't step into itself 3 | # when the application doesn't terminate the right way. 4 | # ******************************************************** 5 | set debuggertesting on 6 | catch x 7 | catch ZeroDivisionError 8 | info catch 9 | catch 5 10 | step 11 | quit 12 | -------------------------------------------------------------------------------- /test/runall: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | #-*- Ruby -*- 3 | debug_opt = '-d ' if $DEBUG or 'd' == ARGV[0] 4 | for file in Dir.glob("test-*.rb") do 5 | puts "=" * 50 6 | puts "== running #{file}..." 7 | system("ruby #{file}"); 8 | end 9 | if ARGV[0] == "really" 10 | system("(cd test && ruby #{debug_opt}runall)") 11 | system("(cd examples && ruby #{debug_opt}runall)") 12 | end 13 | -------------------------------------------------------------------------------- /test/data/break_loop_bug.right: -------------------------------------------------------------------------------- 1 | bp_loop_issue.rb:1 2 | 1.upto(2) { 3 | # set debuggertesting on 4 | Currently testing the debugger is on. 5 | # break 2 6 | Breakpoint 1 file ./bp_loop_issue.rb, line 2 7 | # cont 8 | Breakpoint 1 at bp_loop_issue.rb:2 9 | bp_loop_issue.rb:2 10 | sleep 0.01 11 | # cont 12 | Breakpoint 1 at bp_loop_issue.rb:2 13 | bp_loop_issue.rb:2 14 | sleep 0.01 15 | # cont 16 | -------------------------------------------------------------------------------- /test/data/ctrl.cmd: -------------------------------------------------------------------------------- 1 | set debuggertesting on 2 | set width 80 3 | help 4 | help info 5 | info args 6 | info breakpoints 7 | info display 8 | info program 9 | info global_variables 10 | info line 11 | info locals 12 | info stack 13 | info threads 14 | info variables 15 | eval 1+2 16 | help show 17 | set trace off 18 | show trace 19 | set trace on 20 | set annotate 0 21 | show annotate 22 | 23 | 24 | -------------------------------------------------------------------------------- /test/data/post-mortem-next.right: -------------------------------------------------------------------------------- 1 | pm.rb:3 2 | def zero_div 3 | # # ****************************************************** 4 | # # This tests running "next" over code that post-mortems 5 | # # ****************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # next 2 9 | pm.rb:8 10 | zero_div 11 | # next 12 | pm.rb:5 13 | 1/0 14 | # quit 15 | -------------------------------------------------------------------------------- /test/data/next.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests next command and break at proc def 3 | # ******************************************************** 4 | set debuggertesting on 5 | set callstyle last 6 | set force off 7 | break 1 8 | next 9 | next 10 | next 11 | next 12 | next 13 | next 14 | next 15 | next 16 | next 17 | next 18 | next 19 | next 20 | next 21 | next 22 | next 23 | -------------------------------------------------------------------------------- /test/data/stepping.cmd: -------------------------------------------------------------------------------- 1 | # *************************************************** 2 | # This tests step, next, finish and continue 3 | # *************************************************** 4 | set debuggertesting on 5 | set callstyle last 6 | next 7 | where 8 | step a 9 | set forcestep on 10 | step- ; step- 11 | set forcestep off 12 | where 13 | next 14 | step+ 15 | where 16 | step 3 17 | step+ 18 | where 19 | next+ 20 | # finish 21 | quit 22 | -------------------------------------------------------------------------------- /test/data/source.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # Test the source command 4 | # # rdebug-save has breakpoint commands 5 | # set debuggertesting on 6 | Currently testing the debugger is on. 7 | # source ./rdebug-save.1 8 | Breakpoint 1 file gcd.rb, line 10 9 | Breakpoint 2 file gcd.rb, line 12 10 | autoeval is on. 11 | basename is off. 12 | Currently testing the debugger is on. 13 | autolist is off. 14 | autoirb is off. 15 | # quit 16 | -------------------------------------------------------------------------------- /test/jump2.rb: -------------------------------------------------------------------------------- 1 | def foo3(arg) 2 | arg = arg + 3 3 | puts arg 4 | arg = arg/0 if arg > 10 5 | rescue 6 | puts "r3" 7 | end 8 | 9 | def foo2(arg) 10 | arg = arg + 2 11 | foo3(arg) 12 | puts arg 13 | rescue 14 | puts "r2" 15 | end 16 | 17 | def foo1(arg) 18 | arg = arg + 1 19 | foo2(arg) 20 | puts arg 21 | rescue 22 | puts "r1" 23 | end 24 | 25 | foo1(0) 26 | foo2(10) 27 | puts "done" 28 | -------------------------------------------------------------------------------- /doc/test-tri2.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "test/unit" 3 | require "tri2.rb" 4 | require "rubygems" 5 | require "ruby-debug" 6 | Debugger.start 7 | 8 | class TestTri < Test::Unit::TestCase 9 | def test_basic 10 | debugger 11 | solutions = [] 12 | 0.upto(5) do |i| 13 | solutions << triangle(i) 14 | end 15 | assert_equal([0, 1, 3, 6, 10, 15], solutions, 16 | "Testing the first 5 triangle numbers") 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /test/data/catch.cmd: -------------------------------------------------------------------------------- 1 | # *************************************************** 2 | # Test catch 3 | # *************************************************** 4 | set debuggertesting on 5 | set autoeval off 6 | set basename on 7 | info catch 8 | catch ZeroDivisionError off 9 | catch ZeroDivisionError off afdasdf 10 | catch ZeroDivisionError 11 | info catch 12 | catch ZeroDivisionError off 13 | info catch 14 | catch ZeroDivisionError 15 | c 16 | where 17 | jump 6 18 | cont 19 | jump 11 20 | cont 21 | -------------------------------------------------------------------------------- /test/data/info.cmd: -------------------------------------------------------------------------------- 1 | # *************************************************** 2 | # This tests info command handling 3 | # *************************************************** 4 | set debuggertesting on 5 | set callstyle last 6 | help info 7 | info args 8 | info line 9 | info locals 10 | info stack 11 | info display 12 | help info break 13 | help info display 14 | break 10 15 | break 12 16 | info break 10 17 | info break 1 18 | info break 1 2 19 | info break 20 | info file ./gcd.rb break 21 | quit 22 | -------------------------------------------------------------------------------- /test/pm-catch2.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Test Debugger.catchpoint 3 | def bar(arg) 4 | puts "bar begin" 5 | 1/0 if arg 6 | raise ZeroDivisionError 7 | puts "bar end" 8 | end 9 | 10 | def foo 11 | puts "foo begin" 12 | yield 1 13 | puts "foo end" 14 | rescue ZeroDivisionError 15 | puts "rescue" 16 | end 17 | 18 | def zero_div(arg) 19 | x = 5 20 | foo { |i| bar(i) } 21 | x + arg 22 | rescue ZeroDivisionError 23 | "zero_div rescue" 24 | end 25 | 26 | puts zero_div(10) 27 | puts "done" 28 | -------------------------------------------------------------------------------- /test/data/enable.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests the enable command. 3 | # ******************************************************** 4 | set debuggertesting on 5 | set callstyle last 6 | set autoeval off 7 | break Object.gcd 8 | # Should have a breakpoint 1 9 | enable br 1 10 | # Get help on enable 11 | help enable 12 | # Get help on just enable break 13 | help enable break 14 | # Plain enable should work 15 | enable 16 | # An invalid enable command 17 | enable foo 18 | quit 19 | 20 | 21 | -------------------------------------------------------------------------------- /test/data/frame.cmd: -------------------------------------------------------------------------------- 1 | # *************************************************** 2 | # This tests step, next, finish and continue 3 | # *************************************************** 4 | set debuggertesting on 5 | set callstyle last 6 | # Invalid line number in continue command 7 | continue 3 8 | # This time, for sure! 9 | continue 6 10 | where 11 | up 12 | where 13 | down 14 | where 15 | frame 16 | where 17 | frame -1 18 | where 19 | up 2 20 | where 21 | down 2 22 | where 23 | frame 0 thread 3 24 | frame 0 thread 1 25 | # finish 26 | quit 27 | -------------------------------------------------------------------------------- /test/data/break_bad.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests mostly invalid breakpoints. 3 | # We have some valid ones too. 4 | # ******************************************************** 5 | set debuggertesting on 6 | set callstyle last 7 | set autoeval off 8 | # There aren't 100 lines in gcd.rb. 9 | break 100 10 | break gcd.rb:100 11 | # Line one isn't a valid stopping point. 12 | # It is a comment. 13 | break gcd.rb:1 14 | # This line is okay 15 | break gcd.rb:4 16 | # No class Foo. 17 | break Foo.bar 18 | q 19 | -------------------------------------------------------------------------------- /test/data/help.cmd: -------------------------------------------------------------------------------- 1 | # $Id: setshow.cmd 298 2007-08-28 10:07:35Z rockyb $ 2 | # This tests the functioning of some set/show debugger commands 3 | set debuggertesting on 4 | set autoeval off 5 | set width 80 6 | ### ******************************* 7 | ### *** help commands *** 8 | ### ******************************* 9 | help foo 10 | help set listsize 11 | help show anno 12 | help show foo 13 | help info file 14 | help info file all 15 | help info file br 16 | help info files 17 | 18 | # FIXME - the below should work 19 | # help 20 | # help step 21 | -------------------------------------------------------------------------------- /test/data/method.right: -------------------------------------------------------------------------------- 1 | classes.rb:1 2 | class Mine 3 | # # ******************************************************** 4 | # # This tests the 'method' command 5 | # # ******************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # set autoeval off 9 | autoeval is off. 10 | # b 11 11 | Breakpoint 1 file ./classes.rb, line 11 12 | # c 13 | Breakpoint 1 at classes.rb:11 14 | classes.rb:11 15 | metoo = Mine(new) 16 | # method Mine 17 | mymethod 18 | 19 | # m iv me 20 | @myvar = "init" 21 | # quit 22 | -------------------------------------------------------------------------------- /test/thread1.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Adapted from Programming Ruby 2nd Ed. p. 138 3 | require 'rubygems' 4 | 5 | unless defined?(Debugger) 6 | puts "This program has to be called from the debugger" 7 | exit 1 8 | end 9 | 10 | def fn(count, i) 11 | sleep(rand(0.1)) 12 | if 4 == i 13 | debugger 14 | end 15 | Thread.current['mycount'] = count 16 | end 17 | 18 | count = 0 19 | threads = [] 20 | 5.times do |i| 21 | threads[i] = Thread.new do 22 | fn(count, i) 23 | count += 1 24 | end 25 | end 26 | threads.each {|t| t.join } 27 | -------------------------------------------------------------------------------- /test/pm-base.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Test post-mortem handling using only ruby-debug-base. 3 | src_dir = File.dirname(__FILE__) 4 | %w(ext lib cli).each do |dir| 5 | $:.unshift File.join(src_dir, '..', dir) 6 | end 7 | require 'ruby-debug-base' 8 | 9 | class CommandProcessor 10 | def at_line(context, file, line) 11 | puts 'file: %s, line: %s' % [ File.basename(file), line ] 12 | exit! 13 | end 14 | end 15 | 16 | Debugger.start(:post_mortem => true) 17 | Debugger.handler = CommandProcessor.new 18 | def zero_div 19 | 1/0 20 | end 21 | zero_div 22 | 23 | -------------------------------------------------------------------------------- /test/data/display.cmd: -------------------------------------------------------------------------------- 1 | # *************************************************** 2 | # This tests display expressions. 3 | # *************************************************** 4 | set debuggertesting on 5 | b 6 6 | c 7 | # Should be no display expression yet. 8 | info display 9 | display a 10 | display b 11 | disable display b 12 | disable display 1 13 | c 14 | enable display b 15 | enable display 1 16 | undisplay a 17 | undisplay 2 18 | # Should have only one display expression. 19 | info display 20 | undisplay 1 21 | # Now we have no more display expressions. 22 | info display 23 | q 24 | 25 | -------------------------------------------------------------------------------- /test/data/methodsig.right: -------------------------------------------------------------------------------- 1 | classes.rb:1 2 | class Mine 3 | # # ******************************************************** 4 | # # This tests the 'method' command 5 | # # ******************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # set autoeval off 9 | autoeval is off. 10 | # b 3 11 | Breakpoint 1 file ./classes.rb, line 3 12 | # c 13 | Breakpoint 1 at classes.rb:3 14 | classes.rb:3 15 | @myvar = 'init' 16 | # method sig initialize 17 | Mine#initialize() 18 | # method sig mymethod 19 | Mine#mymethod(a, b=5, &block) 20 | # quit 21 | -------------------------------------------------------------------------------- /test/data/edit.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # ******************************************************** 4 | # # This tests the edit command 5 | # # ******************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # # Edit using current line position. 9 | # edit 10 | FAKE-EDITOR +4 ./gcd.rb 11 | # edit gcd.rb:5 12 | FAKE-EDITOR +5 gcd.rb 13 | # # File should not exist 14 | # edit foo 15 | *** Invalid file/line number specification: foo 16 | # # Add space to the end of 'edit' 17 | # edit 18 | FAKE-EDITOR +4 ./gcd.rb 19 | # quit 20 | -------------------------------------------------------------------------------- /test/data/trace.right: -------------------------------------------------------------------------------- 1 | Tracing(1):./gcd.rb:4 def gcd(a, b) 2 | Tracing(1):./gcd.rb:18 gcd(3,5) 3 | Tracing(1):./gcd.rb:6 if a > b 4 | Tracing(1):./gcd.rb:10 return nil if a <= 0 5 | Tracing(1):./gcd.rb:12 if a == 1 or b-a == 0 6 | Tracing(1):./gcd.rb:15 gcd(b-a, a) 7 | Tracing(1):./gcd.rb:6 if a > b 8 | Tracing(1):./gcd.rb:10 return nil if a <= 0 9 | Tracing(1):./gcd.rb:12 if a == 1 or b-a == 0 10 | Tracing(1):./gcd.rb:15 gcd(b-a, a) 11 | Tracing(1):./gcd.rb:6 if a > b 12 | Tracing(1):./gcd.rb:10 return nil if a <= 0 13 | Tracing(1):./gcd.rb:12 if a == 1 or b-a == 0 14 | Tracing(1):./gcd.rb:13 return a 15 | -------------------------------------------------------------------------------- /test/data/scope-var.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests variable display by scope 3 | # ******************************************************** 4 | set debuggertesting on 5 | set callstyle last 6 | set force off 7 | set annotate 3 8 | step 9 | step 10 | step 11 | step 12 | step 13 | step 14 | step 15 | step 16 | step 17 | step 18 | step 19 | step 20 | step 21 | step 22 | step 23 | step 24 | step 25 | step 26 | step 27 | step 28 | step 29 | step 30 | step 31 | step 32 | step 33 | step 34 | step 35 | step 36 | step 37 | step 38 | step 39 | step 40 | step 41 | step 42 | cont 43 | -------------------------------------------------------------------------------- /test/data/output.right: -------------------------------------------------------------------------------- 1 | starting 2 | stopped 3 | breakpoints 4 | No breakpoints. 5 |  6 | stack 7 | --> #0 at line ./output.rb:1 8 |  9 | variables 10 | self = main 11 |  12 | source ./output.rb:1 13 | puts "one" 14 | # # ******************************************************** 15 | # # This tests the "starting" annotation 16 | # # ******************************************************** 17 | # step 18 | starting 19 | one 20 | stopped 21 | stack 22 | --> #0 at line ./output.rb:2 23 |  24 | variables 25 | self = main 26 |  27 | source ./output.rb:2 28 | puts "two" 29 | # step 30 | starting 31 | two 32 | -------------------------------------------------------------------------------- /doc/primes.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Enumerator for primes 3 | class SievePrime 4 | @@odd_primes = [] 5 | def self.next_prime(&block) 6 | candidate = 2 7 | yield candidate 8 | not_prime = false 9 | candidate += 1 10 | while true do 11 | @@odd_primes.each do |p| 12 | not_prime = (0 == (candidate % p)) 13 | break if not_prime 14 | end 15 | unless not_prime 16 | @@odd_primes << candidate 17 | yield candidate 18 | end 19 | candidate += 2 20 | end 21 | end 22 | end 23 | SievePrime.next_prime do |prime| 24 | puts prime 25 | break if prime > 10 26 | end 27 | 28 | 29 | -------------------------------------------------------------------------------- /doc/hanoi.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | def hanoi(n,a,b,c) 4 | if n-1 > 0 5 | hanoi(n-1, a, c, b) 6 | end 7 | puts "Move disk %s to %s" % [a, b] 8 | if n-1 > 0 9 | hanoi(n-1, c, b, a) 10 | end 11 | end 12 | 13 | i_args=ARGV.length 14 | if i_args > 1 15 | puts "*** Need number of disks or no parameter" 16 | exit 1 17 | end 18 | 19 | n=3 20 | 21 | if i_args > 0 22 | begin 23 | n = ARGV[0].to_i 24 | rescue ValueError, msg: 25 | print "** Expecting an integer, got: %s" % ARGV[0].to_s 26 | exit 2 27 | end 28 | end 29 | 30 | if n < 1 or n > 100 31 | puts "*** number of disks should be between 1 and 100" 32 | exit 2 33 | end 34 | 35 | hanoi(n, :a, :b, :c) 36 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = doc emacs 2 | PHONY = test ChangeLogs 3 | test: check 4 | ChangeLogs: ChangeLog doc/ChangeLog emacs/ChangeLog lib/ChangeLog 5 | ChangeLog: 6 | svn2cl --authors=svn2cl_usermap svn://rubyforge.org/var/svn/ruby-debug/trunk \ 7 | cli test bin AUTHORS CHANGES LICENSE README runner.sh -o ChangeLog 8 | lib/ChangeLog: 9 | svn2cl --authors=svn2cl_usermap svn://rubyforge.org/var/svn/ruby-debug/trunk \ 10 | lib ext -o lib/ChangeLog 11 | doc/ChangeLog: 12 | svn2cl --authors=svn2cl_usermap svn://rubyforge.org/var/svn/ruby-debug/trunk/doc -o doc/ChangeLog 13 | emacs/ChangeLog: 14 | svn2cl --authors=svn2cl_usermap svn://rubyforge.org/var/svn/ruby-debug/trunk/emacs -o emacs/ChangeLog 15 | -------------------------------------------------------------------------------- /test/base/catchpoint.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # Test catchpoint in C ruby_debug extension. 5 | 6 | class TestRubyDebugCatchpoint < Test::Unit::TestCase 7 | 8 | $:.unshift File.join(File.dirname(__FILE__), '..', '..', 'ext') 9 | require 'ruby_debug' 10 | $:.shift 11 | 12 | # test current_context 13 | def test_catchpoints 14 | assert_equal({}, Debugger.catchpoints) 15 | Debugger.add_catchpoint('ZeroDivisionError') 16 | assert_equal({'ZeroDivisionError' => 0}, Debugger.catchpoints) 17 | Debugger.add_catchpoint('RuntimeError') 18 | assert_equal(['RuntimeError', 'ZeroDivisionError'], 19 | Debugger.catchpoints.keys.sort) 20 | end 21 | 22 | end 23 | 24 | -------------------------------------------------------------------------------- /test/gcd-dbg.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This program is used to test that 'restart' works when we didn't call 3 | # the debugger initially. 4 | 5 | TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__), "..")) unless 6 | defined?(TOP_SRC_DIR) 7 | 8 | $:.unshift File.join(TOP_SRC_DIR, "ext") 9 | $:.unshift File.join(TOP_SRC_DIR, "lib") 10 | $:.unshift File.join(TOP_SRC_DIR, "cli") 11 | require 'ruby-debug' 12 | 13 | 14 | # GCD. We assume positive numbers 15 | def gcd(a, b) 16 | # Make: a <= b 17 | debugger 18 | if a > b 19 | a, b = [b, a] 20 | end 21 | 22 | return nil if a <= 0 23 | 24 | if a == 1 or b-a == 0 25 | return a 26 | end 27 | return gcd(b-a, a) 28 | end 29 | 30 | gcd(3,5) 31 | -------------------------------------------------------------------------------- /test/test-list.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test List commands 8 | class TestList < Test::Unit::TestCase 9 | 10 | @@src_dir = File.join(Dir.pwd, File.dirname(__FILE__)) 11 | 12 | require File.join(@@src_dir, 'helper') 13 | include TestHelper 14 | 15 | # Test commands in list.rb 16 | def test_basic 17 | testname='list' 18 | Dir.chdir(@@src_dir) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./gcd.rb 3 5")) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/data/condition.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests primarily the condition command. 3 | # In order to do this we need to run break, and disable 4 | # ******************************************************** 5 | set debuggertesting on 6 | set callstyle last 7 | set autoeval off 8 | break 6 if a > b 9 | info break 10 | condition 1 11 | info break 12 | break 12 13 | condition 2 1 == a 14 | # FIXME: should be able to catch error on: 15 | # condition 2 if 1 == a 16 | disable 1 17 | continue 18 | info break 19 | p a 20 | # Now test trying to enable an invalid breakpoint 21 | break 6 if a > 22 | info break 23 | enable 3 24 | info break 25 | condition 3 a > 5 26 | enable 3 27 | info break 28 | quit 29 | -------------------------------------------------------------------------------- /test/test-next.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test next command 8 | class TestNextCommand < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='next' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./#{testname}.rb")) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/test-catch.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test exception catching 8 | class TestExceptionCatch < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='catch' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./pm-catch.rb")) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/test-scope-var.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test variable scope 8 | class TestScopeVar < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='scope-var' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./#{testname}.rb")) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/test-source.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test 'source' command handling. 8 | class TestSource < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='source' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./gcd.rb 3 5")) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/test-catch2.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test exception catching 8 | class TestExceptionCatch2 < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='catch2' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./pm-catch2.rb")) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/test-catch3.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test exception catching 8 | class TestExceptionCatch3 < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='catch3' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./pm-catch3.rb")) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/test-enable.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test enable and disable commands 8 | class TestEnable < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='enable' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./gcd.rb 3 5")) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/test-breakpoints.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test breakpoint commands 8 | class TestBreakpoints < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='breakpoints' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./gcd.rb 3 5")) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/test-condition.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test condition command 8 | class TestConditionCommand < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='condition' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./gcd.rb 3 5")) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/trunc-call.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This program is used to test that 'restart' works when we didn't call 3 | # the debugger initially. 4 | 5 | TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__), "..")) unless 6 | defined?(TOP_SRC_DIR) 7 | 8 | $:.unshift File.join(TOP_SRC_DIR, "ext") 9 | $:.unshift File.join(TOP_SRC_DIR, "lib") 10 | $:.unshift File.join(TOP_SRC_DIR, "cli") 11 | require 'ruby-debug' 12 | 13 | # GCD. We assume positive numbers 14 | def gcd(a, b) 15 | # Make: a <= b 16 | if a > b 17 | a, b = [b, a] 18 | end 19 | if a==3 20 | Debugger.debugger 21 | end 22 | 23 | return nil if a <= 0 24 | 25 | if a == 1 or b-a == 0 26 | return a 27 | end 28 | return gcd(b-a, a) 29 | end 30 | 31 | gcd(13,8) 32 | -------------------------------------------------------------------------------- /test/test-info.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test info commands 8 | class TestInfo < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | # Test commands in info.rb 17 | def test_basic 18 | testname='info' 19 | Dir.chdir(@@SRC_DIR) do 20 | script = File.join('data', testname + '.cmd') 21 | assert_equal(true, 22 | run_debugger(testname, 23 | "--script #{script} -- ./gcd.rb 3 5")) 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /test/test-annotate.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | require 'fileutils' 4 | 5 | # begin require 'rubygems' rescue LoadError end 6 | # require 'ruby-debug'; Debugger.start 7 | 8 | # Test annotate handling. 9 | class TestAnnotate < Test::Unit::TestCase 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='annotate' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./gcd.rb 3 5")) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/test-setshow.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | class TestSetShow < Test::Unit::TestCase 8 | 9 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 10 | defined?(@@SRC_DIR) 11 | 12 | require File.join(@@SRC_DIR, 'helper') 13 | include TestHelper 14 | 15 | # Test initial variables and setting/getting state. 16 | def test_basic 17 | testname='setshow' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./gcd.rb 3 5")) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/test-display.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test Display commands 8 | class TestDisplay < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | # Test commands in display.rb 17 | def test_basic 18 | testname='display' 19 | Dir.chdir(@@SRC_DIR) do 20 | script = File.join('data', testname + '.cmd') 21 | assert_equal(true, 22 | run_debugger(testname, 23 | "--script #{script} -- ./gcd.rb 3 5")) 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /test/test-emacs-basic.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # require 'rubygems' 5 | # require 'ruby-debug'; Debugger.start(:post_mortem => true) 6 | 7 | # Test the --emacs-basic option. 8 | class TestEmacsBasic < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper.rb') 14 | 15 | include TestHelper 16 | 17 | def test_basic 18 | testname='emacs_basic' 19 | Dir.chdir(@@SRC_DIR) do 20 | script = File.join('data', testname + '.cmd') 21 | assert_equal(true, 22 | run_debugger(testname, 23 | "--emacs-basic --script #{script} -- ./gcd.rb 3 5")) 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /test/test-raise.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test Debugger.load handles uncaught exceptions in the debugged program. 8 | class TestRaise < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='raise' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./raise.rb")) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/data/annotate.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests annotations 3 | # ******************************************************** 4 | set debuggertesting on 5 | set callstyle last 6 | set force off 7 | set annotate 3 8 | # Get into gcd 9 | step 2 10 | # "break" should trigger break annotation 11 | break 10 12 | # "delete" should trigger break annotation 13 | delete 1 14 | # p should not trigger a breakpoint annotation 15 | p a 16 | # "up" should trigger annotations 17 | up 18 | # "b" should trigger like "break" 19 | b 12 20 | # "display" should trigger display annotation 21 | display 1+2 22 | # undisplay should trigger display annotation 23 | undisplay 1 24 | step 25 | # Test error annotations 26 | up 10 27 | frame 100 28 | break bogus:5 29 | quit! 30 | -------------------------------------------------------------------------------- /test/test-edit.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test 'edit' command handling. 8 | class TestEdit < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='edit' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | ENV['EDITOR']='echo FAKE-EDITOR ' 21 | assert_equal(true, 22 | run_debugger(testname, 23 | "--script #{script} -- ./gcd.rb 3 5")) 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /test/data/info-var.cmd: -------------------------------------------------------------------------------- 1 | # *************************************************** 2 | # Test handling of info variables when we have 3 | # redefined inspect or to_s which give an error. 4 | # *************************************************** 5 | set debuggertesting on 6 | # Go to where we have a bad "inspect" of a local variable 7 | continue 36 8 | info variables 9 | # Go to where we have a bad "inspect" and "to_s" of a local variable 10 | continue 40 11 | info variables 12 | break 31 13 | # The first time through, we can do inspect. 14 | continue 15 | info locals 16 | # Now go to where we have a bad "inspect" of an class variable 17 | continue 18 | info locals 19 | info variables 20 | # Now go to where we have a bad "inspect" and "to_s" of an class variable 21 | continue 22 | info locals 23 | quit 24 | -------------------------------------------------------------------------------- /test/data/raise.right: -------------------------------------------------------------------------------- 1 | raise.rb:3 2 | raise "abc" 3 | # # ******************************************************** 4 | # # This tests that the debugger doesn't step into itself 5 | # # when the application doesn't terminate the right way. 6 | # # ******************************************************** 7 | # set debuggertesting on 8 | Currently testing the debugger is on. 9 | # catch x 10 | NameError Exception: undefined local variable or method `x' for main:Object 11 | # catch ZeroDivisionError 12 | Catch exception ZeroDivisionError. 13 | # info catch 14 | ZeroDivisionError 15 | # catch 5 16 | Warning 5 is not known to be a Class 17 | Catch exception 5. 18 | # step 19 | Catchpoint at raise.rb:3: `abc' (RuntimeError) 20 | from ../rdbg.rb:32:in `
' 21 | raise.rb:3 22 | raise "abc" 23 | # quit 24 | -------------------------------------------------------------------------------- /test/test-stepping.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test that linetracing does something. 8 | class TestStepping < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | # Test commands in stepping.rb 17 | def test_basic 18 | testname='stepping' 19 | Dir.chdir(@@SRC_DIR) do 20 | script = File.join('data', testname + '.cmd') 21 | assert_equal(true, 22 | run_debugger(testname, 23 | "--script #{script} -- ./gcd.rb 3 5")) 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /test/scope-var.rb: -------------------------------------------------------------------------------- 1 | require 'ruby_debug' 2 | def scope1(arg1, arg2) 3 | s1_var1 = 123 4 | s1_var2 = "scope1" 5 | scope2 6 | end 7 | 8 | def scope2 9 | s2_var1 = 456 10 | s2_var2 = "scope2" 11 | 0.upto(5) do |i| 12 | j = i * 10 13 | scope3 14 | end 15 | end 16 | 17 | def scope3 18 | s3_var1 = 789 19 | s3_var2 = "scope3" 20 | puts eval("s3_var1", Debugger.current_context.frame_binding(0)) 21 | puts eval("i", Debugger.current_context.frame_binding(1)) 22 | puts eval("j", Debugger.current_context.frame_binding(1)) 23 | puts eval("s2_var1", Debugger.current_context.frame_binding(2)) 24 | puts eval("s1_var1", Debugger.current_context.frame_binding(3)) 25 | puts eval("s0_var1", Debugger.current_context.frame_binding(4)) 26 | end 27 | 28 | s0_var1 = 1357; 29 | scope1(111, 222) 30 | -------------------------------------------------------------------------------- /doc/.cvsignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | Makefile.in 3 | mdate-sh 4 | missing 5 | rdebug-emacs.aux 6 | rdebug-emacs.cp 7 | rdebug-emacs.cps 8 | rdebug-emacs.fn 9 | rdebug-emacs.fns 10 | rdebug-emacs.html 11 | rdebug-emacs.info 12 | rdebug-emacs.ky 13 | rdebug-emacs.log 14 | rdebug-emacs.pdf 15 | rdebug-emacs.pg 16 | rdebug-emacs.pgs 17 | rdebug-emacs.toc 18 | rdebug-emacs.tp 19 | rdebug-emacs.vr 20 | rdoc 21 | ruby-debug.aux 22 | ruby-debug.cp 23 | ruby-debug.cps 24 | ruby-debug.fn 25 | ruby-debug.fns 26 | ruby-debug.html 27 | ruby-debug.info 28 | ruby-debug.ky 29 | ruby-debug.kys 30 | ruby-debug.log 31 | ruby-debug.pdf 32 | ruby-debug.pg 33 | ruby-debug.pgs 34 | ruby-debug.toc 35 | ruby-debug.tp 36 | ruby-debug.vr 37 | ruby-debug.vrs 38 | stamp-1 39 | stamp-vti 40 | texinfo.tex 41 | version-rdebug-emacs.texi 42 | version.texi 43 | -------------------------------------------------------------------------------- /test/test-output.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test 'starting' annotation. 8 | class TestStartingAnnotate < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='output' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "-A 3 --script #{script} -- ./output.rb", 23 | nil, nil, true)) 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/skip.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | 3 | # Implements debugger "skip" command 4 | class SkipCommand < Command 5 | self.allow_in_control = true 6 | 7 | def regexp 8 | / ^\s* 9 | sk(?:ip)? \s* 10 | $ 11 | /ix 12 | end 13 | 14 | def execute 15 | Debugger::skip_next_exception 16 | print "ok\n" 17 | end 18 | 19 | class << self 20 | def help_command 21 | %w[skip] 22 | end 23 | 24 | def help(cmd) 25 | %{ 26 | sk[ip]\tskip the next thrown exception 27 | 28 | This is useful if you've explicitly caught an exception through 29 | the "catch" command, and wish to pass the exception on to the 30 | code that you're debugging. 31 | } 32 | end 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /test/data/help.right: -------------------------------------------------------------------------------- 1 | Currently testing the debugger is on. 2 | autoeval is off. 3 | width is 80. 4 | Undefined command: "foo". Try "help". 5 | Set number of source lines to list by default. 6 | Show annotation level. 7 | 0 == normal; 2 == output annotated suitably for use by programs that control 8 | ruby-debug. 9 | Invalid 'show' subcommand 'foo'. 10 | Info about a particular file read in. 11 | 12 | After the file name is supplied, you can list file attributes that 13 | you wish to see. 14 | 15 | Attributes include: "all", "basic", "breakpoint", "lines", "mtime", "path" 16 | and "sha1". 17 | Info about a particular file read in. 18 | All file information available - breakpoints, lines, mtime, path, and sha1. 19 | Info about a particular file read in. 20 | Show trace line numbers. 21 | File names and timestamps of files read in. 22 | -------------------------------------------------------------------------------- /test/base/binding.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'test/unit' 4 | 5 | # Test binding_n command 6 | class TestBinding < Test::Unit::TestCase 7 | 8 | SRC_DIR = File.expand_path(File.dirname(__FILE__)) unless 9 | defined?(SRC_DIR) 10 | %w(ext lib).each do |dir| 11 | $:.unshift File.join(SRC_DIR, '..', '..', dir) 12 | end 13 | require File.join(SRC_DIR, '..', '..', 'lib', 'ruby-debug-base') 14 | $:.shift; $:.shift 15 | 16 | def test_basic 17 | def inside_fn 18 | s = 'some other string' 19 | b2 = Kernel::binding_n(1) 20 | y2 = eval('s', b2) 21 | assert_equal('this is a test', y2) 22 | end 23 | s = 'this is a test' 24 | Debugger.start 25 | b = Kernel::binding_n(0) 26 | y = eval('s', b) 27 | assert_equal(y, s) 28 | inside_fn 29 | Debugger.stop 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /test/data/jump2.right: -------------------------------------------------------------------------------- 1 | jump2.rb:1 2 | def foo3(arg) 3 | # # ******************************************************** 4 | # # This tests jump command 5 | # # ******************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # set callstyle last 9 | Frame call-display style is last. 10 | # set force off 11 | force-stepping is off. 12 | # step 13 | jump2.rb:9 14 | def foo2(arg) 15 | # step 16 | jump2.rb:17 17 | def foo1(arg) 18 | # step 19 | jump2.rb:25 20 | foo1(0) 21 | # step 22 | jump2.rb:18 23 | arg = arg + 1 24 | # step 25 | jump2.rb:19 26 | foo2(arg) 27 | # step 28 | jump2.rb:10 29 | arg = arg + 2 30 | # step 31 | jump2.rb:11 32 | foo3(arg) 33 | # step 34 | jump2.rb:2 35 | arg = arg + 3 36 | # jump 20 37 | jump2.rb:20 38 | puts arg 39 | # cont 40 | 1 41 | 15 42 | r3 43 | 12 44 | done 45 | -------------------------------------------------------------------------------- /test/data/linetrace.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # ******************************************************** 4 | # # This tests the 'linetrace' command. 5 | # # ******************************************************** 6 | # set basename on 7 | basename is on. 8 | # set linetrace on 9 | line tracing is on. 10 | # continue 11 | Tracing(1):gcd.rb:18 gcd(3,5) 12 | Tracing(1):gcd.rb:6 if a > b 13 | Tracing(1):gcd.rb:10 return nil if a <= 0 14 | Tracing(1):gcd.rb:12 if a == 1 or b-a == 0 15 | Tracing(1):gcd.rb:15 gcd(b-a, a) 16 | Tracing(1):gcd.rb:6 if a > b 17 | Tracing(1):gcd.rb:10 return nil if a <= 0 18 | Tracing(1):gcd.rb:12 if a == 1 or b-a == 0 19 | Tracing(1):gcd.rb:15 gcd(b-a, a) 20 | Tracing(1):gcd.rb:6 if a > b 21 | Tracing(1):gcd.rb:10 return nil if a <= 0 22 | Tracing(1):gcd.rb:12 if a == 1 or b-a == 0 23 | Tracing(1):gcd.rb:13 return a 24 | -------------------------------------------------------------------------------- /test/gcd-dbg-nox.rb: -------------------------------------------------------------------------------- 1 | # This program is *NOT* supposed to be executable, but called 2 | # via ruby (in order to test that restart provides a funky $:). 3 | # This program is used to test that 'restart' works when we didn't call 4 | # the debugger initially. 5 | 6 | TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__), '..')) unless 7 | defined?(TOP_SRC_DIR) 8 | 9 | $:.unshift File.join(TOP_SRC_DIR, 'ext') 10 | $:.unshift File.join(TOP_SRC_DIR, 'lib') 11 | $:.unshift File.join(TOP_SRC_DIR, 'cli') 12 | require 'ruby-debug' 13 | Debugger.init 14 | 15 | # GCD. We assume positive numbers 16 | def gcd(a, b) 17 | # Make: a <= b 18 | debugger 19 | if a > b 20 | a, b = [b, a] 21 | end 22 | 23 | return nil if a <= 0 24 | 25 | if a == 1 or b-a == 0 26 | return a 27 | end 28 | return gcd(b-a, a) 29 | end 30 | 31 | gcd(3,5) 32 | -------------------------------------------------------------------------------- /test/data/breakpoints.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests step, next, continue, disable and 3 | # enable. 4 | # FIXME: break out enable/disable 5 | # ******************************************************** 6 | set debuggertesting on 7 | set callstyle last 8 | set autoeval off 9 | break 6 10 | break 10 11 | break 11 12 | continue 13 | where 14 | break Object.gcd 15 | info break 16 | continue 17 | where 18 | info program 19 | c 6 20 | info break 21 | break foo 22 | info break 23 | disable 1 24 | info break 25 | delete 1 26 | # We should see breakpoint 2 but not 1 27 | info break 28 | # We should still be able to access 2 29 | disable 2 30 | disable bar 31 | disable 32 | # We should be able to delete 2 33 | delete 2 3 34 | info break 35 | # Should get a message about having no breakpoints. 36 | disable 1 37 | enable 1 38 | q! 39 | -------------------------------------------------------------------------------- /test/data/finish.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # ******************************************************** 4 | # # This tests finish. 5 | # # ******************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # set callstyle last 9 | Frame call-display style is last. 10 | # set autoeval off 11 | autoeval is off. 12 | # break 6 13 | Breakpoint 1 file ./gcd.rb, line 6 14 | # continue 15 | Breakpoint 1 at gcd.rb:6 16 | gcd.rb:6 17 | if a > b 18 | # continue 19 | Breakpoint 1 at gcd.rb:6 20 | gcd.rb:6 21 | if a > b 22 | # continue 23 | Breakpoint 1 at gcd.rb:6 24 | gcd.rb:6 25 | if a > b 26 | # where 27 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 28 | #1 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:15 29 | #2 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:15 30 | #3 at line gcd.rb:18 31 | # finish 0 32 | -------------------------------------------------------------------------------- /test/test-quit.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test Quit command 8 | class TestQuit < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='quit' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | # filter = Proc.new{|got_lines, correct_lines| 21 | # [got_lines[0], correct_lines[0]].each do |s| 22 | # s.sub!(/tdebug.rb:\d+/, 'rdebug:999') 23 | # end 24 | # } 25 | assert_equal(true, 26 | run_debugger(testname, 27 | "--script #{script} -- ./null.rb")) 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /test/data/break_bad.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # ******************************************************** 4 | # # This tests mostly invalid breakpoints. 5 | # # We have some valid ones too. 6 | # # ******************************************************** 7 | # set debuggertesting on 8 | Currently testing the debugger is on. 9 | # set callstyle last 10 | Frame call-display style is last. 11 | # set autoeval off 12 | autoeval is off. 13 | # # There aren't 100 lines in gcd.rb. 14 | # break 100 15 | *** There are only 18 lines in file "gcd.rb". 16 | # break gcd.rb:100 17 | *** There are only 18 lines in file "gcd.rb". 18 | # # Line one isn't a valid stopping point. 19 | # # It is a comment. 20 | # break gcd.rb:1 21 | *** Line 1 is not a stopping point in file "gcd.rb". 22 | # # This line is okay 23 | # break gcd.rb:4 24 | Breakpoint 1 file gcd.rb, line 4 25 | # # No class Foo. 26 | # break Foo.bar 27 | *** Unknown class Foo. 28 | # q 29 | -------------------------------------------------------------------------------- /test/data/save.cmd: -------------------------------------------------------------------------------- 1 | # This tests the functioning of some set/show debugger commands 2 | set debuggertesting on 3 | ### ******************************* 4 | ### *** save/source commands *** 5 | ### ******************************* 6 | ######################################## 7 | ### test args and baseneme... 8 | ######################################## 9 | set basename off 10 | set autoeval off 11 | # Should have nothing set 12 | info break 13 | info catch 14 | # Should save nothing 15 | save temp 16 | eval File.open("temp").readlines 17 | # Should read in nothing 18 | source temp 19 | info break 20 | # Now try saving something interesting 21 | break 10 22 | catch RuntimeError 23 | save temp 24 | eval File.open("temp").readlines 25 | # FIXME: The below is broken 26 | ## Change parameters above 27 | ## catch RuntimeError off 28 | ## info catch 29 | ##set listsize 55 30 | source temp 31 | ##info break 32 | ##info catch 33 | ##show listsize 34 | c 35 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/source.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | # Implements debugger "source" command. 3 | class SourceCommand < Command 4 | self.allow_in_control = true 5 | 6 | def regexp 7 | /^\s* so(?:urce)? \s+ (.+) $/x 8 | end 9 | 10 | def execute 11 | file = File.expand_path(@match[1]).strip 12 | unless File.exist?(file) 13 | errmsg "Command file '#{file}' is not found\n" 14 | return 15 | end 16 | if @state and @state.interface 17 | @state.interface.command_queue += File.open(file).readlines 18 | else 19 | Debugger.run_script(file, @state) 20 | end 21 | end 22 | 23 | class << self 24 | def help_command 25 | 'source' 26 | end 27 | 28 | def help(cmd) 29 | %{ 30 | source FILE\texecutes a file containing debugger commands 31 | } 32 | end 33 | end 34 | end 35 | 36 | end 37 | -------------------------------------------------------------------------------- /test/data/jump.right: -------------------------------------------------------------------------------- 1 | jump.rb:1 2 | def foo 3 | # # ******************************************************** 4 | # # This tests jump command 5 | # # ******************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # set callstyle last 9 | Frame call-display style is last. 10 | # set force off 11 | force-stepping is off. 12 | # break 7 13 | Breakpoint 1 file ./jump.rb, line 7 14 | # cont 15 | Breakpoint 1 at jump.rb:7 16 | jump.rb:7 17 | puts j 18 | # jump -1 19 | jump.rb:6 20 | j = j + k 21 | # cont 22 | Breakpoint 1 at jump.rb:7 23 | jump.rb:7 24 | puts j 25 | # delete 1 26 | # jump -1 27 | jump.rb:6 28 | j = j + k 29 | # jump +1 30 | jump.rb:7 31 | puts j 32 | # next 33 | 21 34 | jump.rb:6 35 | j = j + k 36 | # jump 2 37 | jump.rb:2 38 | j = 0 39 | # cont 40 | 11 41 | 22 42 | 34 43 | 12 44 | 23 45 | 35 46 | 13 47 | 24 48 | 36 49 | 14 50 | 25 51 | 37 52 | 15 53 | 26 54 | 38 55 | 38 56 | done 57 | -------------------------------------------------------------------------------- /test/data/emacs_basic.cmd: -------------------------------------------------------------------------------- 1 | # ******************************************************** 2 | # This tests step, next, finish, continue, disable and 3 | # enable. 4 | # FIXME: break out enable/disable 5 | # ******************************************************** 6 | set debuggertesting on 7 | set callstyle last 8 | set autoeval off 9 | break 6 10 | break 10 11 | continue 12 | where 13 | break Foo.bar 14 | break Object.gcd 15 | info break 16 | continue 17 | where 18 | info program 19 | c 10 20 | info break 21 | break foo 22 | info break 23 | disable 1 24 | info break 25 | enable breakpoint 1 26 | enable br 10 27 | delete 1 28 | # We should see breakpoint 2 but not 1 29 | info break 30 | # We should still be able to access 2 31 | disable 2 32 | enable 33 | enable foo 34 | disable bar 35 | disable 36 | # We should be able to delete 2 37 | delete 2 3 38 | info break 39 | # Should get a message about having no breakpoints. 40 | disable 1 41 | enable 1 42 | # finish 43 | quit 44 | -------------------------------------------------------------------------------- /test/test-save.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # require 'rubygems' 5 | # require 'ruby-debug'; Debugger.start(:post_mortem =>true) 6 | 7 | class TestSave < Test::Unit::TestCase 8 | 9 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 10 | defined?(@@SRC_DIR) 11 | 12 | require File.join(@@SRC_DIR, 'helper') 13 | include TestHelper 14 | 15 | # Test initial variables and setting/getting state. 16 | def test_basic 17 | testname='save' 18 | filter = Proc.new{|got_lines, correct_lines| 19 | got_lines.each do |s| 20 | s.sub!(/2 file .*gcd.rb/, '2 file gcd.rb') 21 | end 22 | } 23 | Dir.chdir(@@SRC_DIR) do 24 | script = File.join('data', testname + '.cmd') 25 | assert_equal(true, 26 | run_debugger(testname, 27 | "--script #{script} -- ./gcd.rb 3 5", 28 | nil, filter)) 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /test/cli/commands/catchpoint_test.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'test/unit' 4 | 5 | class TestCatchCommand < Test::Unit::TestCase 6 | 7 | base_dir = File.expand_path(File.join(File.dirname(__FILE__), 8 | '..', '..', '..')) 9 | 10 | %w(ext lib cli).each do |dir| 11 | $: << File.join(base_dir, dir) 12 | end 13 | 14 | require File.join(base_dir, 'cli', 'ruby-debug') 15 | 16 | class MockState 17 | attr_accessor :message 18 | def context; end 19 | def confirm(msg); true end 20 | def print(*args) 21 | @message = *args 22 | end 23 | end 24 | 25 | # regression test for bug #20156 26 | def test_catch_does_not_blow_up 27 | state = MockState.new 28 | catch_cmd = Debugger::CatchCommand.new(state) 29 | assert(catch_cmd.match('catch off')) 30 | catch(:debug_error) do 31 | catch_cmd.execute 32 | end 33 | assert_equal(nil, state.message) 34 | end 35 | 36 | end 37 | -------------------------------------------------------------------------------- /rdbg.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | #!/usr/bin/env ruby 3 | # $Id: rdbg.rb 756 2008-03-13 02:15:04Z rockyb $ 4 | 5 | # Use this to run rdebug without installing it. We assume that the 6 | # library directories are stored at the same level the directory 7 | # this program. 8 | module RDebugRunner 9 | def runner(stdout=nil) 10 | 11 | # Add libraries to load path. 12 | dirname=File.dirname(__FILE__) 13 | libs = %w(ext lib cli) 14 | libs.each { |lib| $:.unshift File.join(dirname, lib) } 15 | 16 | rdebug=ENV['RDEBUG'] || File.join(dirname, 'bin', 'rdebug') 17 | if stdout 18 | old_stdout = $stdout 19 | $stdout.reopen(stdout) 20 | else 21 | old_stdout = nil 22 | end 23 | load(rdebug, true) 24 | $stdout.reopen(old_stdout) if old_stdout 25 | 26 | # Remove those libraries we just added. 27 | 1.upto(libs.size) {$:.shift} 28 | end 29 | module_function :runner 30 | end 31 | if __FILE__ == $0 32 | RDebugRunner.runner 33 | end 34 | -------------------------------------------------------------------------------- /test/pm-catch3.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Test catching uncaught exceptions 3 | def get_exception(arg) 4 | result = case arg 5 | when 0 then LoadError 6 | when 1 then ZeroDivisionError 7 | when 2 then NoMethodError 8 | else RuntimeError 9 | end 10 | return result 11 | end 12 | 13 | def bar(arg) 14 | $var = $var + "bar begin:" 15 | 1/0 if arg 16 | if false 17 | raise LoadError 18 | end 19 | $var = $var + "bar end:" 20 | end 21 | 22 | def foo(arg) 23 | $var = $var + "foo begin:" 24 | yield arg 25 | $var = $var + "foo end:" 26 | rescue get_exception(0), NameError 27 | $var = $var + "foo rescue:" 28 | ensure 29 | $var = $var + "foo ensure:" 30 | end 31 | 32 | def zero_div(arg) 33 | x = 5 34 | foo(arg) { |i| bar(i) } 35 | x + arg 36 | rescue get_exception(arg) 37 | $var = $var + "zero_div rescue:" 38 | return "divide by zero" 39 | end 40 | 41 | $var = "start1:" 42 | puts zero_div(1) 43 | puts $var 44 | $var = "start2:" 45 | puts zero_div(2) 46 | puts $var 47 | puts "done" 48 | -------------------------------------------------------------------------------- /test/test-info-thread.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test simple thread commands 8 | class TestInfoThread < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='info-thread' 18 | Dir.chdir(@@SRC_DIR) do 19 | filter = Proc.new{|got_lines, correct_lines| 20 | [got_lines, correct_lines].each do |a| 21 | a.each do |s| 22 | s.sub!(/Thread:0x[0-9a-f]+/, 'Thread:0x12345678') 23 | end 24 | end 25 | } 26 | script = File.join('data', testname + '.cmd') 27 | assert_equal(true, 28 | run_debugger(testname, 29 | "--script #{script} -- ./gcd.rb 3 5", nil, filter)) 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /test/data/post-mortem-osx.right: -------------------------------------------------------------------------------- 1 | pm.rb:3 2 | def zero_div 3 | # # *************************************************** 4 | # # This tests post-mortem handling. 5 | # # *************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # continue 9 | pm.rb:5 10 | 1/0 11 | # # Should have got a divide by 0 error 12 | # info program 13 | The program crashed. 14 | Exception: # 15 | # where 16 | --> #0 / at line pm.rb:5 17 | #1 at line pm.rb:8 18 | # up 19 | #1 at line pm.rb:8 20 | # p x 21 | 2 22 | # help 23 | Type 'help ' for help on a specific command 24 | 25 | Available commands: 26 | backtrace delete edit frame list ps restart source undisplay 27 | break disable enable help method putl save thread up 28 | catch display eval info p quit set tmate var 29 | condition down exit irb pp reload show trace where 30 | 31 | # quit 32 | -------------------------------------------------------------------------------- /test/data/post-mortem.right: -------------------------------------------------------------------------------- 1 | pm.rb:3 2 | def zero_div 3 | # # *************************************************** 4 | # # This tests post-mortem handling. 5 | # # *************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # continue 9 | pm.rb:5 10 | 1/0 11 | # # Should have got a divide by 0 error 12 | # info program 13 | The program crashed. 14 | Exception: # 15 | # where 16 | --> #0 / at line pm.rb:5 17 | #1 at line pm.rb:8 18 | # up 19 | #1 at line pm.rb:8 20 | # p x 21 | 2 22 | # help 23 | Type 'help ' for help on a specific command 24 | 25 | Available commands: 26 | backtrace delete enable info p reload source var 27 | break disable eval irb pp restart thread where 28 | catch display exit kill ps save trace 29 | condition down frame list putl set undisplay 30 | continue edit help method quit show up 31 | 32 | # quit 33 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/reload.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | # Implements debugger "reload" command. 3 | class ReloadCommand < Command 4 | self.allow_in_control = true 5 | 6 | register_setting_get(:reload_source_on_change) do 7 | Debugger.reload_source_on_change 8 | end 9 | register_setting_set(:reload_source_on_change) do |value| 10 | Debugger.reload_source_on_change = value 11 | end 12 | 13 | def regexp 14 | /^\s*r(?:eload)?$/ 15 | end 16 | 17 | def execute 18 | Debugger.source_reload 19 | print "Source code is reloaded. Automatic reloading is #{source_reloading}.\n" 20 | end 21 | 22 | private 23 | 24 | def source_reloading 25 | Debugger.reload_source_on_change ? 'on' : 'off' 26 | end 27 | 28 | class << self 29 | def help_command 30 | 'reload' 31 | end 32 | 33 | def help(cmd) 34 | %{ 35 | r[eload]\tforces source code reloading 36 | } 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/quit.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | 3 | # Implements debugger "quit" command 4 | class QuitCommand < Command 5 | self.allow_in_control = true 6 | 7 | def regexp 8 | / ^\s* 9 | (?:q(?:uit)?|exit) \s* 10 | (!|\s+unconditionally)? \s* 11 | $ 12 | /ix 13 | end 14 | 15 | def execute 16 | if @match[1] or confirm("Really quit? (y/n) ") 17 | @state.interface.finalize 18 | exit! # exit -> exit!: No graceful way to stop threads... 19 | end 20 | end 21 | 22 | class << self 23 | def help_command 24 | %w[quit exit] 25 | end 26 | 27 | def help(cmd) 28 | %{ 29 | q[uit] [!|unconditionally]\texit from debugger. 30 | exit[!]\talias to quit 31 | 32 | Normally we prompt before exiting. However if the parameter 33 | "unconditionally" or is given or suffixed with !, we stop 34 | without asking further questions. 35 | } 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /test/test-jump.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test jump command 8 | class TestJumpCommand < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='jump' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./#{testname}.rb")) 23 | end 24 | end 25 | 26 | def test_basic_2 27 | testname='jump2' 28 | Dir.chdir(@@SRC_DIR) do 29 | script = File.join('data', testname + '.cmd') 30 | assert_equal(true, 31 | run_debugger(testname, 32 | "--script #{script} -- ./#{testname}.rb")) 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/tmate.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | if RUBY_PLATFORM =~ /darwin/ 3 | class TextMateCommand < Command # :nodoc: 4 | def regexp 5 | /^\s*tm(?:ate)?(?:\s*(\d+))?$/ 6 | end 7 | 8 | def execute 9 | if @match[1] 10 | frm_n = @match[1].to_i 11 | if frm_n > @state.context.stack_size || frm_n == 0 12 | print "Wrong frame number\n" 13 | return 14 | end 15 | file, line = @state.context.frame_file(frm_n-1), @state.context.frame_line(frm_n-1) 16 | else 17 | file, line = @state.file, @state.line 18 | end 19 | %x|open 'txmt://open?url=file://#{File.expand_path(file)}&line=#{line}'| 20 | end 21 | 22 | class << self 23 | def help_command 24 | 'tmate' 25 | end 26 | 27 | def help(cmd) 28 | %{ 29 | tm[ate] n\topens a current file in TextMate. 30 | \t\tIt uses n-th frame if arg (n) is specifed. 31 | } 32 | end 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /test/test-finish.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # require 'rubygems' 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test finish command 8 | class TestFinish < Test::Unit::TestCase 9 | 10 | @@src_dir = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@src_dir) 12 | 13 | require File.join(@@src_dir, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='finish' 18 | # Ruby 1.8.6 and earlier have a trace-line number bug for return 19 | # statements. 20 | # filter = Proc.new{|got_lines, correct_lines| 21 | # [got_lines[31], got_lines[34]].flatten.each do |s| 22 | # s.sub!(/gcd.rb:\d+/, 'gcd.rb:13') 23 | # end 24 | # got_lines[32] = 'return a' 25 | # } 26 | Dir.chdir(@@src_dir) do 27 | script = File.join('data', testname + '.cmd') 28 | assert_equal(true, 29 | run_debugger(testname, 30 | "--script #{script} -- ./gcd.rb 3 5", 31 | nil, nil)) 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /test/test-method.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # require 'rubygems' 5 | # require 'ruby-debug'; Debugger.start(:post_mortem => true) 6 | 7 | class TestMethod < Test::Unit::TestCase 8 | 9 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 10 | defined?(@@SRC_DIR) 11 | 12 | require File.join(@@SRC_DIR, 'helper') 13 | include TestHelper 14 | 15 | def test_basic 16 | testname='method' 17 | Dir.chdir(@@SRC_DIR) do 18 | script = File.join('data', testname + '.cmd') 19 | assert_equal(true, 20 | run_debugger(testname, 21 | "--script #{script} -- ./classes.rb")) 22 | begin 23 | require 'methodsig' 24 | testname='methodsig' 25 | script = File.join('data', testname + '.cmd') 26 | assert_equal(true, 27 | run_debugger(testname, 28 | "--script #{script} -- ./classes.rb")) 29 | rescue LoadError 30 | puts "Skipping method sig test" 31 | end 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /test/data/next.right: -------------------------------------------------------------------------------- 1 | next.rb:1 2 | def foo 3 | # # ******************************************************** 4 | # # This tests next command and break at proc def 5 | # # ******************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # set callstyle last 9 | Frame call-display style is last. 10 | # set force off 11 | force-stepping is off. 12 | # break 1 13 | Breakpoint 1 file ./next.rb, line 1 14 | # next 15 | next.rb:7 16 | a = 1 17 | # next 18 | next.rb:8 19 | if a == 1 20 | # next 21 | next.rb:9 22 | a += 2 23 | # next 24 | next.rb:10 25 | puts a 26 | # next 27 | 3 28 | next.rb:12 29 | foo 30 | # next 31 | Breakpoint 1 at next.rb:1 32 | next.rb:1 33 | def foo 34 | # next 35 | next.rb:2 36 | a = 1 37 | # next 38 | next.rb:3 39 | puts "Stop here" 40 | # next 41 | Stop here 42 | next.rb:4 43 | b = 2 44 | # next 45 | next.rb:13 46 | b = 2 47 | # next 48 | next.rb:14 49 | b += 2 50 | # next 51 | next.rb:15 52 | puts "one" 53 | # next 54 | one 55 | next.rb:16 56 | c = 4 57 | # next 58 | next.rb:17 59 | puts "two" 60 | # next 61 | two 62 | -------------------------------------------------------------------------------- /test/test-break-bad.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test (mostly) invalid breakpoint commands 8 | class TestBadBreak < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='break_bad' 18 | Dir.chdir(@@SRC_DIR) do 19 | script = File.join('data', testname + '.cmd') 20 | assert_equal(true, 21 | run_debugger(testname, 22 | "--script #{script} -- ./gcd.rb 3 5")) 23 | end 24 | end 25 | 26 | def test_break_loop 27 | testname='break_loop_bug' 28 | Dir.chdir(@@SRC_DIR) do 29 | script = File.join('data', testname + '.cmd') 30 | # FIXME: Issue #1 31 | # assert_equal(true, 32 | # run_debugger(testname, 33 | # "--script #{script} -- ./bp_loop_issue.rb")) 34 | end 35 | end 36 | 37 | end 38 | -------------------------------------------------------------------------------- /test/test-frame.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # require 'rubygems' 5 | # require 'ruby-debug'; Debugger.start(:post_mortem => true) 6 | 7 | # Test frame commands 8 | class TestFrame < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | # Test commands in frame.rb 17 | def test_basic 18 | testname='frame' 19 | # Ruby 1.8.6 and earlier have a trace-line number bug for return 20 | # statements. 21 | filter = Proc.new{|got_lines, correct_lines| 22 | [got_lines[11], correct_lines[11]].flatten.each do |s| 23 | s.sub!(/in file ".*gcd.rb/, 'in file "gcd.rb') 24 | end 25 | } 26 | Dir.chdir(@@SRC_DIR) do 27 | script = File.join('data', testname + '.cmd') 28 | assert_equal(true, 29 | run_debugger(testname, 30 | "--script #{script} -- ./gcd.rb 3 5", 31 | nil, filter)) 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/continue.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | 3 | # Implements debugger "continue" command. 4 | class ContinueCommand < Command 5 | self.allow_in_post_mortem = true 6 | self.need_context = false 7 | def regexp 8 | /^\s* c(?:ont(?:inue)?)? (?:\s+(.*))? $/x 9 | end 10 | 11 | def execute 12 | if @match[1] && !@state.context.dead? 13 | filename = File.expand_path(@state.file) 14 | line_number = get_int(@match[1], "Continue", 0, nil, 0) 15 | return unless line_number 16 | unless LineCache.trace_line_numbers(filename).member?(line_number) 17 | errmsg("Line %d is not a stopping point in file \"%s\".\n", 18 | line_number, filename) 19 | return 20 | end 21 | @state.context.set_breakpoint(filename, line_number) 22 | end 23 | @state.proceed 24 | end 25 | 26 | class << self 27 | def help_command 28 | 'continue' 29 | end 30 | 31 | def help(cmd) 32 | %{ 33 | c[ont[inue]][ nnn]\trun until program ends, hits a breakpoint or reaches line nnn 34 | } 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /test/data/catch3.right: -------------------------------------------------------------------------------- 1 | pm-catch3.rb:3 2 | def get_exception(arg) 3 | # # *************************************************** 4 | # # Test catch 5 | # # *************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # set autoeval off 9 | autoeval is off. 10 | # set basename on 11 | basename is on. 12 | # c 13 | divide by zero 14 | start1:foo begin:bar begin:foo ensure:zero_div rescue: 15 | Catchpoint at pm-catch3.rb:15: `divided by 0' (ZeroDivisionError) 16 | from tdebug.rb:61:in `debug_program' 17 | from tdebug.rb:247:in `' 18 | from ../rdbg.rb:23:in `load' 19 | from ../rdbg.rb:23:in `runner' 20 | from ../rdbg.rb:32:in `
' 21 | pm-catch3.rb:15 22 | 1/0 if arg 23 | # w 24 | --> #0 Object.bar(arg#Fixnum) at line pm-catch3.rb:15 25 | #1 at line pm-catch3.rb:34 26 | #2 Object.foo(arg#Fixnum) at line pm-catch3.rb:24 27 | #3 Object.zero_div(arg#Fixnum) at line pm-catch3.rb:34 28 | #4 at line pm-catch3.rb:45 29 | # p $var 30 | "start2:foo begin:bar begin:" 31 | # jump +4 32 | pm-catch3.rb:19 33 | $var = $var + "bar end:" 34 | # c 35 | 7 36 | start2:foo begin:bar begin:bar end:foo end:foo ensure: 37 | done 38 | -------------------------------------------------------------------------------- /emacs/test/test-gud.el: -------------------------------------------------------------------------------- 1 | ;; -*- emacs-lisp -*- 2 | ;; This program has to be run from the directory it is currently in and 3 | ;; the rdebug code has to be in the parent directory 4 | (load-file "./elk-test.el") 5 | 6 | (setq load-path (cons ".." load-path)) 7 | (require 'rdebug-gud) 8 | (setq load-path (cdr load-path)) 9 | 10 | (defun y-or-n-p (prompt) 11 | "Replacement of y-or-n-p() for rdebug testing" 12 | (assert-nil "y-or-n-p should not have been called")) 13 | 14 | (defun error (msg) 15 | "Replacement error() for rdebug testing" 16 | (assert-nil "error should not have been called")) 17 | 18 | ;; ------------------------------------------------------------------- 19 | 20 | (deftest "test-rdebug-find-file" 21 | ;; Set to cause a warning in find-file-no-select and 22 | ;; check that it is ignored. 23 | (let ((large-file-warning-threshold 1)) 24 | (gud-rdebug-find-file "elk-test.el"))) 25 | 26 | 27 | ;; ------------------------------------------------------------------- 28 | ;; Build and run the test suite. 29 | ;; 30 | 31 | (build-suite "rdebug-gud-suite" 32 | "test-rdebug-find-file") 33 | 34 | (run-elk-test "rdebug-gud-suite" 35 | "test some rdebug-gud code") 36 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/kill.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | 3 | # Implements debugger "kill" command 4 | class KillCommand < Command 5 | self.allow_in_control = true 6 | 7 | def regexp 8 | / ^\s* 9 | (?:kill) \s* 10 | (?:\s+(\S+))?\s* 11 | $ 12 | /ix 13 | end 14 | 15 | def execute 16 | puts @match[1] 17 | if @match[1] 18 | signame = @match[1] 19 | unless Signal.list.member?(signame) 20 | errmsg("signal name #{signame} is not a signal I know about\n") 21 | return false 22 | end 23 | if 'KILL' == signame 24 | @state.interface.finalize 25 | end 26 | else 27 | if not confirm("Really kill? (y/n) ") 28 | return 29 | else 30 | signame = 'KILL' 31 | end 32 | end 33 | Process.kill(signame, Process.pid) 34 | end 35 | 36 | class << self 37 | def help_command 38 | %w[kill] 39 | end 40 | 41 | def help(cmd) 42 | %{ 43 | kill [SIGNAL] 44 | 45 | Send [signal] to Process.pid 46 | Equivalent of Process.kill(Process.pid) 47 | } 48 | end 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /test/base/load.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # Test of Debugger.debug_load in C extension ruby_debug.so 5 | class TestDebugLoad < Test::Unit::TestCase 6 | 7 | @@src_dir = File.dirname(__FILE__) 8 | $:.unshift File.join(@@src_dir, '..', '..', 'ext') 9 | require 'ruby_debug' 10 | $:.shift 11 | 12 | class << self 13 | def at_line(file, line) 14 | @@at_line = [File.basename(file), line] 15 | end 16 | end 17 | 18 | Debugger::PROG_SCRIPT = File.join(@@src_dir, '..', 'gcd.rb') 19 | 20 | class Debugger::Context 21 | def at_line(file, line) 22 | TestDebugLoad::at_line(file, line) 23 | end 24 | end 25 | 26 | def test_debug_load 27 | # Without stopping 28 | bt = Debugger.debug_load(Debugger::PROG_SCRIPT, false) 29 | assert_equal(nil, bt) 30 | # With stopping 31 | bt = Debugger.debug_load(Debugger::PROG_SCRIPT, true) 32 | assert_equal(nil, bt) 33 | assert_equal(['gcd.rb', 4], @@at_line) 34 | 35 | # Test that we get a proper backtrace on a script that raises 'abc' 36 | prog_script = File.join(@@src_dir, '..', 'raise.rb') 37 | bt = Debugger.debug_load(prog_script, false) 38 | assert_equal(bt.to_s, 'abc') 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /test/data/display.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # *************************************************** 4 | # # This tests display expressions. 5 | # # *************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # b 6 9 | Breakpoint 1 file ./gcd.rb, line 6 10 | # c 11 | Breakpoint 1 at gcd.rb:6 12 | gcd.rb:6 13 | if a > b 14 | # # Should be no display expression yet. 15 | # info display 16 | There are no auto-display expressions now. 17 | # display a 18 | 1: a = 3 19 | # display b 20 | 2: b = 5 21 | # disable display b 22 | Disable display argument 'b' needs to be a number. 23 | # disable display 1 24 | # c 25 | Breakpoint 1 at gcd.rb:6 26 | 2: b = 3 27 | gcd.rb:6 28 | if a > b 29 | # enable display b 30 | Enable display argument 'b' needs to be a number. 31 | # enable display 1 32 | # undisplay a 33 | Undisplay argument 'a' needs to be a number. 34 | # undisplay 2 35 | # # Should have only one display expression. 36 | # info display 37 | Auto-display expressions now in effect: 38 | Num Enb Expression 39 | 1: y a 40 | # undisplay 1 41 | # # Now we have no more display expressions. 42 | # info display 43 | There are no auto-display expressions now. 44 | # q 45 | -------------------------------------------------------------------------------- /test/info-var-bug.rb: -------------------------------------------------------------------------------- 1 | class Lousy_inspect 2 | attr_accessor :var 3 | def inspect # An unhelpful inspect 4 | throw "Foo" # Raises an exception 5 | end 6 | def initialize 7 | @var = 'initialized' 8 | end 9 | end 10 | class Lousy_inspect_and_to_s 11 | attr_accessor :var 12 | def inspect # An unhelpful inspect 13 | throw "Foo" # Raises an exception 14 | end 15 | def to_s # An unhelpful to_s 16 | throw "bar" # Raises an exception 17 | end 18 | def initialize 19 | @var = 'initialized' # Something to inspect 20 | end 21 | end 22 | 23 | # Something that will be passed objects with 24 | # bad inspect or to_s methods 25 | class UnsuspectingClass 26 | @@Const = 'A constant' 27 | @@var = 'a class variable' 28 | def initialize(a) 29 | @a = a # "info locals" will try to use 30 | # inspect or to_s here 31 | @b = 5 32 | end 33 | end 34 | def test_Lousy_inspect 35 | x = Lousy_inspect.new 36 | x 37 | end 38 | def test_lousy_inspect_and_to_s 39 | x = Lousy_inspect_and_to_s.new 40 | x 41 | end 42 | x = test_Lousy_inspect 43 | y = test_lousy_inspect_and_to_s 44 | UnsuspectingClass.new(10) 45 | UnsuspectingClass.new(x) 46 | UnsuspectingClass.new(y) 47 | y = 2 48 | -------------------------------------------------------------------------------- /test/data/stepping.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # *************************************************** 4 | # # This tests step, next, finish and continue 5 | # # *************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # set callstyle last 9 | Frame call-display style is last. 10 | # next 11 | gcd.rb:18 12 | gcd(3,5) 13 | # where 14 | --> #0 at line gcd.rb:18 15 | # step a 16 | Step argument 'a' needs to be a number. 17 | # set forcestep on 18 | force-stepping is on. 19 | # step- ; step- 20 | gcd.rb:6 21 | if a > b 22 | # set forcestep off 23 | force-stepping is off. 24 | # where 25 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 26 | #1 at line gcd.rb:18 27 | # next 28 | gcd.rb:10 29 | return nil if a <= 0 30 | # step+ 31 | gcd.rb:12 32 | if a == 1 or b-a == 0 33 | # where 34 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:12 35 | #1 at line gcd.rb:18 36 | # step 3 37 | gcd.rb:10 38 | return nil if a <= 0 39 | # step+ 40 | gcd.rb:12 41 | if a == 1 or b-a == 0 42 | # where 43 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:12 44 | #1 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:15 45 | #2 at line gcd.rb:18 46 | # next+ 47 | gcd.rb:15 48 | gcd(b-a, a) 49 | # # finish 50 | # quit 51 | -------------------------------------------------------------------------------- /test/data/enable.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # ******************************************************** 4 | # # This tests the enable command. 5 | # # ******************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # set callstyle last 9 | Frame call-display style is last. 10 | # set autoeval off 11 | autoeval is off. 12 | # break Object.gcd 13 | Breakpoint 1 at Object::gcd 14 | # # Should have a breakpoint 1 15 | # enable br 1 16 | # # Get help on enable 17 | # help enable 18 | Enable some things. 19 | This is used to cancel the effect of the "disable" command. 20 | -- 21 | List of enable subcommands: 22 | -- 23 | enable breakpoints -- Enable specified breakpoints 24 | enable display -- Enable some expressions to be displayed when program stops 25 | # # Get help on just enable break 26 | # help enable break 27 | Enable specified breakpoints. 28 | Give breakpoint numbers (separated by spaces) as arguments. 29 | This is used to cancel the effect of the "disable" command. 30 | # # Plain enable should work 31 | # enable 32 | *** "enable" must be followed "display", "breakpoints" or breakpoint numbers. 33 | # # An invalid enable command 34 | # enable foo 35 | Enable breakpoints argument 'foo' needs to be a number. 36 | # quit 37 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/finish.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | # Implements the debugger 'finish' command. 3 | class FinishCommand < Command 4 | self.allow_in_post_mortem = false 5 | self.need_context = true 6 | 7 | def regexp 8 | /^\s*fin(?:ish)? (?:\s+(.*))?$/x 9 | end 10 | 11 | def execute 12 | max_frame = @state.context.stack_size - @state.frame_pos 13 | if !@match[1] or @match[1].empty? 14 | frame_pos = @state.frame_pos 15 | else 16 | frame_pos = get_int(@match[1], "Finish", 0, max_frame-1, 0) 17 | return nil unless frame_pos 18 | end 19 | @state.context.stop_frame = frame_pos 20 | @state.frame_pos = 0 21 | @state.proceed 22 | end 23 | 24 | class << self 25 | def help_command 26 | 'finish' 27 | end 28 | 29 | def help(cmd) 30 | %{ 31 | fin[ish] [frame-number]\tExecute until selected stack frame returns. 32 | 33 | If no frame number is given, we run until the currently selected frame 34 | returns. The currently selected frame starts out the most-recent 35 | frame or 0 if no frame positioning (e.g "up", "down" or "frame") has 36 | been performed. If a frame number is given we run until that frame 37 | returns. 38 | } 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /test/test-trace.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test tracing 8 | class TestTrace < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_trace_option 17 | 18 | filter = Proc.new{|got_lines, correct_lines| 19 | got_lines.collect!{|l| l !~ /:gcd\.rb:/? l : nil}.compact! 20 | } 21 | 22 | testname='trace' 23 | Dir.chdir(@@SRC_DIR) do 24 | assert_equal(true, 25 | run_debugger(testname, 26 | "-nx --trace ./gcd.rb 3 5", nil, filter)) 27 | end 28 | end 29 | 30 | def test_linetrace_command 31 | 32 | filter = Proc.new{|got_lines, correct_lines| 33 | got_lines.collect!{|l| l !~ /:rdbg\.rb:/? l : nil}.compact! 34 | } 35 | 36 | testname='linetrace' 37 | Dir.chdir(@@SRC_DIR) do 38 | script = File.join('data', testname + '.cmd') 39 | assert_equal(true, 40 | run_debugger(testname, 41 | "--script #{script} -- ./gcd.rb 3 5", nil, 42 | filter)) 43 | 44 | end 45 | end 46 | 47 | end 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2005 Kent Sibilev 2 | All rights reserved. 3 | * 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * 13 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 | SUCH DAMAGE. -------------------------------------------------------------------------------- /test/cli/commands/unit/regexp.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | 3 | 4 | class TestCommandREs < Test::Unit::TestCase 5 | base_dir=File.expand_path(File.join(File.dirname(__FILE__), 6 | '..', '..', '..', '..', 7 | 'cli', 'ruby-debug')) 8 | require File.join(base_dir, 'command') 9 | require File.join(base_dir, 'commands', 'frame') 10 | include Debugger 11 | 12 | def test_quit 13 | c = QuitCommand.new(nil) 14 | assert c.regexp.match('quit') 15 | assert c.regexp.match('q') 16 | assert c.regexp.match('quit!') 17 | assert c.regexp.match('q!') 18 | assert c.regexp.match('quit unconditionally') 19 | assert c.regexp.match('exit') 20 | assert c.regexp.match('exit!') 21 | end 22 | 23 | def test_up 24 | c = UpCommand.new(nil) 25 | assert c.regexp.match('up') 26 | assert c.regexp.match('up 2') 27 | assert c.regexp.match('up 2+5') 28 | assert c.regexp.match('u') 29 | assert c.regexp.match('u 2') 30 | assert_equal nil, c.regexp.match('ufoo') 31 | end 32 | 33 | def test_down 34 | c = DownCommand.new(nil) 35 | assert c.regexp.match('down') 36 | assert c.regexp.match('down 2') 37 | assert_equal(nil, c.regexp.match('d 2')) 38 | assert_equal(nil, c.regexp.match('d')) 39 | assert_equal(nil, c.regexp.match('dow')) 40 | end 41 | end 42 | 43 | -------------------------------------------------------------------------------- /test/data/info-thread.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # ******************************************************** 4 | # # This tests basic info thread commands 5 | # set debuggertesting on 6 | Currently testing the debugger is on. 7 | # set callstyle last 8 | Frame call-display style is last. 9 | # set autoeval off 10 | autoeval is off. 11 | # info threads terse 12 | + 1 # ./gcd.rb:4 13 | # info threads ver 14 | + 1 # 15 | #0 at line gcd.rb:4 16 | # info thread 1 t 17 | + 1 # ./gcd.rb:4 18 | # info threads 19 | + 1 # ./gcd.rb:4 20 | # info thread 21 | + 1 # ./gcd.rb:4 22 | # help info thread 23 | List info about thread NUM. 24 | 25 | If no thread number is given, we list info for all threads. 'terse' and 'verbose' 26 | options are possible. If terse, just give summary thread name information. See 27 | "help info threads" for more detail about this summary information. 28 | 29 | If 'verbose' appended to the end of the command, then the entire 30 | stack trace is given for each thread. 31 | # help info threads 32 | information of currently-known threads. 33 | 34 | This information includes whether the thread is current (+), if it is 35 | suspended ($), or ignored (!). The thread number and the top stack 36 | item. If 'verbose' is given then the entire stack frame is shown. 37 | # q 38 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/edit.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | class Edit < Command # :nodoc: 3 | self.allow_in_control = true 4 | def regexp 5 | /^\s* ed(?:it)? (?:\s+(.*))?$/ix 6 | end 7 | 8 | def execute 9 | if not @match[1] or @match[1].strip.empty? 10 | unless @state.context 11 | errmsg "We are not in a state that has an associated file.\n" 12 | return 13 | end 14 | file = @state.file 15 | line_number = @state.line 16 | elsif @pos_match = /([^:]+)[:]([0-9]+)/.match(@match[1]) 17 | file, line_number = @pos_match.captures 18 | else 19 | errmsg "Invalid file/line number specification: #{@match[1]}\n" 20 | return 21 | end 22 | editor = ENV['EDITOR'] || 'ex' 23 | if File.readable?(file) 24 | system("#{editor} +#{line_number} #{file}") 25 | else 26 | errmsg "File \"#{file}\" is not readable.\n" 27 | end 28 | end 29 | 30 | class << self 31 | def help_command 32 | 'edit' 33 | end 34 | 35 | def help(cmd) 36 | %{ 37 | Edit specified file. 38 | 39 | With no argument, edits file containing most recent line listed. 40 | Editing targets can also be specified in this: 41 | FILE:LINENUM, to edit at that line in that file, 42 | } 43 | end 44 | end 45 | end 46 | 47 | 48 | end # module Debugger 49 | -------------------------------------------------------------------------------- /test/test-dollar-0.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test --no-stop and $0 setting. 8 | class TestDollar0 < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_basic 17 | testname='breakpoints' 18 | Dir.chdir(@@SRC_DIR) do 19 | home_save = ENV['HOME'] 20 | ENV['HOME'] = '.' 21 | filter = Proc.new{|got_lines, correct_lines| 22 | [got_lines, correct_lines].flatten.each do |s| 23 | s.gsub!(/.*dollar-0.rb$/, 'dollar-0.rb') 24 | end 25 | } 26 | 27 | assert_equal(true, 28 | run_debugger('dollar-0', 29 | '-nx --no-stop ./dollar-0.rb', 30 | nil, filter, false, '../bin/rdebug')) 31 | # Ruby's __FILE__ seems to prepend ./ when no directory was added. 32 | assert_equal(true, 33 | run_debugger('dollar-0b', 34 | '-nx --no-stop ' + 35 | File.join('..', 'test', 'dollar-0.rb'), 36 | nil, filter, false, '../bin/rdebug')) 37 | ENV['HOME'] = home_save 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /test/data/catch.right: -------------------------------------------------------------------------------- 1 | pm-catch.rb:3 2 | def zero_div 3 | # # *************************************************** 4 | # # Test catch 5 | # # *************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # set autoeval off 9 | autoeval is off. 10 | # set basename on 11 | basename is on. 12 | # info catch 13 | No exceptions set to be caught. 14 | # catch ZeroDivisionError off 15 | *** Catch for exception ZeroDivisionError not found. 16 | # catch ZeroDivisionError off afdasdf 17 | *** Unknown command: "catch ZeroDivisionError off afdasdf". Try "help". 18 | # catch ZeroDivisionError 19 | Catch exception ZeroDivisionError. 20 | # info catch 21 | ZeroDivisionError 22 | # catch ZeroDivisionError off 23 | Catch for exception ZeroDivisionError removed. 24 | # info catch 25 | No exceptions set to be caught. 26 | # catch ZeroDivisionError 27 | Catch exception ZeroDivisionError. 28 | # c 29 | Catchpoint at pm-catch.rb:5: `divided by 0' (ZeroDivisionError) 30 | from ../rdbg.rb:23:in `runner' 31 | from ../rdbg.rb:32:in `
' 32 | pm-catch.rb:5 33 | 1/0 34 | # where 35 | --> #0 Object.zero_div at line pm-catch.rb:5 36 | #1 at line pm-catch.rb:9 37 | # jump 6 38 | pm-catch.rb:6 39 | x = 6 40 | # cont 41 | 6 42 | Catchpoint at pm-catch.rb:10: `RuntimeError' (RuntimeError) 43 | from ../rdbg.rb:32:in `
' 44 | pm-catch.rb:10 45 | raise RuntimeError 46 | # jump 11 47 | pm-catch.rb:11 48 | x = 3 49 | # cont 50 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/condition.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | 3 | class ConditionCommand < Command # :nodoc: 4 | 5 | def regexp 6 | /^\s* cond(?:ition)? (?:\s+(\d+)\s*(.*))?$/ix 7 | end 8 | 9 | def execute 10 | if not @match[1] 11 | errmsg "\"condition\" must be followed a breakpoint number and expression\n" 12 | else 13 | breakpoints = Debugger.breakpoints.sort_by{|b| b.id } 14 | largest = breakpoints.inject(0) do |tally, b| 15 | tally = b.id if b.id > tally 16 | end 17 | if 0 == largest 18 | print "No breakpoints have been set.\n" 19 | return 20 | end 21 | pos = get_int(@match[1], "Condition", 1, largest) 22 | return unless pos 23 | breakpoints.each do |b| 24 | if b.id == pos 25 | b.expr = @match[2].empty? ? nil : @match[2] 26 | break 27 | end 28 | end 29 | 30 | end 31 | end 32 | 33 | class << self 34 | def help_command 35 | 'condition' 36 | end 37 | 38 | def help(cmd) 39 | %{ 40 | Condition breakpoint-number expression 41 | Specify breakpoint number N to break only if COND is true. 42 | N is an integer and COND is an expression to be evaluated whenever 43 | breakpoint N is reached. If the empty string is used, the condition is removed. 44 | } 45 | end 46 | end 47 | end 48 | 49 | end # module Debugger 50 | -------------------------------------------------------------------------------- /test/data/setshow.cmd: -------------------------------------------------------------------------------- 1 | # This tests the functioning of some set/show debugger commands 2 | set debuggertesting on 3 | ### ******************************* 4 | ### *** Set/show commands *** 5 | ### ******************************* 6 | ######################################## 7 | ### test args and baseneme... 8 | ######################################## 9 | set args this is a test 10 | show args 11 | show basename 12 | set basename foo 13 | show base 14 | set basename off 15 | show basename 16 | set basename 0 17 | show basename 18 | set basename 1 19 | show basename 20 | ######################################## 21 | ### test listsize tests... 22 | ######################################## 23 | show listsize 24 | show listsi 25 | set listsize abc 26 | set listsize -20 27 | ######################################## 28 | ### test linetrace... 29 | ######################################## 30 | set linetrace on 31 | show linetrace 32 | set linetrace off 33 | show linetrace 34 | ######################################## 35 | ### show history 36 | ######################################## 37 | set history 38 | set history size 10 39 | show history size 40 | set history save off 41 | show history save 42 | set history save 1 43 | show history save 44 | #### Test 'autoeval'... 45 | set autoeval on 46 | puts 'printed via autoeval' 47 | set autoeval off 48 | puts 'autoeval should not run this' 49 | #### Test 'callstyle'... 50 | set callstyle 51 | set callstyle short 52 | set callstyle last 53 | set callstyle tracked 54 | set callstyle foo 55 | 56 | 57 | -------------------------------------------------------------------------------- /ext/ruby_debug/extconf.rb: -------------------------------------------------------------------------------- 1 | require "mkmf" 2 | require "ruby_core_source" 3 | 4 | if RUBY_VERSION < "1.9" 5 | STDERR.print("Ruby version is too old\n") 6 | exit(1) 7 | end 8 | 9 | hdrs = lambda { 10 | iseqs = %w[vm_core.h iseq.h] 11 | return false unless begin 12 | have_struct_member("rb_method_entry_t", "called_id", "method.h") or 13 | have_struct_member("rb_control_frame_t", "method_id", "method.h") 14 | end && 15 | have_header("vm_core.h") && have_header("iseq.h") && have_header("insns.inc") && 16 | have_header("insns_info.inc") && have_header("eval_intern.h") 17 | return false unless have_type("struct iseq_line_info_entry", iseqs) || 18 | have_type("struct iseq_insn_info_entry", iseqs) 19 | if checking_for(checking_message("if rb_iseq_compile_with_option was added an argument filepath")) do 20 | try_compile(< 22 | #include "vm_core.h" 23 | extern VALUE rb_iseq_new_main(NODE *node, VALUE filename, VALUE filepath); 24 | SRC 25 | end 26 | $defs << '-DRB_ISEQ_COMPILE_5ARGS' 27 | end 28 | } 29 | 30 | dir_config("ruby") 31 | if !Ruby_core_source::create_makefile_with_core(hdrs, "ruby_debug") 32 | STDERR.print("Makefile creation failed\n") 33 | STDERR.print("*************************************************************\n\n") 34 | STDERR.print(" NOTE: For Ruby 1.9 installation instructions, please see:\n\n") 35 | STDERR.print(" http://wiki.github.com/mark-moseley/ruby-debug\n\n") 36 | STDERR.print("*************************************************************\n\n") 37 | exit(1) 38 | end 39 | -------------------------------------------------------------------------------- /test/test-info-var.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test info variables command 8 | class TestInfoVar < Test::Unit::TestCase 9 | 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | 13 | require File.join(@@SRC_DIR, 'helper') 14 | include TestHelper 15 | 16 | def test_info_variables 17 | 18 | Dir.chdir(@@SRC_DIR) do 19 | 20 | filter = Proc.new{|got_lines, correct_lines| 21 | [got_lines[13-1], correct_lines[13-1]].each do |s| 22 | s.sub!(/Mine:0x[0-9,a-f]+/, 'Mine:') 23 | end 24 | [got_lines, correct_lines].each do |a| 25 | a.each do |s| 26 | s.sub!(/Lousy_inspect:0x[0-9,a-f]+/, 'Lousy_inspect:') 27 | s.sub!(/UnsuspectingClass:0x[0-9,a-f]+/, 'UnsuspectingClass:') 28 | end 29 | end 30 | } 31 | 32 | testname='info-var' 33 | script = File.join('data', testname + '.cmd') 34 | assert_equal(true, 35 | run_debugger(testname, 36 | "--script #{script} -- ./info-var-bug.rb", 37 | nil, filter)) 38 | testname='info-var-bug2' 39 | script = File.join('data', testname + '.cmd') 40 | assert_equal(true, 41 | run_debugger(testname, 42 | "--script #{script} -- ./info-var-bug2.rb", 43 | nil)) 44 | 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /test/data/info-var.right: -------------------------------------------------------------------------------- 1 | info-var-bug.rb:1 2 | class Lousy_inspect 3 | # # *************************************************** 4 | # # Test handling of info variables when we have 5 | # # redefined inspect or to_s which give an error. 6 | # # *************************************************** 7 | # set debuggertesting on 8 | Currently testing the debugger is on. 9 | # # Go to where we have a bad "inspect" of a local variable 10 | # continue 36 11 | info-var-bug.rb:36 12 | x 13 | # info variables 14 | self = main 15 | x = # 16 | # # Go to where we have a bad "inspect" and "to_s" of a local variable 17 | # continue 40 18 | info-var-bug.rb:40 19 | x 20 | # info variables 21 | self = main 22 | x = *Error in evaluation* 23 | # break 31 24 | Breakpoint 1 file ./info-var-bug.rb, line 31 25 | # # The first time through, we can do inspect. 26 | # continue 27 | Breakpoint 1 at info-var-bug.rb:31 28 | info-var-bug.rb:31 29 | @b = 5 30 | # info locals 31 | a = 10 32 | # # Now go to where we have a bad "inspect" of an class variable 33 | # continue 34 | Breakpoint 1 at info-var-bug.rb:31 35 | info-var-bug.rb:31 36 | @b = 5 37 | # info locals 38 | a = # 39 | # info variables 40 | a = # 41 | self = # 42 | @a = # 43 | @@Const = "A constant" 44 | @@var = "a class variable" 45 | # # Now go to where we have a bad "inspect" and "to_s" of an class variable 46 | # continue 47 | Breakpoint 1 at info-var-bug.rb:31 48 | info-var-bug.rb:31 49 | @b = 5 50 | # info locals 51 | *Error in evaluation* 52 | # quit 53 | -------------------------------------------------------------------------------- /test/test-init.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | require 'rbconfig' 4 | 5 | # begin require 'rubygems' rescue LoadError end 6 | # require 'ruby-debug'; Debugger.start 7 | 8 | # Test Debugger.init and setting up ruby-debug variables 9 | class TestDebuggerInit < Test::Unit::TestCase 10 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 11 | defined?(@@SRC_DIR) 12 | require File.join(@@SRC_DIR, 'helper') 13 | 14 | def test_basic 15 | debugger_output = 'test-init.out' 16 | Dir.chdir(@@SRC_DIR) do 17 | old_emacs = ENV['EMACS'] 18 | old_columns = ENV['COLUMNS'] 19 | ENV['EMACS'] = nil 20 | ENV['COLUMNS'] = '120' 21 | ruby = "#{TestHelper.load_ruby} #{TestHelper.load_params}" 22 | IO.popen("#{ruby} ./gcd-dbg.rb 5 >#{debugger_output}", 'w') do |pipe| 23 | pipe.puts 'p Debugger::PROG_SCRIPT' 24 | pipe.puts 'show args' 25 | pipe.puts 'quit unconditionally' 26 | end 27 | lines = File.open(debugger_output).readlines 28 | ENV['EMACS'] = old_emacs 29 | ENV['COLUMNS'] = old_columns 30 | 31 | right_file = case Config::CONFIG['host_os'] 32 | when /^darwin/ 33 | 'test-init-osx.right' 34 | when /^cygwin/ 35 | 'test-init-cygwin.right' 36 | else 37 | 'test-init.right' 38 | end 39 | expected = File.open(File.join('data', right_file)).readlines 40 | assert_equal(expected, lines) 41 | File.delete(debugger_output) if expected == lines 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /test/data/catch2.right: -------------------------------------------------------------------------------- 1 | pm-catch2.rb:3 2 | def bar(arg) 3 | # # *************************************************** 4 | # # Test catch 5 | # # *************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # set autoeval off 9 | autoeval is off. 10 | # set basename on 11 | basename is on. 12 | # catch ZeroDivisionError 13 | Catch exception ZeroDivisionError. 14 | # c 15 | foo begin 16 | bar begin 17 | Catchpoint at pm-catch2.rb:5: `divided by 0' (ZeroDivisionError) 18 | from tdebug.rb:61:in `debug_program' 19 | from tdebug.rb:247:in `' 20 | from ../rdbg.rb:23:in `load' 21 | from ../rdbg.rb:23:in `runner' 22 | from ../rdbg.rb:32:in `
' 23 | pm-catch2.rb:5 24 | 1/0 if arg 25 | # sk 26 | ok 27 | # break 27 28 | Breakpoint 1 file ./pm-catch2.rb, line 27 29 | # c 30 | rescue 31 | 15 32 | Breakpoint 1 at pm-catch2.rb:27 33 | pm-catch2.rb:27 34 | puts "done" 35 | # jump -1 36 | pm-catch2.rb:26 37 | puts zero_div(10) 38 | # break 4 39 | Breakpoint 2 file ./pm-catch2.rb, line 4 40 | # c 41 | foo begin 42 | Breakpoint 2 at pm-catch2.rb:4 43 | pm-catch2.rb:4 44 | puts "bar begin" 45 | # p arg = nil 46 | nil 47 | # c 48 | bar begin 49 | Catchpoint at pm-catch2.rb:6: `ZeroDivisionError' (ZeroDivisionError) 50 | from tdebug.rb:61:in `debug_program' 51 | from tdebug.rb:247:in `' 52 | from ../rdbg.rb:23:in `load' 53 | from ../rdbg.rb:23:in `runner' 54 | from ../rdbg.rb:32:in `
' 55 | pm-catch2.rb:6 56 | raise ZeroDivisionError 57 | # jump 7 58 | pm-catch2.rb:7 59 | puts "bar end" 60 | # del 1 61 | # c 62 | bar end 63 | foo end 64 | 15 65 | done 66 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/help.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | 3 | # Implements debugger "help" command. 4 | class HelpCommand < Command 5 | self.allow_in_control = true 6 | 7 | def regexp 8 | /^\s* h(?:elp)? (?:\s+(.+))? $/x 9 | end 10 | 11 | def execute 12 | if @match[1] 13 | args = @match[1].split 14 | cmds = @state.commands.select do |cmd| 15 | [cmd.help_command].flatten.include?(args[0]) 16 | end 17 | else 18 | args = @match[1] 19 | cmds = [] 20 | end 21 | unless cmds.empty? 22 | help = cmds.map{ |cmd| cmd.help(args) }.join 23 | help = help.split("\n").map{|l| l.gsub(/^ +/, '')} 24 | help.shift if help.first && help.first.empty? 25 | help.pop if help.last && help.last.empty? 26 | print help.join("\n") 27 | else 28 | if args and args[0] 29 | errmsg "Undefined command: \"#{args[0]}\". Try \"help\"." 30 | else 31 | print "ruby-debug help v#{Debugger::VERSION}\n" unless 32 | self.class.settings[:debuggertesting] 33 | print "Type 'help ' for help on a specific command\n\n" 34 | print "Available commands:\n" 35 | cmds = @state.commands.map{ |cmd| cmd.help_command } 36 | cmds = cmds.flatten.uniq.sort 37 | print columnize(cmds, self.class.settings[:width]) 38 | end 39 | end 40 | print "\n" 41 | end 42 | 43 | class << self 44 | def help_command 45 | 'help' 46 | end 47 | 48 | def help(cmd) 49 | %{ 50 | h[elp]\t\tprint this help 51 | h[elp] command\tprint help on command 52 | } 53 | end 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /doc/emacs-notes.txt: -------------------------------------------------------------------------------- 1 | * rdebug.el is loaded by the user when Emacs is launched. (Should 2 | Rdebug ever be part of Emacs, this should be the items autoloaded by 3 | Emacs.) 4 | 5 | There is a command buffer which is the gud process. There are a number 6 | of "secondary" buffers have in gud-comint-buffer the gud process. The 7 | way we go the other direction from gud process to secondary buffer is 8 | by buffer name. Source buffers don't seem to have a local 9 | gud-comint-buffer variable set but use the global value. Perhaps 10 | source buffer should have their own buffer-local value(s)? 11 | 12 | For each secondary buffer we have things for that specific buffer. In particular: 13 | * frames (rdebug-frames.el) 14 | * output (rdebug-output.el) 15 | * variables (rdebug-varbuf.el) 16 | * watch or display-expressions - (rdebug-watch.el 17 | * breakpoints (rdebug-breaks.el) 18 | 19 | Each specific secondary buffer includes 20 | - setting the buffer up, 21 | - specific commands for that buffer 22 | - the kinds of functions that buffer deals with (e.g. frame 23 | things for the "frame" buffer or breakpoints for the "breakpoints" buffer.) 24 | 25 | * rdebug-gud.el contains things that interface to gdb. Possibly also 26 | things that interface to gdb-ui should be there as well. 27 | 28 | * rdebug-shortkey.el has all the magic that needs to be done to make 29 | shortkey mode work. 30 | 31 | * rdebug-track is all the things to make rdebug-track mode work. 32 | 33 | I have some additions, which deals with *when* certain files are loaded. 34 | 35 | * rdebug-source.el is loaded when the first Ruby source file is loaded 36 | Of course, the name rdebug-source.el is not important, we could rename 37 | it to something else and reuse the name for other source-related 38 | things. 39 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/catchpoint.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | class CatchCommand < Command # :nodoc: 3 | self.allow_in_control = true 4 | 5 | def regexp 6 | /^\s* cat(?:ch)? 7 | (?:\s+ (\S+))? 8 | (?:\s+ (off))? \s* $/ix 9 | end 10 | 11 | def execute 12 | excn = @match[1] 13 | if not excn 14 | # No args given. 15 | info_catch 16 | elsif not @match[2] 17 | # One arg given. 18 | if 'off' == excn 19 | Debugger.catchpoints.clear if 20 | confirm("Delete all catchpoints? (y or n) ") 21 | else 22 | binding = @state.context ? get_binding : TOPLEVEL_BINDING 23 | unless debug_eval("#{excn}.is_a?(Class)", binding) 24 | print "Warning #{excn} is not known to be a Class\n" 25 | end 26 | Debugger.add_catchpoint(excn) 27 | print "Catch exception %s.\n", excn 28 | end 29 | elsif @match[2] != 'off' 30 | errmsg "Off expected. Got %s\n", @match[2] 31 | elsif Debugger.catchpoints.member?(excn) 32 | Debugger.catchpoints.delete(excn) 33 | print "Catch for exception %s removed.\n", excn 34 | else 35 | errmsg "Catch for exception %s not found.\n", excn 36 | end 37 | end 38 | 39 | class << self 40 | def help_command 41 | 'catch' 42 | end 43 | 44 | def help(cmd) 45 | %{ 46 | cat[ch]\t\tsame as "info catch" 47 | cat[ch] [on|off] 48 | \tIntercept when there would otherwise be no handler. 49 | \tWith an "on" or "off", turn handling the exception on or off. 50 | cat[ch] off\tdelete all catchpoints 51 | } 52 | end 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /test/data/frame.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # *************************************************** 4 | # # This tests step, next, finish and continue 5 | # # *************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # set callstyle last 9 | Frame call-display style is last. 10 | # # Invalid line number in continue command 11 | # continue 3 12 | *** Line 3 is not a stopping point in file "gcd.rb". 13 | # # This time, for sure! 14 | # continue 6 15 | gcd.rb:6 16 | if a > b 17 | # where 18 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 19 | #1 at line gcd.rb:18 20 | # up 21 | #1 at line gcd.rb:18 22 | # where 23 | #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 24 | --> #1 at line gcd.rb:18 25 | # down 26 | #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 27 | # where 28 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 29 | #1 at line gcd.rb:18 30 | # frame 31 | #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 32 | # where 33 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 34 | #1 at line gcd.rb:18 35 | # frame -1 36 | #1 at line gcd.rb:18 37 | # where 38 | #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 39 | --> #1 at line gcd.rb:18 40 | # up 2 41 | *** Adjusting would put us beyond the oldest (initial) frame. 42 | # where 43 | #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 44 | --> #1 at line gcd.rb:18 45 | # down 2 46 | *** Adjusting would put us beyond the newest (innermost) frame. 47 | # where 48 | #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 49 | --> #1 at line gcd.rb:18 50 | # frame 0 thread 3 51 | *** Thread 3 doesn't exist. 52 | # frame 0 thread 1 53 | #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 54 | # # finish 55 | # quit 56 | -------------------------------------------------------------------------------- /emacs/test/test-indent.el: -------------------------------------------------------------------------------- 1 | ;; -*- emacs-lisp -*- 2 | ;; This program has to be run from the directory it is currently in and 3 | ;; the rdebug code has to be in the parent directory 4 | (load-file "./elk-test.el") 5 | 6 | ;; ------------------------------------------------------------------- 7 | ;; Check source code indentation 8 | ;; 9 | 10 | (put 'rdebug-debug-enter 'lisp-indent-hook 1) 11 | 12 | (defun rdebug-test-reindent-one-file (file) 13 | (let ((buf (generate-new-buffer "testing")) 14 | (res nil)) 15 | (save-excursion 16 | (switch-to-buffer buf) 17 | (insert-file file) 18 | (emacs-lisp-mode) 19 | (set-buffer-modified-p nil) 20 | (undo-boundary) 21 | (indent-region (point-min) (point-max)) 22 | (if (buffer-modified-p) 23 | (setq res "Reindentation failed"))) 24 | (kill-buffer buf) 25 | res)) 26 | 27 | (deftest "rdebug-indent-files" 28 | (mapcar (lambda (lisp-file) 29 | (message lisp-file) 30 | (assert-nil (rdebug-test-reindent-one-file lisp-file))) 31 | '("../rdebug.el" 32 | "../rdebug-breaks.el" 33 | "../rdebug-cmd.el" 34 | "../rdebug-core.el" 35 | "../rdebug-dbg.el" 36 | "../rdebug-error.el" 37 | "../rdebug-frames.el" 38 | "../rdebug-fns.el" 39 | "../rdebug-gud.el" 40 | "../rdebug-help.el" 41 | "../rdebug-info.el" 42 | "../rdebug-layouts.el" 43 | "../rdebug-output.el" 44 | "../rdebug-regexp.el" 45 | "../rdebug-secondary.el" 46 | "../rdebug-source.el" 47 | "../rdebug-track.el" 48 | "../rdebug-varbuf.el" 49 | "../rdebug-vars.el" 50 | "../rdebug-watch.el" 51 | "./test-cmd.el" 52 | "./test-core.el" 53 | "./test-indent.el" 54 | "./test-regexp.el" 55 | ))) 56 | 57 | (run-elk-test "rdebug-indent-files" 58 | "test indentation of Lisp files") 59 | -------------------------------------------------------------------------------- /test/test-help.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # begin require 'rubygems' rescue LoadError end 4 | # require 'ruby-debug' ; Debugger.start 5 | 6 | require 'test/unit' 7 | SRC_DIR = File.dirname(__FILE__) unless 8 | defined?(SRC_DIR) 9 | %w(ext lib cli).each do |dir| 10 | $:.unshift File.join(SRC_DIR, '..', dir) 11 | end 12 | require 'ruby_debug' 13 | 14 | require File.join(SRC_DIR, '..', 'cli', 'ruby-debug') 15 | $:.shift; $:.shift; $:.shift 16 | 17 | def cheap_diff(got_lines, correct_lines) 18 | puts got_lines if $DEBUG 19 | correct_lines.each_with_index do |line, i| 20 | correct_lines[i].chomp! 21 | if got_lines[i] != correct_lines[i] 22 | puts "difference found at line #{i+1}" 23 | puts "got : #{got_lines[i]}" 24 | puts "need: #{correct_lines[i]}" 25 | return false 26 | end 27 | if correct_lines.size != got_lines.size 28 | puts("difference in number of lines: " + 29 | "#{correct_lines.size} vs. #{got_lines.size}") 30 | return false 31 | end 32 | return true 33 | end 34 | end 35 | 36 | # Test Help commands 37 | class TestHelp < Test::Unit::TestCase 38 | require 'stringio' 39 | 40 | # Test initial variables and setting/getting state. 41 | def test_basic 42 | testbase = 'help' 43 | op = StringIO.new('', 'w') 44 | Dir.chdir(SRC_DIR) do 45 | script = File.join('data', "#{testbase}.cmd") 46 | Debugger.const_set('Version', 'unit testing') 47 | Debugger.run_script(script, op) 48 | got_lines = op.string.split("\n") 49 | right_file = File.join('data', "#{testbase}.right") 50 | correct_lines = File.readlines(right_file) 51 | result = cheap_diff(got_lines, correct_lines) 52 | unless result 53 | puts '-' * 80 54 | puts got_lines 55 | puts '-' * 80 56 | end 57 | assert result 58 | end 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /test/data/save.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # This tests the functioning of some set/show debugger commands 4 | # set debuggertesting on 5 | Currently testing the debugger is on. 6 | # ### ******************************* 7 | # ### *** save/source commands *** 8 | # ### ******************************* 9 | # ######################################## 10 | # ### test args and baseneme... 11 | # ######################################## 12 | # set basename off 13 | basename is off. 14 | # set autoeval off 15 | autoeval is off. 16 | # # Should have nothing set 17 | # info break 18 | No breakpoints. 19 | # info catch 20 | No exceptions set to be caught. 21 | # # Should save nothing 22 | # save temp 23 | Saved to 'temp' 24 | # eval File.open("temp").readlines 25 | ["set autoeval off\n", "set basename off\n", "set debuggertesting on\n", "set autolist off\n", "set autoirb off\n"] 26 | # # Should read in nothing 27 | # source temp 28 | autoeval is off. 29 | basename is off. 30 | Currently testing the debugger is on. 31 | autolist is off. 32 | autoirb is off. 33 | # info break 34 | No breakpoints. 35 | # # Now try saving something interesting 36 | # break 10 37 | Breakpoint 1 file ./gcd.rb, line 10 38 | # catch RuntimeError 39 | Catch exception RuntimeError. 40 | # save temp 41 | Saved to 'temp' 42 | # eval File.open("temp").readlines 43 | ["break ./gcd.rb:10\n", "catch RuntimeError\n", "set autoeval off\n", "set basename on\n", "set debuggertesting on\n", "set autolist off\n", "set autoirb off\n"] 44 | # # FIXME: The below is broken 45 | # ## Change parameters above 46 | # ## catch RuntimeError off 47 | # ## info catch 48 | # ##set listsize 55 49 | # source temp 50 | Breakpoint 2 file gcd.rb, line 10 51 | Catch exception RuntimeError. 52 | autoeval is off. 53 | basename is on. 54 | Currently testing the debugger is on. 55 | autolist is off. 56 | autoirb is off. 57 | # ##info break 58 | # ##info catch 59 | # ##show listsize 60 | -------------------------------------------------------------------------------- /test/test-ctrl.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # begin require 'rubygems' rescue LoadError end 4 | # require 'ruby-debug' ; Debugger.start 5 | 6 | require 'test/unit' 7 | SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 8 | defined?(SRC_DIR) 9 | %w(ext lib cli).each do |dir| 10 | $: << File.join(SRC_DIR, '..', dir) 11 | end 12 | require 'ruby_debug' 13 | require File.join(SRC_DIR, '..', 'cli', 'ruby-debug') 14 | 15 | # Test Local Control Interface 16 | class TestCtrl < Test::Unit::TestCase 17 | 18 | def cheap_diff(got_lines, correct_lines, outfile) 19 | if correct_lines.size != got_lines.size 20 | puts "Size difference #{correct_lines.size} vs. #{got_lines.size}" 21 | File.open(outfile, 'w') {|f| f.puts got_lines} 22 | return false 23 | end 24 | correct_lines.each_with_index do |line, i| 25 | correct_lines[i].chomp! 26 | if got_lines[i] != correct_lines[i] 27 | puts "difference found at line #{i+1}" 28 | puts "got : #{got_lines[i]}" 29 | puts "need: #{correct_lines[i]}" 30 | File.open(outfile, 'w') {|f| f.puts got_lines} 31 | return false 32 | end 33 | end 34 | end 35 | 36 | require 'stringio' 37 | 38 | # Test initial variables and setting/getting state. 39 | def test_ctrl 40 | ENV['COLUMNS'] = '80' 41 | ENV['EMACS'] = nil 42 | testbase = 'ctrl' 43 | out = StringIO.new('', 'w') 44 | Dir.chdir(SRC_DIR) do 45 | script = File.join('data', "#{testbase}.cmd") 46 | interface = Debugger::ScriptInterface.new(script, out) 47 | processor = Debugger::ControlCommandProcessor.new(interface) 48 | processor.process_commands 49 | got_lines = out.string.split("\n") 50 | right_file = File.join('data', "#{testbase}.right") 51 | correct_lines = File.readlines(right_file) 52 | assert cheap_diff(got_lines, correct_lines, "#{testbase}.out") 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /test/data/condition.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # ******************************************************** 4 | # # This tests primarily the condition command. 5 | # # In order to do this we need to run break, and disable 6 | # # ******************************************************** 7 | # set debuggertesting on 8 | Currently testing the debugger is on. 9 | # set callstyle last 10 | Frame call-display style is last. 11 | # set autoeval off 12 | autoeval is off. 13 | # break 6 if a > b 14 | Breakpoint 1 file ./gcd.rb, line 6 15 | # info break 16 | Num Enb What 17 | 1 y at ./gcd.rb:6 if a > b 18 | # condition 1 19 | # info break 20 | Num Enb What 21 | 1 y at ./gcd.rb:6 22 | # break 12 23 | Breakpoint 2 file ./gcd.rb, line 12 24 | # condition 2 1 == a 25 | # # FIXME: should be able to catch error on: 26 | # # condition 2 if 1 == a 27 | # disable 1 28 | # continue 29 | Breakpoint 2 at gcd.rb:12 30 | gcd.rb:12 31 | if a == 1 or b-a == 0 32 | # info break 33 | Num Enb What 34 | 1 n at ./gcd.rb:6 35 | 2 y at ./gcd.rb:12 if 1 == a 36 | breakpoint already hit 1 time 37 | # p a 38 | 1 39 | # # Now test trying to enable an invalid breakpoint 40 | # break 6 if a > 41 | Breakpoint 3 file ./gcd.rb, line 6 42 | *** Expression "a > " syntactically incorrect; breakpoint disabled. 43 | # info break 44 | Num Enb What 45 | 1 n at ./gcd.rb:6 46 | 2 y at ./gcd.rb:12 if 1 == a 47 | breakpoint already hit 1 time 48 | 3 n at ./gcd.rb:6 if a > 49 | # enable 3 50 | *** Expression "a > " syntactically incorrect; breakpoint remains disabled. 51 | # info break 52 | Num Enb What 53 | 1 n at ./gcd.rb:6 54 | 2 y at ./gcd.rb:12 if 1 == a 55 | breakpoint already hit 1 time 56 | 3 n at ./gcd.rb:6 if a > 57 | # condition 3 a > 5 58 | # enable 3 59 | # info break 60 | Num Enb What 61 | 1 n at ./gcd.rb:6 62 | 2 y at ./gcd.rb:12 if 1 == a 63 | breakpoint already hit 1 time 64 | 3 y at ./gcd.rb:6 if a > 5 65 | # quit 66 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/jump.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | 3 | # Implements debugger "jump" command 4 | class JumpCommand < Command 5 | self.allow_in_control = true 6 | 7 | def numeric?(object) 8 | true if Float(object) rescue false 9 | end 10 | 11 | def regexp 12 | / ^\s* 13 | j(?:ump)? \s* 14 | (?:\s+(\S+))?\s* 15 | (?:\s+(\S+))?\s* 16 | $ 17 | /ix 18 | end 19 | 20 | def execute 21 | if !@match[1] 22 | errmsg "\"jump\" must be followed by a line number\n" 23 | return 24 | end 25 | if !numeric?(@match[1]) 26 | puts "Bad line number: " + @match[1] 27 | return 28 | end 29 | line = @match[1].to_i 30 | line = @state.context.frame_line(0) + line if @match[1][0] == '+' or @match[1][0] == '-' 31 | if line == @state.context.frame_line(0) 32 | CommandProcessor.print_location_and_text(@state.context.frame_file(0), line) 33 | return 34 | end 35 | file = @match[2] 36 | file = @state.context.frame_file(file.to_i) if numeric?(file) 37 | file = @state.context.frame_file(0) if !file 38 | case Debugger.current_context.jump(line, file) 39 | when 0 40 | @state.proceed 41 | when 1 42 | errmsg "Not possible to jump from here\n" 43 | when 2 44 | errmsg "Couldn't find debugged frame\n" 45 | when 3 46 | errmsg "Couldn't find active code at " + file + ":" + line.to_s + "\n" 47 | end 48 | end 49 | 50 | class << self 51 | def help_command 52 | %w[jump] 53 | end 54 | 55 | def help(cmd) 56 | %{ 57 | j[ump] line\tjump to line number (absolute) 58 | j[ump] -line\tjump back to line (relative) 59 | j[ump] +line\tjump ahead to line (relative) 60 | 61 | Change the next line of code to be executed. 62 | } 63 | end 64 | end 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/trace.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | class TraceCommand < Command # :nodoc: 3 | def regexp 4 | /^\s* tr(?:ace)? (?: \s+ (\S+)) # on |off | var(iable) 5 | (?: \s+ (\S+))? # (all | variable-name)? 6 | (?: \s+ (\S+))? \s* # (stop | nostop)? 7 | $/ix 8 | end 9 | 10 | def execute 11 | if @match[1] =~ /on|off/ 12 | onoff = 'on' == @match[1] 13 | if @match[2] 14 | Debugger.current_context.tracing = onoff 15 | print "Tracing %s all threads.\n" % (onoff ? 'on' : 'off') 16 | else 17 | Debugger.tracing = onoff 18 | print "Tracing %s on current thread.\n" % (onoff ? 'on' : 'off') 19 | end 20 | elsif @match[1] =~ /var(?:iable)?/ 21 | varname=@match[2] 22 | if debug_eval("defined?(#{varname})") 23 | if @match[3] && @match[3] !~ /(:?no)?stop/ 24 | errmsg("expecting 'stop' or 'nostop'; got %s\n" % @match[3]) 25 | else 26 | dbg_cmd = if @match[3] && (@match[3] !~ /nostop/) 27 | 'debugger' else '' end 28 | end 29 | eval(" 30 | trace_var(:#{varname}) do |val| 31 | print \"traced variable #{varname} has value \#{val}\n\" 32 | #{dbg_cmd} 33 | end") 34 | else 35 | errmsg "#{varname} is not a global variable.\n" 36 | end 37 | else 38 | errmsg("expecting 'on', 'off', 'var' or 'variable'; got: %s\n" % 39 | @match[1]) 40 | end 41 | end 42 | 43 | class << self 44 | def help_command 45 | 'trace' 46 | end 47 | 48 | def help(cmd) 49 | %{ 50 | tr[ace] (on|off)\tset trace mode of current thread 51 | tr[ace] (on|off) all\tset trace mode of all threads 52 | tr[ace] var(iable) VARNAME [stop|nostop]\tset trace variable on VARNAME 53 | } 54 | end 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /test/test-hist.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # begin require 'rubygems' rescue LoadError end 5 | # require 'ruby-debug'; Debugger.start 6 | 7 | # Test history commands 8 | 9 | class TestHistory < Test::Unit::TestCase 10 | 11 | @@SRC_DIR = File.join(Dir.pwd, File.dirname(__FILE__)) unless 12 | defined?(@@SRC_DIR) 13 | 14 | require File.join(@@SRC_DIR, 'helper') 15 | include TestHelper 16 | 17 | unless defined?(@@FILE_HISTORY) 18 | @@FILE_HISTORY = '.rdebug_hist' 19 | end 20 | 21 | def test_basic 22 | 23 | # Set up history file to read from. 24 | ENV['HOME']=@@SRC_DIR 25 | ENV['RDEBUG'] = nil 26 | 27 | debugger_commands = ['show commands', 28 | 'set history save on', 29 | 'show history', 30 | 'quit unconditionally'] 31 | debugger_output = 'test-history.out' 32 | 33 | Dir.chdir(@@SRC_DIR) do 34 | correct_lines = File.read(File.join('data', 'history.right')).split(/\n/) 35 | f = File.open(@@FILE_HISTORY, 'w') 36 | correct_lines[0.. -(debugger_commands.length+1)].each do |line| 37 | f.puts line 38 | end 39 | f.close 40 | 41 | # Now that we've set up a history file, run the debugger 42 | # and check that it's reading that correctly. 43 | debug_pgm=File.join('..', 'rdbg.rb') 44 | debugged=File.join('gcd.rb') 45 | IO.popen("#{debug_pgm} #{debugged} 3 5 >#{debugger_output}", 'w') do 46 | |pipe| 47 | debugger_commands.each do |cmd| 48 | pipe.puts cmd 49 | end 50 | end 51 | 52 | # Compare output 53 | got_lines = File.read(@@FILE_HISTORY).split(/\n/) 54 | # FIXME: Disable for now. 55 | assert true, 'FIXME' 56 | return 57 | if cheap_diff(got_lines, correct_lines) 58 | assert true 59 | FileUtils.rm(debugger_output) 60 | FileUtils.rm(@@FILE_HISTORY) 61 | else 62 | assert nil, 'Output differs' 63 | end 64 | end 65 | end 66 | end 67 | 68 | 69 | -------------------------------------------------------------------------------- /emacs/test/test-shortkey.el: -------------------------------------------------------------------------------- 1 | ;; -*- emacs-lisp -*- 2 | ;; This program has to be run from the directory it is currently in and 3 | ;; the rdebug code has to be in the parent directory 4 | (load-file "./elk-test.el") 5 | 6 | ;; FIXME? Should we use "require 'rdebug" here. 7 | ;; Would have to prepend . to load-path. 8 | (setq load-path (cons ".." load-path)) 9 | (load-file "../rdebug-shortkey.el") 10 | 11 | (deftest "rdebug-shortkey-mode-test" 12 | (let ((buf (generate-new-buffer "shortkey readwrite"))) 13 | (with-current-buffer buf 14 | (setq buffer-read-only nil) 15 | ;; turning on short-key-mode make buffer read-only 16 | (rdebug-internal-short-key-mode 1) 17 | (assert-equal t buffer-read-only) 18 | 19 | ;; turning off short-key-mode should make buffer read-write again 20 | (rdebug-internal-short-key-mode -1) 21 | (assert-equal nil buffer-read-only) 22 | 23 | ;; -------------------- 24 | ;; Check multiple "on": and "off:s". 25 | 26 | (rdebug-internal-short-key-mode 1) 27 | (assert-equal t buffer-read-only) 28 | 29 | (rdebug-internal-short-key-mode 1) 30 | (assert-equal t buffer-read-only) 31 | 32 | (rdebug-internal-short-key-mode 1) 33 | (assert-equal t buffer-read-only) 34 | 35 | (rdebug-internal-short-key-mode -1) 36 | (assert-equal nil buffer-read-only)) 37 | 38 | (kill-buffer buf)) 39 | 40 | (let ((buf (generate-new-buffer "shortkey readonly"))) 41 | (with-current-buffer buf 42 | (setq buffer-read-only t) 43 | 44 | ;; turning on short-key-mode keep buffer read-only 45 | (rdebug-internal-short-key-mode 1) 46 | (assert-equal t buffer-read-only) 47 | 48 | ;; The buffer was originally in read-only mode, it should remain 49 | ;; there. 50 | (rdebug-internal-short-key-mode -1) 51 | (assert-equal t buffer-read-only)) 52 | (kill-buffer buf))) 53 | 54 | ;; ------------------------------------------------------------------- 55 | ;; Build and run the test suite. 56 | ;; 57 | 58 | (build-suite "rdebug-suite" 59 | "rdebug-shortkey-mode-test") 60 | (run-elk-test "rdebug-suite" 61 | "test things in rdebug-shortkey.el") 62 | -------------------------------------------------------------------------------- /cli/ruby-debug/helper.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | 3 | module ParseFunctions 4 | Position_regexp = '(?:(\d+)|(.+?)[:.#]([^.:\s]+))' 5 | 6 | # Parse 'str' of command 'cmd' as an integer between 7 | # min and max. If either min or max is nil, that 8 | # value has no bound. 9 | def get_int(str, cmd, min=nil, max=nil, default=1) 10 | return default unless str 11 | begin 12 | int = Integer(str) 13 | if min and int < min 14 | print "%s argument '%s' needs to at least %s.\n" % [cmd, str, min] 15 | return nil 16 | elsif max and int > max 17 | print "%s argument '%s' needs to at most %s.\n" % [cmd, str, max] 18 | return nil 19 | end 20 | return int 21 | rescue 22 | print "%s argument '%s' needs to be a number.\n" % [cmd, str] 23 | return nil 24 | end 25 | end 26 | 27 | # Return true if arg is 'on' or 1 and false arg is 'off' or 0. 28 | # Any other value raises RuntimeError. 29 | def get_onoff(arg, default=nil, print_error=true) 30 | if arg.nil? or arg == '' 31 | if default.nil? 32 | if print_error 33 | print "Expecting 'on', 1, 'off', or 0. Got nothing.\n" 34 | raise RuntimeError 35 | end 36 | return default 37 | end 38 | end 39 | case arg.downcase 40 | when '1', 'on' 41 | return true 42 | when '0', 'off' 43 | return false 44 | else 45 | if print_error 46 | print "Expecting 'on', 1, 'off', or 0. Got: %s.\n" % arg.to_s 47 | raise RuntimeError 48 | end 49 | end 50 | end 51 | 52 | # Return 'on' or 'off' for supplied parameter. The parmeter should 53 | # be true, false or nil. 54 | def show_onoff(bool) 55 | if not [TrueClass, FalseClass, NilClass].member?(bool.class) 56 | return "??" 57 | end 58 | return bool ? 'on' : 'off' 59 | end 60 | 61 | # Return true if code is syntactically correct for Ruby. 62 | def syntax_valid?(code) 63 | eval("BEGIN {return true}\n#{code}", nil, "", 0) 64 | rescue Exception 65 | false 66 | end 67 | 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /ruby-debug.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | 3 | Gem::Specification.new do |s| 4 | s.name = %q{ruby-debug-base19} 5 | s.version = "0.12.0" 6 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= 7 | s.authors = ["Kent Sibilev", "Mark Moseley"] 8 | s.date = %q{2009-09-08} 9 | s.description = %q{ruby-debug is a fast implementation of the standard Ruby debugger debug.rb. 10 | It is implemented by utilizing a new Ruby C API hook. The core component 11 | provides support that front-ends can build on. It provides breakpoint 12 | handling, bindings for stack frames among other things. 13 | } 14 | s.email = %q{mark@fast-software.com} 15 | s.extra_rdoc_files = [ 16 | "README", 17 | "ext/ruby_debug/ruby_debug.c" 18 | ] 19 | s.files = [ 20 | "AUTHORS", 21 | "CHANGES", 22 | "LICENSE", 23 | "README", 24 | "Rakefile", 25 | "ext/ruby_debug/extconf.rb", 26 | "ext/ruby_debug/breakpoint.c", 27 | "ext/ruby_debug/ruby_debug.h", 28 | "ext/ruby_debug/ruby_debug.c", 29 | "lib/ruby-debug-base.rb", 30 | "lib/ChangeLog" 31 | ] 32 | s.homepage = %q{http://rubyforge.org/projects/ruby-debug19/} 33 | s.rdoc_options = ["--charset=UTF-8"] 34 | s.require_paths = ["lib"] 35 | s.required_ruby_version = Gem::Requirement.new(">= 1.8.2") 36 | s.rubyforge_project = %q{ruby-debug19} 37 | s.rubygems_version = %q{1.3.4} 38 | s.summary = %q{Fast Ruby debugger - core component} 39 | s.test_files = [ 40 | "test/base/base.rb", 41 | "test/base/binding.rb", 42 | "test/base/catchpoint.rb" 43 | ] 44 | s.files += s.test_files 45 | s.extensions << "ext/ruby_debug/extconf.rb" 46 | s.add_dependency("columnize", ">= 0.3.1") 47 | s.add_dependency("ruby_core_source", ">= 0.1.4") 48 | s.add_dependency("linecache19", ">= 0.5.11") 49 | 50 | if s.respond_to? :specification_version then 51 | current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION 52 | s.specification_version = 3 53 | 54 | if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then 55 | else 56 | end 57 | else 58 | end 59 | end 60 | 61 | -------------------------------------------------------------------------------- /emacs/rdebug-dbg.el: -------------------------------------------------------------------------------- 1 | ;;; rdebug-dbg.el --- Ruby debugger frames buffer 2 | 3 | ;; Copyright (C) 2008 Rocky Bernstein (rocky@gnu.org) 4 | ;; Copyright (C) 2008 Anders Lindgren 5 | 6 | ;; $Id: rdebug-dbg.el 702 2008-02-17 22:00:36Z rockyb $ 7 | 8 | ;; This program is free software; you can redistribute it and/or modify 9 | ;; it under the terms of the GNU General Public License as published by 10 | ;; the Free Software Foundation; either version 2, or (at your option) 11 | ;; any later version. 12 | 13 | ;; This program is distributed in the hope that it will be useful, 14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ;; GNU General Public License for more details. 17 | 18 | ;; You should have received a copy of the GNU General Public License 19 | ;; along with GNU Emacs; see the file COPYING. If not, write to the 20 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 21 | ;; Boston, MA 02111-1307, USA. 22 | 23 | ;;; Commentary: 24 | 25 | ;; See the manual and the file `rdebug.el' for more information. 26 | 27 | ;; This file contains internal debug trace support. 28 | 29 | ;;; Code: 30 | 31 | (require 'rdebug-vars) 32 | 33 | (defun rdebug-debug-message (&rest args) 34 | (if rdebug-debug-active 35 | (let ((buf (get-buffer-create "*Xrdebug*"))) 36 | (with-current-buffer buf 37 | (save-excursion 38 | (goto-char (point-max)) 39 | ;; 32 = space. 40 | (insert (make-string (* 4 rdebug-debug-depth) 32)) 41 | (insert (apply #'format args)) 42 | (insert "\n")))))) 43 | 44 | 45 | (defmacro rdebug-debug-enter (str &rest body) 46 | (declare (indent 1) (debug t)) 47 | `(progn 48 | (rdebug-debug-message "--> %s" ,str) 49 | (setq rdebug-debug-depth (+ rdebug-debug-depth 1)) 50 | (unwind-protect 51 | (progn 52 | ,@body) 53 | (setq rdebug-debug-depth (max 0 (- rdebug-debug-depth 1))) 54 | (rdebug-debug-message "<-- %s" ,str)))) 55 | 56 | (provide 'rdebug-dbg) 57 | 58 | ;;; Local variables: 59 | ;;; eval:(put 'rdebug-debug-enter 'lisp-indent-hook 1) 60 | ;;; End: 61 | 62 | ;;; rdebug-dbg.el ends here 63 | -------------------------------------------------------------------------------- /emacs/test/test-frames.el: -------------------------------------------------------------------------------- 1 | ;; -*- emacs-lisp -*- 2 | ;; This program has to be run from the directory it is currently in and 3 | ;; the rdebug code has to be in the parent directory 4 | (load-file "./elk-test.el") 5 | 6 | ;; FIXME? Should we use "require 'rdebug" here. 7 | ;; Would have to prepend . to load-path. 8 | (load-file "../rdebug.el") 9 | (load-file "../rdebug-regexp.el") 10 | (load-file "../rdebug-frames.el") 11 | 12 | (make-variable-buffer-local 'gud-rdebug-marker-acc) 13 | 14 | (deftest "rdebug-stack-buffer-field-test" 15 | (let ((buf (generate-new-buffer "testing"))) 16 | (save-excursion 17 | (switch-to-buffer buf) 18 | (insert 19 | "--> #0 Object.gcd(a#Fixnum, b#Fixnum) at line /tmp/gcd.rb:4\n") 20 | (insert 21 | " at line /foo/bar/custom_require.rb:27\n") 22 | 23 | (goto-char (point-min)) 24 | (let* ((b (line-beginning-position)) (e (line-end-position)) 25 | (s (buffer-substring b e)) 26 | (file nil) (line nil)) 27 | (assert-nonnil (string-match rdebug-stack-frame-regexp s)) 28 | (assert-equal "/tmp/gcd.rb" (rdebug-stack-buffer-field 29 | s b 30 | rdebug-stack-frame-file-group 31 | font-lock-comment-face)) 32 | (assert-equal "4" (rdebug-stack-buffer-field 33 | s b 34 | rdebug-stack-frame-line-group 35 | font-lock-constant-face)) 36 | (forward-line) 37 | (setq b (line-beginning-position)) 38 | (setq e (line-end-position)) 39 | (setq s (buffer-substring b e)) 40 | (assert-nonnil (string-match rdebug-stack-frame-2nd-regexp s)) 41 | (assert-equal "/foo/bar/custom_require.rb" 42 | (rdebug-stack-buffer-field 43 | s b 44 | rdebug-stack-frame-2nd-file-group 45 | font-lock-comment-face)) 46 | (assert-equal "27" (rdebug-stack-buffer-field 47 | s b 48 | rdebug-stack-frame-2nd-line-group 49 | font-lock-constant-face)) 50 | )) 51 | (kill-buffer buf))) 52 | 53 | 54 | ;; ------------------------------------------------------------------- 55 | ;; Build and run the test suite. 56 | ;; 57 | 58 | (build-suite "rdebug-suite" 59 | "rdebug-stack-buffer-field-test") 60 | (run-elk-test "rdebug-suite" 61 | "test things in rdebug-frames.el") 62 | 63 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # $Id: Makefile.am,v 1.3 2006/12/28 12:34:25 rockyb Exp $ 3 | # Copyright (C) 2007 Rocky Bernstein 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 2 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | ############################################################################## 18 | 19 | EXT=1 20 | man1_MANS = rdebug.$(EXT) 21 | 22 | EXTRA_DIST = $(man1_MANS) \ 23 | hanoi.rb primes.rb test-tri2.rb tri3.rb triangle.rb \ 24 | ruby-debug.info ruby-debug.html ruby-debug.pdf 25 | 26 | info_TEXINFOS = ruby-debug.texi rdebug-emacs.texi 27 | 28 | all: $(INFO_DEPS) $(man1_MANS) html pdf 29 | 30 | pdf: ruby-debug.pdf rdebug-emacs.pdf 31 | 32 | txt: ruby-debug.txt rdebug-emacs.txt 33 | 34 | ps: ruby-debug.ps rdebug-emacs.ps 35 | 36 | man: $(man1_MANS) 37 | 38 | html: ruby-debug.html rdebug-emacs.html 39 | 40 | ruby-debug.html: ruby-debug.texi 41 | texi2html $(srcdir)/ruby-debug.texi || true 42 | 43 | rdebug-emacs.html: rdebug-emacs.texi 44 | texi2html $(srcdir)/rdebug-emacs.texi || true 45 | 46 | %.ps.gz: %.ps 47 | gzip -9c $< > $@ 48 | 49 | # Our `texinfo.tex' must reside in the current directory, otherwise 50 | # texi2dvi will use the default. 51 | .texi.pdf: 52 | $(TEXI2PDF) -I $(srcdir) $< 53 | 54 | .texi.dvi: 55 | $(TEXI2DVI) -I $(srcdir) $< 56 | 57 | .dvi.ps: 58 | test -d $(docdir) || mkdir $(docdir) 59 | $(DVIPS) $< -o $@ 60 | 61 | all-formats: pdf dvi txt ps html 62 | 63 | MOSTLYCLEANFILES = rubydb.tgs rubydb.ps.gz rubydb.pdf rubydb.html rubydb_toc.html rubydb_foot.html rubydb-man.html 64 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/stepping.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | # Mix-in module to assist in command parsing. 3 | module SteppingFunctions # :nodoc: 4 | def parse_stepping_args(command_name, match) 5 | if match[1].nil? 6 | force = Command.settings[:force_stepping] 7 | elsif match[1] == '+' 8 | force = true 9 | elsif match[1] == '-' 10 | force = false 11 | end 12 | steps = get_int(match[2], command_name, 1) 13 | return [steps, force] 14 | end 15 | end 16 | # Implements debugger "next" command. 17 | class NextCommand < Command 18 | self.allow_in_post_mortem = false 19 | self.need_context = true 20 | 21 | def regexp 22 | /^\s* n(?:ext)? 23 | ([+-])?(?:\s+(\S+))? 24 | \s*$/x 25 | end 26 | 27 | def execute 28 | steps, force = parse_stepping_args("Next", @match) 29 | return unless steps 30 | @state.context.step_over steps, @state.frame_pos, force 31 | @state.proceed 32 | end 33 | 34 | class << self 35 | def help_command 36 | 'next' 37 | end 38 | 39 | def help(cmd) 40 | %{ 41 | n[ext][+-]?[ nnn]\tstep over once or nnn times, 42 | \t\t'+' forces to move to another line. 43 | \t\t'-' is the opposite of '+' and disables the force_stepping setting. 44 | } 45 | end 46 | end 47 | end 48 | 49 | # Implements debugger "step" command. 50 | class StepCommand < Command 51 | self.allow_in_post_mortem = false 52 | self.need_context = true 53 | 54 | def regexp 55 | /^\s* s(?:tep)? 56 | ([+-])?(?:\s+(\S+))? 57 | \s*$/x 58 | end 59 | 60 | def execute 61 | steps, force = parse_stepping_args("Step", @match) 62 | return unless steps 63 | @state.context.step(steps, force) 64 | @state.proceed 65 | end 66 | 67 | class << self 68 | def help_command 69 | 'step' 70 | end 71 | 72 | def help(cmd) 73 | %{ 74 | s[tep][+-]?[ nnn]\tstep (into methods) once or nnn times 75 | \t\t'+' forces to move to another line. 76 | \t\t'-' is the opposite of '+' and disables the force_stepping setting. 77 | } 78 | end 79 | end 80 | end 81 | end 82 | -------------------------------------------------------------------------------- /test/data/info.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # *************************************************** 4 | # # This tests info command handling 5 | # # *************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # set callstyle last 9 | Frame call-display style is last. 10 | # help info 11 | Generic command for showing things about the program being debugged. 12 | -- 13 | List of info subcommands: 14 | -- 15 | info args -- Argument variables of current stack frame 16 | info breakpoints -- Status of user-settable breakpoints 17 | info catch -- Exceptions that can be caught in the current stack frame 18 | info display -- Expressions to display when program stops 19 | info file -- Info about a particular file read in 20 | info files -- File names and timestamps of files read in 21 | info global_variables -- Global variables 22 | info instance_variables -- Instance variables of the current stack frame 23 | info line -- Line number and file name of current position in source file 24 | info locals -- Local variables of the current stack frame 25 | info program -- Execution status of the program 26 | info stack -- Backtrace of the stack 27 | info thread -- List info about thread NUM 28 | info threads -- information of currently-known threads 29 | info variables -- Local and instance variables of the current stack frame 30 | # info args 31 | # info line 32 | Line 4 of "./gcd.rb" 33 | # info locals 34 | # info stack 35 | --> #0 at line gcd.rb:4 36 | # info display 37 | There are no auto-display expressions now. 38 | # help info break 39 | Status of user-settable breakpoints. 40 | Without argument, list info about all breakpoints. With an 41 | integer argument, list info on that breakpoint. 42 | # help info display 43 | Expressions to display when program stops. 44 | # break 10 45 | Breakpoint 1 file ./gcd.rb, line 10 46 | # break 12 47 | Breakpoint 2 file ./gcd.rb, line 12 48 | # info break 10 49 | *** No breakpoints found among list given. 50 | # info break 1 51 | Num Enb What 52 | 1 y at ./gcd.rb:10 53 | # info break 1 2 54 | Num Enb What 55 | 1 y at ./gcd.rb:10 56 | 2 y at ./gcd.rb:12 57 | # info break 58 | Num Enb What 59 | 1 y at ./gcd.rb:10 60 | 2 y at ./gcd.rb:12 61 | # info file ./gcd.rb break 62 | File ./gcd.rb 63 | breakpoint line numbers: 64 | 4 6 7 10 12 13 15 18 65 | # quit 66 | -------------------------------------------------------------------------------- /test/base/base.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'test/unit' 3 | 4 | # Some tests of Debugger module in C extension ruby_debug 5 | class TestRubyDebug < Test::Unit::TestCase 6 | $:.unshift File.join(File.dirname(__FILE__), '..', '..', 'ext') 7 | require 'ruby_debug' 8 | $:.shift 9 | 10 | # test current_context 11 | def test_current_context 12 | assert(Debugger.started?, 13 | 'debugger should now be started.') 14 | assert_equal(__LINE__, Debugger.current_context.frame_line) 15 | assert_equal(Debugger.current_context.frame_file, 16 | Debugger.current_context.frame_file(0)) 17 | assert_equal(File.basename(__FILE__), 18 | File.basename(Debugger.current_context.frame_file)) 19 | assert_raises(ArgumentError) {Debugger.current_context.frame_file(1, 2)} 20 | assert_raises(ArgumentError) {Debugger.current_context.frame_file(10)} 21 | assert_equal(7, Debugger.current_context.stack_size) 22 | assert_equal(TestRubyDebug, Debugger.current_context.frame_class) 23 | assert_equal(false, Debugger.current_context.dead?, 'Not dead yet!') 24 | end 25 | 26 | # Test initial variables and setting/getting state. 27 | def test_debugger_base 28 | assert(Debugger.started?, 29 | 'Debugger should now be started.') 30 | assert_equal(false, Debugger.debug, 31 | 'Debug variable should not be set.') 32 | a = Debugger.contexts 33 | assert_equal(1, a.size, 34 | 'There should only be one context.') 35 | assert_equal(Array, a.class, 36 | 'Context should be an array.') 37 | end 38 | 39 | # Test breakpoint handling 40 | def test_breakpoints 41 | assert_equal(0, Debugger.breakpoints.size, 42 | 'There should not be any breakpoints set.') 43 | brk = Debugger.add_breakpoint(__FILE__, 1) 44 | assert_equal(Debugger::Breakpoint, brk.class, 45 | 'Breakpoint should have been set and returned.') 46 | assert_equal(1, Debugger.breakpoints.size, 47 | 'There should now be one breakpoint set.') 48 | Debugger.remove_breakpoint(0) 49 | assert_equal(1, Debugger.breakpoints.size, 50 | 'There should still be one breakpoint set.') 51 | Debugger.remove_breakpoint(1) 52 | assert_equal(0, Debugger.breakpoints.size, 53 | 'There should no longer be any breakpoints set.') 54 | end 55 | end 56 | 57 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/method.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | 3 | begin 4 | require 'methodsig' 5 | have_methodsig = true 6 | rescue LoadError 7 | have_methodsig = false 8 | end 9 | 10 | # Implements the debugger 'method sig' command. 11 | class MethodSigCommand < Command 12 | def regexp 13 | /^\s*m(?:ethod)?\s+sig(?:nature)?\s+(\S+)\s*$/ 14 | end 15 | 16 | def execute 17 | obj = debug_eval('method(:%s)' % @match[1]) 18 | if obj.is_a?(Method) 19 | begin 20 | print "%s\n", obj.signature.to_s 21 | rescue 22 | errmsg("Can't get signature for '#{@match[1]}'\n") 23 | end 24 | else 25 | errmsg("Can't make method out of '#{@match[1]}'\n") 26 | end 27 | end 28 | 29 | class << self 30 | def help_command 31 | 'method' 32 | end 33 | 34 | def help(cmd) 35 | %{ 36 | m[ethod] sig[nature] \tshow the signature of a method 37 | } 38 | end 39 | end 40 | end if have_methodsig 41 | 42 | # Implements the debugger 'method' command. 43 | class MethodCommand < Command 44 | def regexp 45 | /^\s*m(?:ethod)?\s+((iv)|(i(:?nstance\s+)?)\s+)?/ 46 | end 47 | 48 | def execute 49 | if @match[1] == "iv" 50 | obj = debug_eval(@match.post_match) 51 | obj.instance_variables.sort.each do |v| 52 | print "%s = %s\n", v, obj.instance_variable_get(v).inspect 53 | end 54 | elsif @match[1] 55 | obj = debug_eval(@match.post_match) 56 | print "%s\n", columnize(obj.methods.sort(), 57 | self.class.settings[:width]) 58 | else 59 | obj = debug_eval(@match.post_match) 60 | unless obj.kind_of? Module 61 | print "Should be Class/Module: %s\n", @match.post_match 62 | else 63 | print "%s\n", columnize(obj.instance_methods(false).sort(), 64 | self.class.settings[:width]) 65 | end 66 | end 67 | end 68 | 69 | class << self 70 | def help_command 71 | 'method' 72 | end 73 | 74 | def help(cmd) 75 | %{ 76 | m[ethod] i[nstance] \tshow methods of object 77 | m[ethod] iv \t\tshow instance variables of object 78 | m[ethod] \t\tshow instance methods of class or module 79 | } 80 | end 81 | end 82 | end 83 | 84 | end 85 | -------------------------------------------------------------------------------- /emacs/test/test-fns.el: -------------------------------------------------------------------------------- 1 | ;; -*- emacs-lisp -*- 2 | ;; This program has to be run from the directory it is currently in and 3 | ;; the rdebug code has to be in the parent directory 4 | (load-file "./elk-test.el") 5 | 6 | (setq load-path (cons ".." load-path)) 7 | (require 'rdebug-fns) 8 | (require 'rdebug-locring) 9 | (setq load-path (cdr load-path)) 10 | 11 | ;; ------------------------------------------------------------------- 12 | 13 | (deftest "test-add-to-ring" 14 | (let ((location-ring (make-ring 5))) 15 | (assert-equal t (ring-empty-p location-ring)) 16 | (rdebug-locring-add 'first location-ring) 17 | (assert-equal 'first (ring-ref location-ring 0)) 18 | (assert-equal 1 (ring-length location-ring)) 19 | ;; Trying to add the same entry should not again. 20 | (rdebug-locring-add 'first location-ring) 21 | (assert-equal 1 (ring-length location-ring)) 22 | 23 | ;; Second should go in as last item. 24 | (rdebug-locring-add 'second location-ring) 25 | (assert-equal 'second (ring-ref location-ring 1)) 26 | ;; First item is still 0. 27 | (assert-equal 'first (ring-ref location-ring 0)))) 28 | 29 | (deftest "test-chomp" 30 | (assert-equal "" (chomp "")) 31 | (assert-equal "hi" (chomp "hi")) 32 | (assert-equal "hi" (chomp "hi\n")) 33 | (assert-equal "hi\n" (chomp "hi\n\n")) 34 | (assert-equal "hi" (chomp "hi\n\n" t))) 35 | 36 | (deftest "test-set-frame-arrow" 37 | (let ((rdebug-frames-current-frame-number 0)) 38 | (rdebug-set-frame-arrow (current-buffer)) 39 | (assert-equal '((overlay-arrow . right-triangle)) 40 | fringe-indicator-alist) 41 | (setq rdebug-frames-current-frame-number 1) 42 | (rdebug-set-frame-arrow (current-buffer)) 43 | (assert-equal '((overlay-arrow . hollow-right-triangle)) 44 | fringe-indicator-alist))) 45 | 46 | (require 'shell) 47 | (deftest "test-dead-process-p" 48 | (assert-equal t (rdebug-dead-process-p)) 49 | (let ((gud-comint-buffer nil)) 50 | (assert-equal t (rdebug-dead-process-p)) 51 | (setq gud-comint-buffer (shell)) 52 | (assert-equal nil (rdebug-dead-process-p)))) 53 | 54 | ;; ------------------------------------------------------------------- 55 | ;; Build and run the test suite. 56 | ;; 57 | 58 | (build-suite "rdebug-gud-suite" 59 | "test-add-to-ring" 60 | "test-chomp" 61 | "test-dead-process-p" 62 | "test-set-frame-arrow") 63 | 64 | (run-elk-test "rdebug-gud-suite" 65 | "test some rdebug-error code") 66 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/save.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | module SaveFunctions # :nodoc: 3 | 4 | # Create a temporary file to write in if file is nil 5 | def open_save 6 | require "tempfile" 7 | file = Tempfile.new("rdebug-save") 8 | # We want close to not unlink, so redefine. 9 | def file.close 10 | @tmpfile.close if @tmpfile 11 | end 12 | return file 13 | end 14 | end 15 | 16 | class SaveCommand < Command # :nodoc: 17 | self.allow_in_control = true 18 | 19 | def save_breakpoints(file) 20 | Debugger.breakpoints.each do |b| 21 | file.puts "break #{b.source}:#{b.pos}#{" if #{b.expr}" if b.expr}" 22 | end 23 | end 24 | 25 | def save_catchpoints(file) 26 | Debugger.catchpoints.keys.each do |c| 27 | file.puts "catch #{c}" 28 | end 29 | end 30 | 31 | def save_displays(file) 32 | for d in @state.display 33 | if d[0] 34 | file.puts "display #{d[1]}" 35 | end 36 | end 37 | end 38 | 39 | def save_settings(file) 40 | # FIXME put routine in set 41 | %w(autoeval basename debuggertesting).each do |setting| 42 | on_off = show_onoff(Command.settings[setting.to_sym]) 43 | file.puts "set #{setting} #{on_off}" 44 | end 45 | %w(autolist autoirb).each do |setting| 46 | on_off = show_onoff(Command.settings[setting.to_sym] > 0) 47 | file.puts "set #{setting} #{on_off}" 48 | end 49 | end 50 | 51 | def regexp 52 | /^\s* sa(?:ve)? 53 | (?:\s+(.+))? 54 | \s*$/ix 55 | end 56 | 57 | def execute 58 | if not @match[1] or @match[1].strip.empty? 59 | file = open_save() 60 | else 61 | file = open(@match[1], 'w') 62 | end 63 | save_breakpoints(file) 64 | save_catchpoints(file) 65 | # save_displays(file) 66 | save_settings(file) 67 | print "Saved to '#{file.path}'\n" 68 | if @state and @state.interface 69 | @state.interface.restart_file = file.path 70 | end 71 | file.close 72 | end 73 | 74 | class << self 75 | def help_command 76 | 'save' 77 | end 78 | 79 | def help(cmd) 80 | %{ 81 | save [FILE] 82 | Saves current debugger state to FILE as a script file. 83 | This includes breakpoints, catchpoints, display expressions and some settings. 84 | If no filename is given, we will fabricate one. 85 | 86 | Use the 'source' command in another debug session to restore them.} 87 | end 88 | end 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /test/data/breakpoints.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # ******************************************************** 4 | # # This tests step, next, continue, disable and 5 | # # enable. 6 | # # FIXME: break out enable/disable 7 | # # ******************************************************** 8 | # set debuggertesting on 9 | Currently testing the debugger is on. 10 | # set callstyle last 11 | Frame call-display style is last. 12 | # set autoeval off 13 | autoeval is off. 14 | # break 6 15 | Breakpoint 1 file ./gcd.rb, line 6 16 | # break 10 17 | Breakpoint 2 file ./gcd.rb, line 10 18 | # break 11 19 | *** Line 11 is not a stopping point in file "gcd.rb". 20 | # continue 21 | Breakpoint 1 at gcd.rb:6 22 | gcd.rb:6 23 | if a > b 24 | # where 25 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 26 | #1 at line gcd.rb:18 27 | # break Object.gcd 28 | Breakpoint 3 at Object::gcd 29 | # info break 30 | Num Enb What 31 | 1 y at ./gcd.rb:6 32 | breakpoint already hit 1 time 33 | 2 y at ./gcd.rb:10 34 | 3 y at Object:gcd 35 | # continue 36 | Breakpoint 2 at gcd.rb:10 37 | gcd.rb:10 38 | return nil if a <= 0 39 | # where 40 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:10 41 | #1 at line gcd.rb:18 42 | # info program 43 | Program stopped. It stopped at a breakpoint. 44 | # c 6 45 | Breakpoint 3 at Object:gcd 46 | gcd.rb:4 47 | def gcd(a, b) 48 | # info break 49 | Num Enb What 50 | 1 y at ./gcd.rb:6 51 | breakpoint already hit 1 time 52 | 2 y at ./gcd.rb:10 53 | breakpoint already hit 1 time 54 | 3 y at Object:gcd 55 | breakpoint already hit 1 time 56 | # break foo 57 | *** Invalid breakpoint location: foo. 58 | # info break 59 | Num Enb What 60 | 1 y at ./gcd.rb:6 61 | breakpoint already hit 1 time 62 | 2 y at ./gcd.rb:10 63 | breakpoint already hit 1 time 64 | 3 y at Object:gcd 65 | breakpoint already hit 1 time 66 | # disable 1 67 | # info break 68 | Num Enb What 69 | 1 n at ./gcd.rb:6 70 | breakpoint already hit 1 time 71 | 2 y at ./gcd.rb:10 72 | breakpoint already hit 1 time 73 | 3 y at Object:gcd 74 | breakpoint already hit 1 time 75 | # delete 1 76 | # # We should see breakpoint 2 but not 1 77 | # info break 78 | Num Enb What 79 | 2 y at ./gcd.rb:10 80 | breakpoint already hit 1 time 81 | 3 y at Object:gcd 82 | breakpoint already hit 1 time 83 | # # We should still be able to access 2 84 | # disable 2 85 | # disable bar 86 | Disable breakpoints argument 'bar' needs to be a number. 87 | # disable 88 | *** "disable" must be followed "display", "breakpoints" or breakpoint numbers. 89 | # # We should be able to delete 2 90 | # delete 2 3 91 | # info break 92 | No breakpoints. 93 | # # Should get a message about having no breakpoints. 94 | # disable 1 95 | *** No breakpoints have been set. 96 | # enable 1 97 | *** No breakpoints have been set. 98 | # q! 99 | -------------------------------------------------------------------------------- /emacs/rdebug-error.el: -------------------------------------------------------------------------------- 1 | ;;; rdebug-error.el --- Ruby debugger error buffer 2 | 3 | ;; Copyright (C) 2008 Rocky Bernstein (rocky@gnu.org) 4 | ;; Copyright (C) 2008 Anders Lindgren 5 | 6 | ;; $Id: rdebug-error.el 713 2008-02-21 02:56:48Z rockyb $ 7 | 8 | ;; This program is free software; you can redistribute it and/or modify 9 | ;; it under the terms of the GNU General Public License as published by 10 | ;; the Free Software Foundation; either version 2, or (at your option) 11 | ;; any later version. 12 | 13 | ;; This program is distributed in the hope that it will be useful, 14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ;; GNU General Public License for more details. 17 | 18 | ;; You should have received a copy of the GNU General Public License 19 | ;; along with GNU Emacs; see the file COPYING. If not, write to the 20 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 21 | ;; Boston, MA 02111-1307, USA. 22 | 23 | ;;; Commentary: 24 | 25 | ;; See the manual and the file `rdebug.el' for more information. 26 | 27 | ;; This file contains code dealing with the error secondary buffer. 28 | 29 | ;;; Code: 30 | 31 | (require 'rdebug-dbg) 32 | (require 'rdebug-fns) 33 | (require 'rdebug-secondary) 34 | (require 'rdebug-source) 35 | 36 | (defun rdebug-display-error-buffer () 37 | "Display the rdebug error buffer." 38 | (interactive) 39 | (rdebug-display-secondary-buffer "error")) 40 | 41 | (defvar rdebug-error-mode-map 42 | (let ((map (make-sparse-keymap))) 43 | (rdebug-populate-secondary-buffer-map map) 44 | map) 45 | "Keymap used in the error buffer in the `rdebug' Ruby debugger.") 46 | 47 | (defun rdebug-error-mode () 48 | "Major mode for displaying the script error in the `rdebug' Ruby debugger. 49 | 50 | \\{rdebug-error-mode}" 51 | (interactive) 52 | (kill-all-local-variables) 53 | (setq major-mode 'rdebug-error-mode) 54 | (setq mode-name "RDEBUG Error") 55 | (setq buffer-read-only t) 56 | (set (make-local-variable 'rdebug-secondary-buffer) t) 57 | (setq mode-line-process 'rdebug-mode-line-process) 58 | (use-local-map rdebug-error-mode-map) 59 | (run-mode-hooks 'rdebug-error-mode-hook)) 60 | 61 | (defun rebug-setup-error-buffer (buf comint-buffer) 62 | (rdebug-debug-enter "rebug-setup-error-buffer" 63 | (with-current-buffer buf 64 | (rdebug-error-mode) 65 | (set (make-local-variable 'gud-comint-buffer) comint-buffer)))) 66 | 67 | (defun rdebug-errmsg (msg) 68 | ;;; (with-current-buffer (rdebug-get-buffer "error" gud-target-name) 69 | ;;; (goto-char (point-max)) 70 | ;;; (insert msg)) 71 | (message (chomp msg))) 72 | 73 | (provide 'rdebug-error) 74 | 75 | ;;; Local variables: 76 | ;;; eval:(put 'rdebug-debug-enter 'lisp-indent-hook 1) 77 | ;;; End: 78 | 79 | ;;; rdebug-error.el ends here 80 | -------------------------------------------------------------------------------- /emacs/rdebug-info.el: -------------------------------------------------------------------------------- 1 | ;;; rdebug-info.el --- This file contains code dealing with the Ruby 2 | ;;; debugger's info secondary buffer. 3 | 4 | ;; Copyright (C) 2008 Rocky Bernstein (rocky@gnu.org) 5 | ;; Copyright (C) 2008 Anders Lindgren 6 | 7 | ;; $Id: rdebug-breaks.el 670 2008-02-06 18:15:28Z rockyb $ 8 | 9 | ;; This program is free software; you can redistribute it and/or modify 10 | ;; it under the terms of the GNU General Public License as published by 11 | ;; the Free Software Foundation; either version 2, or (at your option) 12 | ;; any later version. 13 | 14 | ;; This program is distributed in the hope that it will be useful, 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | ;; GNU General Public License for more details. 18 | 19 | ;; You should have received a copy of the GNU General Public License 20 | ;; along with GNU Emacs; see the file COPYING. If not, write to the 21 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 22 | ;; Boston, MA 02111-1307, USA. 23 | 24 | ;;; Commentary: 25 | 26 | ;; See the manual and the file `rdebug.el' for more information. 27 | 28 | 29 | ;;; Code: 30 | 31 | (require 'rdebug-dbg) 32 | (require 'rdebug-gud) 33 | (require 'rdebug-regexp) 34 | (require 'rdebug-secondary) 35 | (require 'rdebug-source) 36 | (require 'rdebug-vars) 37 | 38 | (defun rdebug-display-info-buffer () 39 | "Display the rdebug breakpoints buffer." 40 | (interactive) 41 | (rdebug-display-secondary-buffer "info")) 42 | 43 | (defvar rdebug-info-mode-map 44 | (let ((map (make-sparse-keymap))) 45 | (rdebug-populate-secondary-buffer-map map) 46 | map) 47 | "Keymap for the Rdebug info secondary buffer.") 48 | 49 | (defun rdebug-info-mode () 50 | "Major mode for Ruby debugger info buffer. 51 | 52 | \\{rdebug-info-mode-map}" 53 | (kill-all-local-variables) 54 | (setq major-mode 'rdebug-info-mode) 55 | (setq mode-name "RDEBUG Info") 56 | (use-local-map rdebug-info-mode-map) 57 | (setq buffer-read-only t) 58 | (set (make-local-variable 'rdebug-secondary-buffer) t) 59 | (setq mode-line-process 'rdebug-mode-line-process) 60 | (run-mode-hooks 'rdebug-info-mode-hook)) 61 | 62 | (defun rdebug-setup-info-buffer (buf comint-buffer) 63 | "Setup the Rdebug debugger info buffer." 64 | (rdebug-debug-enter "rdebug-setup-info-buffer" 65 | (with-current-buffer buf 66 | (let ((inhibit-read-only t) 67 | (old-line-number (buffer-local-value 'rdebug-current-line-number 68 | buf))) 69 | (rdebug-info-mode) 70 | (goto-line old-line-number))))) 71 | 72 | 73 | ;; ------------------------------------------------------------------- 74 | ;; The end. 75 | ;; 76 | 77 | (provide 'rdebug-info) 78 | 79 | ;;; Local variables: 80 | ;;; eval:(put 'rdebug-debug-enter 'lisp-indent-hook 1) 81 | ;;; End: 82 | 83 | ;;; rdebug-info.el ends here 84 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/list.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | # Implements debugger "list" command. 3 | class ListCommand < Command 4 | 5 | register_setting_get(:autolist) do 6 | ListCommand.always_run 7 | end 8 | register_setting_set(:autolist) do |value| 9 | ListCommand.always_run = value 10 | end 11 | 12 | def regexp 13 | /^\s* l(?:ist)? (?:\s*([-=])|\s+(.+))? $/x 14 | end 15 | 16 | def execute 17 | listsize = Command.settings[:listsize] 18 | if !@match || !(@match[1] || @match[2]) 19 | b = @state.previous_line ? 20 | @state.previous_line + listsize : @state.line - (listsize/2) 21 | e = b + listsize - 1 22 | elsif @match[1] == '-' 23 | b = if @state.previous_line 24 | if @state.previous_line > 0 25 | @state.previous_line - listsize 26 | else 27 | @state.previous_line 28 | end 29 | else 30 | @state.line - (listsize/2) 31 | end 32 | e = b + listsize - 1 33 | elsif @match[1] == '=' 34 | @state.previous_line = nil 35 | b = @state.line - (listsize/2) 36 | e = b + listsize -1 37 | else 38 | b, e = @match[2].split(/[-,]/) 39 | if e 40 | b = b.to_i 41 | e = e.to_i 42 | else 43 | b = b.to_i - (listsize/2) 44 | e = b + listsize - 1 45 | end 46 | end 47 | @state.previous_line = display_list(b, e, @state.file, @state.line) 48 | end 49 | 50 | class << self 51 | def help_command 52 | 'list' 53 | end 54 | 55 | def help(cmd) 56 | %{ 57 | l[ist]\t\tlist forward 58 | l[ist] -\tlist backward 59 | l[ist] =\tlist current line 60 | l[ist] nn-mm\tlist given lines 61 | * NOTE - to turn on autolist, use 'set autolist' 62 | } 63 | end 64 | end 65 | 66 | private 67 | 68 | # Show FILE from line B to E where CURRENT is the current line number. 69 | # If we can show from B to E then we return B, otherwise we return the 70 | # previous line @state.previous_line. 71 | def display_list(b, e, file, current) 72 | print "[%d, %d] in %s\n", b, e, file 73 | lines = LineCache::getlines(file, 74 | Command.settings[:reload_source_on_change]) 75 | if lines 76 | return @state.previous_line if b >= lines.size 77 | e = lines.size if lines.size < e 78 | [b, 1].max.upto(e) do |n| 79 | if n > 0 && lines[n-1] 80 | if n == current 81 | print "=> %d %s\n", n, lines[n-1].chomp 82 | else 83 | print " %d %s\n", n, lines[n-1].chomp 84 | end 85 | end 86 | end 87 | else 88 | errmsg "No sourcefile available for %s\n", file 89 | return @state.previous_line 90 | end 91 | return e == lines.size ? @state.previous_line : b 92 | end 93 | end 94 | end 95 | -------------------------------------------------------------------------------- /test/data/annotate.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # ******************************************************** 4 | # # This tests annotations 5 | # # ******************************************************** 6 | # set debuggertesting on 7 | Currently testing the debugger is on. 8 | # set callstyle last 9 | Frame call-display style is last. 10 | # set force off 11 | force-stepping is off. 12 | # set annotate 3 13 | Annotation level is 3 14 | # # Get into gcd 15 | # step 2 16 | starting 17 | stopped 18 | breakpoints 19 | No breakpoints. 20 |  21 | stack 22 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 23 | #1 at line gcd.rb:18 24 |  25 | variables 26 | a = 3 27 | b = 5 28 | self = main 29 |  30 | source gcd.rb:6 31 | if a > b 32 | # # "break" should trigger break annotation 33 | # break 10 34 | Breakpoint 1 file ./gcd.rb, line 10 35 | breakpoints 36 | Num Enb What 37 | 1 y at ./gcd.rb:10 38 |  39 | # # "delete" should trigger break annotation 40 | # delete 1 41 | breakpoints 42 | No breakpoints. 43 |  44 | # # p should not trigger a breakpoint annotation 45 | # p a 46 | 3 47 | # # "up" should trigger annotations 48 | # up 49 | #1 at line gcd.rb:18 50 | stack 51 | #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 52 | --> #1 at line gcd.rb:18 53 |  54 | variables 55 | self = main 56 |  57 | # # "b" should trigger like "break" 58 | # b 12 59 | Breakpoint 2 file ./gcd.rb, line 12 60 | breakpoints 61 | Num Enb What 62 | 2 y at ./gcd.rb:12 63 |  64 | # # "display" should trigger display annotation 65 | # display 1+2 66 | 1: 1+2 = 3 67 | display 68 | 1: 1+2 = 3 69 |  70 | # # undisplay should trigger display annotation 71 | # undisplay 1 72 | display 73 |  74 | # step 75 | display 76 |  77 | starting 78 | stopped 79 | breakpoints 80 | Num Enb What 81 | 2 y at ./gcd.rb:12 82 |  83 | display 84 |  85 | stack 86 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:10 87 | #1 at line gcd.rb:18 88 |  89 | variables 90 | a = 3 91 | b = 5 92 | self = main 93 |  94 | source gcd.rb:10 95 | return nil if a <= 0 96 | # # Test error annotations 97 | # up 10 98 | error-begin 99 | Adjusting would put us beyond the oldest (initial) frame. 100 |  101 | display 102 |  103 | stack 104 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:10 105 | #1 at line gcd.rb:18 106 |  107 | variables 108 | a = 3 109 | b = 5 110 | self = main 111 |  112 | # frame 100 113 | error-begin 114 | Adjusting would put us beyond the oldest (initial) frame. 115 |  116 | display 117 |  118 | stack 119 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:10 120 | #1 at line gcd.rb:18 121 |  122 | variables 123 | a = 3 124 | b = 5 125 | self = main 126 |  127 | # break bogus:5 128 | error-begin 129 | No source file named bogus 130 |  131 | Breakpoint 3 file bogus, line 5 132 | breakpoints 133 | Num Enb What 134 | 2 y at ./gcd.rb:12 135 | 3 y at bogus:5 136 |  137 | display 138 |  139 | # quit! 140 | -------------------------------------------------------------------------------- /test/data/list.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # ******************************************************** 4 | # # This tests the 'list' command. 5 | # # ******************************************************** 6 | # set basename on 7 | basename is on. 8 | # list 9 | [-1, 8] in ./gcd.rb 10 | 1 #!/usr/bin/env ruby 11 | 2 12 | 3 # GCD. We assume positive numbers 13 | => 4 def gcd(a, b) 14 | 5 # Make: a <= b 15 | 6 if a > b 16 | 7 a, b = [b, a] 17 | 8 end 18 | # list 19 | [9, 18] in ./gcd.rb 20 | 9 21 | 10 return nil if a <= 0 22 | 11 23 | 12 if a == 1 or b-a == 0 24 | 13 return a 25 | 14 end 26 | 15 gcd(b-a, a) 27 | 16 end 28 | 17 29 | 18 gcd(3,5) 30 | # list 31 | [9, 18] in ./gcd.rb 32 | 9 33 | 10 return nil if a <= 0 34 | 11 35 | 12 if a == 1 or b-a == 0 36 | 13 return a 37 | 14 end 38 | 15 gcd(b-a, a) 39 | 16 end 40 | 17 41 | 18 gcd(3,5) 42 | # list 43 | [9, 18] in ./gcd.rb 44 | 9 45 | 10 return nil if a <= 0 46 | 11 47 | 12 if a == 1 or b-a == 0 48 | 13 return a 49 | 14 end 50 | 15 gcd(b-a, a) 51 | 16 end 52 | 17 53 | 18 gcd(3,5) 54 | # list - 55 | [-1, 8] in ./gcd.rb 56 | 1 #!/usr/bin/env ruby 57 | 2 58 | 3 # GCD. We assume positive numbers 59 | => 4 def gcd(a, b) 60 | 5 # Make: a <= b 61 | 6 if a > b 62 | 7 a, b = [b, a] 63 | 8 end 64 | # list - 65 | [-1, 8] in ./gcd.rb 66 | 1 #!/usr/bin/env ruby 67 | 2 68 | 3 # GCD. We assume positive numbers 69 | => 4 def gcd(a, b) 70 | 5 # Make: a <= b 71 | 6 if a > b 72 | 7 a, b = [b, a] 73 | 8 end 74 | # list - 75 | [-1, 8] in ./gcd.rb 76 | 1 #!/usr/bin/env ruby 77 | 2 78 | 3 # GCD. We assume positive numbers 79 | => 4 def gcd(a, b) 80 | 5 # Make: a <= b 81 | 6 if a > b 82 | 7 a, b = [b, a] 83 | 8 end 84 | # list - 85 | [-1, 8] in ./gcd.rb 86 | 1 #!/usr/bin/env ruby 87 | 2 88 | 3 # GCD. We assume positive numbers 89 | => 4 def gcd(a, b) 90 | 5 # Make: a <= b 91 | 6 if a > b 92 | 7 a, b = [b, a] 93 | 8 end 94 | # list 1 95 | [-4, 5] in ./gcd.rb 96 | 1 #!/usr/bin/env ruby 97 | 2 98 | 3 # GCD. We assume positive numbers 99 | => 4 def gcd(a, b) 100 | 5 # Make: a <= b 101 | # list 20 102 | [15, 24] in ./gcd.rb 103 | 15 gcd(b-a, a) 104 | 16 end 105 | 17 106 | 18 gcd(3,5) 107 | # set listsize 5 108 | Number of source lines to list by default is 5. 109 | # list 5 110 | [3, 7] in ./gcd.rb 111 | 3 # GCD. We assume positive numbers 112 | => 4 def gcd(a, b) 113 | 5 # Make: a <= b 114 | 6 if a > b 115 | 7 a, b = [b, a] 116 | # list = 117 | [2, 6] in ./gcd.rb 118 | 2 119 | 3 # GCD. We assume positive numbers 120 | => 4 def gcd(a, b) 121 | 5 # Make: a <= b 122 | 6 if a > b 123 | # list 3-4 124 | [3, 4] in ./gcd.rb 125 | 3 # GCD. We assume positive numbers 126 | => 4 def gcd(a, b) 127 | # 128 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/display.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | module DisplayFunctions # :nodoc: 3 | def display_expression(exp) 4 | print "%s = %s\n", exp, debug_silent_eval(exp).to_s 5 | end 6 | 7 | def active_display_expressions? 8 | @state.display.select{|d| d[0]}.size > 0 9 | end 10 | 11 | def print_display_expressions 12 | n = 1 13 | for d in @state.display 14 | if d[0] 15 | print "%d: ", n 16 | display_expression(d[1]) 17 | end 18 | n += 1 19 | end 20 | end 21 | end 22 | 23 | class AddDisplayCommand < Command # :nodoc: 24 | def regexp 25 | /^\s*disp(?:lay)?\s+(.+)$/ 26 | end 27 | 28 | def execute 29 | exp = @match[1] 30 | @state.display.push [true, exp] 31 | print "%d: ", @state.display.size 32 | display_expression(exp) 33 | end 34 | 35 | class << self 36 | def help_command 37 | 'display' 38 | end 39 | 40 | def help(cmd) 41 | %{ 42 | disp[lay] \tadd expression into display expression list 43 | } 44 | end 45 | end 46 | end 47 | 48 | class DisplayCommand < Command # :nodoc: 49 | def self.always_run 50 | Debugger.annotate = 0 unless Debugger.annotate 51 | if Debugger.annotate > 1 52 | 0 53 | else 54 | 2 55 | end 56 | end 57 | 58 | def regexp 59 | /^\s*disp(?:lay)?$/ 60 | end 61 | 62 | def execute 63 | print_display_expressions 64 | end 65 | 66 | class << self 67 | def help_command 68 | 'display' 69 | end 70 | 71 | def help(cmd) 72 | %{ 73 | disp[lay]\t\tdisplay expression list 74 | } 75 | end 76 | end 77 | end 78 | 79 | class DeleteDisplayCommand < Command # :nodoc: 80 | 81 | def regexp 82 | /^\s* undisp(?:lay)? \s* (?:(\S+))?$/x 83 | end 84 | 85 | def execute 86 | unless pos = @match[1] 87 | if confirm("Clear all expressions? (y/n) ") 88 | for d in @state.display 89 | d[0] = false 90 | end 91 | end 92 | else 93 | pos = get_int(pos, "Undisplay") 94 | return unless pos 95 | if @state.display[pos-1] 96 | @state.display[pos-1][0] = nil 97 | else 98 | errmsg "Display expression %d is not defined.\n", pos 99 | end 100 | end 101 | end 102 | 103 | class << self 104 | def help_command 105 | 'undisplay' 106 | end 107 | 108 | def help(cmd) 109 | %{ 110 | undisp[lay][ nnn] 111 | Cancel some expressions to be displayed when program stops. 112 | Arguments are the code numbers of the expressions to stop displaying. 113 | No argument means cancel all automatic-display expressions. 114 | "delete display" has the same effect as this command. 115 | Do "info display" to see current list of code numbers. 116 | } 117 | end 118 | end 119 | end 120 | end 121 | -------------------------------------------------------------------------------- /test/data/emacs_basic.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # ******************************************************** 4 | # # This tests step, next, finish, continue, disable and 5 | # # enable. 6 | # # FIXME: break out enable/disable 7 | # # ******************************************************** 8 | # set debuggertesting on 9 | Currently testing the debugger is on. 10 | # set callstyle last 11 | Frame call-display style is last. 12 | # set autoeval off 13 | autoeval is off. 14 | # break 6 15 | Breakpoint 1 file ./gcd.rb, line 6 16 | # break 10 17 | Breakpoint 2 file ./gcd.rb, line 10 18 | # continue 19 | Breakpoint 1 at gcd.rb:6 20 | gcd.rb:6 21 | if a > b 22 | # where 23 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6 24 | #1 at line gcd.rb:18 25 | # break Foo.bar 26 | *** Unknown class Foo. 27 | # break Object.gcd 28 | Breakpoint 3 at Object::gcd 29 | # info break 30 | Num Enb What 31 | 1 y at ./gcd.rb:6 32 | breakpoint already hit 1 time 33 | 2 y at ./gcd.rb:10 34 | 3 y at Object:gcd 35 | # continue 36 | Breakpoint 2 at gcd.rb:10 37 | gcd.rb:10 38 | return nil if a <= 0 39 | # where 40 | --> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:10 41 | #1 at line gcd.rb:18 42 | # info program 43 | Program stopped. It stopped at a breakpoint. 44 | # c 10 45 | Breakpoint 3 at Object:gcd 46 | gcd.rb:4 47 | def gcd(a, b) 48 | # info break 49 | Num Enb What 50 | 1 y at ./gcd.rb:6 51 | breakpoint already hit 1 time 52 | 2 y at ./gcd.rb:10 53 | breakpoint already hit 1 time 54 | 3 y at Object:gcd 55 | breakpoint already hit 1 time 56 | # break foo 57 | *** Invalid breakpoint location: foo. 58 | # info break 59 | Num Enb What 60 | 1 y at ./gcd.rb:6 61 | breakpoint already hit 1 time 62 | 2 y at ./gcd.rb:10 63 | breakpoint already hit 1 time 64 | 3 y at Object:gcd 65 | breakpoint already hit 1 time 66 | # disable 1 67 | # info break 68 | Num Enb What 69 | 1 n at ./gcd.rb:6 70 | breakpoint already hit 1 time 71 | 2 y at ./gcd.rb:10 72 | breakpoint already hit 1 time 73 | 3 y at Object:gcd 74 | breakpoint already hit 1 time 75 | # enable breakpoint 1 76 | # enable br 10 77 | Enable breakpoints argument '10' needs to at most 3. 78 | # delete 1 79 | # # We should see breakpoint 2 but not 1 80 | # info break 81 | Num Enb What 82 | 2 y at ./gcd.rb:10 83 | breakpoint already hit 1 time 84 | 3 y at Object:gcd 85 | breakpoint already hit 1 time 86 | # # We should still be able to access 2 87 | # disable 2 88 | # enable 89 | *** "enable" must be followed "display", "breakpoints" or breakpoint numbers. 90 | # enable foo 91 | Enable breakpoints argument 'foo' needs to be a number. 92 | # disable bar 93 | Disable breakpoints argument 'bar' needs to be a number. 94 | # disable 95 | *** "disable" must be followed "display", "breakpoints" or breakpoint numbers. 96 | # # We should be able to delete 2 97 | # delete 2 3 98 | # info break 99 | No breakpoints. 100 | # # Should get a message about having no breakpoints. 101 | # disable 1 102 | *** No breakpoints have been set. 103 | # enable 1 104 | *** No breakpoints have been set. 105 | # # finish 106 | # quit 107 | -------------------------------------------------------------------------------- /test/data/setshow.right: -------------------------------------------------------------------------------- 1 | gcd.rb:4 2 | def gcd(a, b) 3 | # # This tests the functioning of some set/show debugger commands 4 | # set debuggertesting on 5 | Currently testing the debugger is on. 6 | # ### ******************************* 7 | # ### *** Set/show commands *** 8 | # ### ******************************* 9 | # ######################################## 10 | # ### test args and baseneme... 11 | # ######################################## 12 | # set args this is a test 13 | Argument list to give program being debugged when it is started is "this is a test". 14 | # show args 15 | Argument list to give program being debugged when it is started is "this is a test". 16 | # show basename 17 | basename is on. 18 | # set basename foo 19 | Expecting 'on', 1, 'off', or 0. Got: foo. 20 | # show base 21 | basename is on. 22 | # set basename off 23 | basename is off. 24 | # show basename 25 | basename is off. 26 | # set basename 0 27 | basename is off. 28 | # show basename 29 | basename is off. 30 | # set basename 1 31 | basename is on. 32 | # show basename 33 | basename is on. 34 | # ######################################## 35 | # ### test listsize tests... 36 | # ######################################## 37 | # show listsize 38 | Number of source lines to list by default is 10. 39 | # show listsi 40 | Number of source lines to list by default is 10. 41 | # set listsize abc 42 | Set listsize argument 'abc' needs to be a number. 43 | # set listsize -20 44 | Set listsize argument '-20' needs to at least 1. 45 | # ######################################## 46 | # ### test linetrace... 47 | # ######################################## 48 | # set linetrace on 49 | line tracing is on. 50 | # show linetrace 51 | line tracing is on. 52 | # set linetrace off 53 | line tracing is off. 54 | # show linetrace 55 | line tracing is off. 56 | # ######################################## 57 | # ### show history 58 | # ######################################## 59 | # set history 60 | Need two parameters for 'set history'; got 0. 61 | # set history size 10 62 | Debugger history size is 10 63 | # show history size 64 | Debugger history size is 10 65 | # set history save off 66 | Saving of history save is off. 67 | # show history save 68 | Saving of history save is off. 69 | # set history save 1 70 | Saving of history save is on. 71 | # show history save 72 | Saving of history save is on. 73 | # #### Test 'autoeval'... 74 | # set autoeval on 75 | autoeval is on. 76 | # puts 'printed via autoeval' 77 | printed via autoeval 78 | nil 79 | # set autoeval off 80 | autoeval is off. 81 | # puts 'autoeval should not run this' 82 | *** Unknown command: "puts 'autoeval should not run this'". Try "help". 83 | # #### Test 'callstyle'... 84 | # set callstyle 85 | Invalid call style . Should be one of: 'short' or 'last'. 86 | Frame call-display style is last. 87 | # set callstyle short 88 | Frame call-display style is short. 89 | # set callstyle last 90 | Frame call-display style is last. 91 | # set callstyle tracked 92 | Invalid call style tracked. Should be one of: 'short' or 'last'. 93 | Frame call-display style is last. 94 | # set callstyle foo 95 | Invalid call style foo. Should be one of: 'short' or 'last'. 96 | Frame call-display style is last. 97 | # 98 | # 99 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/control.rb: -------------------------------------------------------------------------------- 1 | module Debugger 2 | class RestartCommand < Command # :nodoc: 3 | self.allow_in_control = true 4 | 5 | def regexp 6 | / ^\s* 7 | (?:restart|R) 8 | (?:\s+ (\S?.*\S))? \s* 9 | $ 10 | /ix 11 | end 12 | 13 | def execute 14 | if not defined? Debugger::PROG_SCRIPT 15 | errmsg "Don't know name of debugged program\n" 16 | return 17 | end 18 | prog_script = Debugger::PROG_SCRIPT 19 | if not defined? Debugger::RDEBUG_SCRIPT 20 | # FIXME? Should ask for confirmation? 21 | print "Debugger was not called from the outset...\n" 22 | rdebug_script = prog_script 23 | else 24 | rdebug_script = Debugger::RDEBUG_SCRIPT 25 | end 26 | begin 27 | Dir.chdir(Debugger::INITIAL_DIR) 28 | rescue 29 | print "Failed to change initial directory #{Debugger::INITIAL_DIR}" 30 | end 31 | if not File.exist?(File.expand_path(prog_script)) 32 | errmsg "Ruby program #{prog_script} doesn't exist\n" 33 | return 34 | end 35 | if not File.executable?(prog_script) and rdebug_script == prog_script 36 | print "Ruby program #{prog_script} doesn't seem to be executable...\n" 37 | print "We'll add a call to Ruby.\n" 38 | ruby = begin defined?(Gem) ? Gem.ruby : "ruby" rescue "ruby" end 39 | rdebug_script = "#{ruby} -I#{$:.join(' -I')} #{prog_script}" 40 | else 41 | rdebug_script += ' ' 42 | end 43 | if @match[1] 44 | argv = [prog_script] + @match[1].split(/[ \t]+/) 45 | else 46 | if not defined? Command.settings[:argv] 47 | errmsg "Arguments have not been set. Use 'set args' to set them.\n" 48 | return 49 | else 50 | argv = Command.settings[:argv] 51 | end 52 | end 53 | args = argv.join(' ') 54 | 55 | # An execv would be preferable to the "exec" below. 56 | cmd = rdebug_script + args 57 | print "Re exec'ing:\n\t#{cmd}\n" 58 | exec cmd 59 | rescue Errno::EOPNOTSUPP 60 | print "Restart command is not available at this time.\n" 61 | end 62 | 63 | class << self 64 | def help_command 65 | 'restart' 66 | end 67 | 68 | def help(cmd) 69 | %{ 70 | restart|R [args] 71 | Restart the program. This is a re-exec - all debugger state 72 | is lost. If command arguments are passed those are used. 73 | } 74 | end 75 | end 76 | end 77 | 78 | class InterruptCommand < Command # :nodoc: 79 | self.allow_in_control = true 80 | self.allow_in_post_mortem = false 81 | self.event = false 82 | self.need_context = true 83 | 84 | def regexp 85 | /^\s*i(?:nterrupt)?\s*$/ 86 | end 87 | 88 | def execute 89 | unless Debugger.interrupt_last 90 | context = Debugger.thread_context(Thread.main) 91 | context.interrupt 92 | end 93 | end 94 | 95 | class << self 96 | def help_command 97 | 'interrupt' 98 | end 99 | 100 | def help(cmd) 101 | %{ 102 | i[nterrupt]\tinterrupt the program 103 | } 104 | end 105 | end 106 | end 107 | end 108 | -------------------------------------------------------------------------------- /test/data/ctrl.right: -------------------------------------------------------------------------------- 1 | Currently testing the debugger is on. 2 | width is 80. 3 | Type 'help ' for help on a specific command 4 | 5 | Available commands: 6 | break edit help jump pp quit save skip 7 | catch eval info kill ps reload set source 8 | delete exit interrupt p putl restart show thread 9 | 10 | Generic command for showing things about the program being debugged. 11 | -- 12 | List of info subcommands: 13 | -- 14 | info args -- Argument variables of current stack frame 15 | info breakpoints -- Status of user-settable breakpoints 16 | info catch -- Exceptions that can be caught in the current stack frame 17 | info display -- Expressions to display when program stops 18 | info file -- Info about a particular file read in 19 | info files -- File names and timestamps of files read in 20 | info global_variables -- Global variables 21 | info instance_variables -- Instance variables of the current stack frame 22 | info line -- Line number and file name of current position in source file 23 | info locals -- Local variables of the current stack frame 24 | info program -- Execution status of the program 25 | info stack -- Backtrace of the stack 26 | info thread -- List info about thread NUM 27 | info threads -- information of currently-known threads 28 | info variables -- Local and instance variables of the current stack frame 29 | No frame selected. 30 | info breakpoints not available here. 31 | info display not available here. 32 | The program being debugged is not being run. 33 | info global_variables not available here. 34 | info line not available here. 35 | info line not available here. 36 | info stack not available here. 37 | info threads not available here. 38 | info variables not available here. 39 | 3 40 | Generic command for showing things about the debugger. 41 | 42 | -- 43 | List of show subcommands: 44 | -- 45 | show annotate -- Show annotation level 46 | show args -- Show argument list to give program being debugged when it is started 47 | show autoeval -- Show if unrecognized command are evaluated 48 | show autolist -- Show if 'list' commands is run on breakpoints 49 | show autoirb -- Show if IRB is invoked on debugger stops 50 | show autoreload -- Show if source code is reloaded when changed 51 | show basename -- Show if basename used in reporting files 52 | show callstyle -- Show paramater style used showing call frames 53 | show commands -- Show the history of commands you typed 54 | show forcestep -- Show if sure 'next/step' forces move to a new line 55 | show fullpath -- Show if full file names are displayed in frames 56 | show history -- Generic command for showing command history parameters 57 | show keep-frame-bindings -- Save frame binding on each call 58 | show linetrace -- Show line execution tracing 59 | show linetrace+ -- Show if consecutive lines should be different are shown in tracing 60 | show listsize -- Show number of source lines to list by default 61 | show port -- Show server port 62 | show post-mortem -- Show whether we go into post-mortem debugging on an uncaught exception 63 | show trace -- Show if a stack trace is displayed when 'eval' raises exception 64 | show version -- Show what version of the debugger this is 65 | show width -- Show the number of characters the debugger thinks are in a line 66 | Displaying stack trace is off. 67 | Displaying stack trace is off. 68 | Displaying stack trace is on. 69 | Annotation level is 0 70 | Annotation level is 0 71 | -------------------------------------------------------------------------------- /emacs/test/test-annotate.el: -------------------------------------------------------------------------------- 1 | ;; -*- emacs-lisp -*- 2 | ;; This program has to be run from the directory it is currently in and 3 | ;; the rdebug code has to be in the parent directory 4 | (load-file "./elk-test.el") 5 | 6 | ;; FIXME? Should we use "require 'rdebug" here. 7 | ;; Would have to prepend . to load-path. 8 | (load-file "../rdebug.el") 9 | (load-file "../rdebug-annotate.el") 10 | 11 | (defvar last-annotation nil 12 | "Value of the last annotation processed") 13 | 14 | ;; Redefine functions to make them harmless for testing 15 | (defun rdebug-process-annotation (name contents) 16 | (setq last-annotation name)) 17 | 18 | (make-variable-buffer-local 'gud-rdebug-marker-acc) 19 | 20 | ;; ------------------------------------------------------------------- 21 | ;; Test harness for testing the filter. 22 | ;; 23 | 24 | (require 'advice) 25 | 26 | (defvar rdebug-test-cmd-list '()) 27 | 28 | ;; Override, partially because tooltip-show doesn't work in batch 29 | ;; mode, and partially because we collect the output here. 30 | (defun tooltip-show (text) 31 | (setq rdebug-test-cmd-list (cons text rdebug-test-cmd-list))) 32 | 33 | (defun assert-filter (output str &optional cmd-list) 34 | (setq rdebug-test-cmd-list '()) 35 | (setq gud-marker-acc "") 36 | (let ((orig-queue rdebug-call-queue)) 37 | (let ((real-output (gud-rdebug-marker-filter str))) 38 | (assert-equal output real-output) 39 | (assert-equal cmd-list (reverse rdebug-test-cmd-list))) 40 | 41 | ;; 42 | ;; Feed the filter one character at a time -- the end result should 43 | ;; be the same. 44 | ;; 45 | (setq rdebug-test-cmd-list '()) 46 | (setq gud-marker-acc "") 47 | (let ((real-output "") 48 | (len (length str)) 49 | (i 0) 50 | (rdebug-call-queue orig-queue)) 51 | (while (< i len) 52 | (setq real-output 53 | (concat real-output 54 | (gud-rdebug-marker-filter 55 | (substring str i (if (equal (+ 1 i) len) 56 | nil 57 | (+ 1 i)))))) 58 | (setq i (+ 1 i))) 59 | (assert-equal output real-output) 60 | (assert-equal cmd-list (reverse rdebug-test-cmd-list))))) 61 | 62 | 63 | (deftest "rdebug-filter" 64 | ;;; (assert-filter "X" "X") 65 | ;;; (assert-filter "XYZ" "XYZ") 66 | ;;; (assert-filter "" "\n") 67 | ;;; (assert-filter "Testing 1 2 3" "Testing 1 2 3") 68 | ;;; (assert-filter "Testing 1 2 3" "Testing 1 2 3") 69 | ;;; (assert-filter "ABC" "\ 70 | ;;; breakpoints 71 | ;;; No breakpoints 72 | ;;;  73 | ;;; ABC") 74 | 75 | ;; Some systems (read: Mac) echoes the command. 76 | (setq rdebug-call-queue '(("pp 100" :tooltip))) 77 | (assert-filter "pp 100\n100\n(rdb:1) " "\ 78 | prompt 79 | pp 100\n100 80 | pre-prompt 81 | \(rdb:1) \nprompt\n" 82 | '("100\n")) 83 | 84 | ;; Some systems don't echo the command. 85 | (setq rdebug-call-queue '(("pp 100" :tooltip))) 86 | (assert-filter "100\n(rdb:1) " "\ 87 | prompt 88 | 100 89 | pre-prompt 90 | \(rdb:1) \nprompt\n" 91 | '("100\n")) 92 | ) 93 | 94 | 95 | ;; ------------------------------------------------------------------- 96 | ;; Build and run the test suite. 97 | ;; 98 | 99 | (build-suite "rdebug-suite" 100 | "rdebug-filter") 101 | 102 | (run-elk-test "rdebug-suite" 103 | "test regular expressions used in tracking lines") 104 | -------------------------------------------------------------------------------- /cli/ruby-debug/commands/irb.rb: -------------------------------------------------------------------------------- 1 | require 'irb' 2 | 3 | module IRB # :nodoc: 4 | module ExtendCommand # :nodoc: 5 | class Continue # :nodoc: 6 | def self.execute(conf) 7 | throw :IRB_EXIT, :cont 8 | end 9 | end 10 | class Next # :nodoc: 11 | def self.execute(conf) 12 | throw :IRB_EXIT, :next 13 | end 14 | end 15 | class Step # :nodoc: 16 | def self.execute(conf) 17 | throw :IRB_EXIT, :step 18 | end 19 | end 20 | end 21 | ExtendCommandBundle.def_extend_command "cont", :Continue 22 | ExtendCommandBundle.def_extend_command "n", :Next 23 | ExtendCommandBundle.def_extend_command "step", :Step 24 | 25 | def self.start_session(binding) 26 | unless @__initialized 27 | args = ARGV.dup 28 | ARGV.replace([]) 29 | IRB.setup(nil) 30 | ARGV.replace(args) 31 | @__initialized = true 32 | end 33 | 34 | workspace = WorkSpace.new(binding) 35 | 36 | irb = Irb.new(workspace) 37 | 38 | @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC] 39 | @CONF[:MAIN_CONTEXT] = irb.context 40 | 41 | catch(:IRB_EXIT) do 42 | irb.eval_input 43 | end 44 | end 45 | end 46 | 47 | module Debugger 48 | 49 | # Implements debugger "irb" command. 50 | class IRBCommand < Command 51 | 52 | register_setting_get(:autoirb) do 53 | IRBCommand.always_run 54 | end 55 | register_setting_set(:autoirb) do |value| 56 | IRBCommand.always_run = value 57 | end 58 | 59 | def regexp 60 | /^\s* irb 61 | (?:\s+(-d))? 62 | \s*$/x 63 | end 64 | 65 | def execute 66 | unless @state.interface.kind_of?(LocalInterface) 67 | print "Command is available only in local mode.\n" 68 | throw :debug_error 69 | end 70 | 71 | save_trap = trap("SIGINT") do 72 | throw :IRB_EXIT, :cont if $rdebug_in_irb 73 | end 74 | 75 | add_debugging = @match.is_a?(Array) && '-d' == @match[1] 76 | $rdebug_state = @state if add_debugging 77 | $rdebug_in_irb = true 78 | cont = IRB.start_session(get_binding) 79 | case cont 80 | when :cont 81 | @state.proceed 82 | when :step 83 | force = Command.settings[:force_stepping] 84 | @state.context.step(1, force) 85 | @state.proceed 86 | when :next 87 | force = Command.settings[:force_stepping] 88 | @state.context.step_over(1, @state.frame_pos, force) 89 | @state.proceed 90 | else 91 | file = @state.context.frame_file(0) 92 | line = @state.context.frame_line(0) 93 | CommandProcessor.print_location_and_text(file, line) 94 | @state.previous_line = nil 95 | end 96 | 97 | ensure 98 | $rdebug_in_irb = nil 99 | $rdebug_state = nil if add_debugging 100 | trap("SIGINT", save_trap) if save_trap 101 | end 102 | 103 | class << self 104 | def help_command 105 | 'irb' 106 | end 107 | 108 | def help(cmd) 109 | %{ 110 | irb [-d]\tstarts an Interactive Ruby (IRB) session. 111 | 112 | If -d is added you can get access to debugger state via the global variable 113 | $RDEBUG_state. 114 | 115 | irb is extended with methods "cont", "n" and "step" which 116 | run the corresponding debugger commands. In contrast to the real debugger 117 | commands these commands don't allow command arguments. 118 | } 119 | end 120 | end 121 | end 122 | end 123 | 124 | -------------------------------------------------------------------------------- /emacs/rdebug-cmd.el: -------------------------------------------------------------------------------- 1 | ;;; rdebug-cmd.el --- Ruby debugger command buffer 2 | 3 | ;; Copyright (C) 2008 Rocky Bernstein (rocky@gnu.org) 4 | ;; Copyright (C) 2008 Anders Lindgren 5 | 6 | ;; $Id: rdebug-cmd.el 822 2008-04-27 08:28:29Z rockyb $ 7 | 8 | ;; This program is free software; you can redistribute it and/or modify 9 | ;; it under the terms of the GNU General Public License as published by 10 | ;; the Free Software Foundation; either version 2, or (at your option) 11 | ;; any later version. 12 | 13 | ;; This program is distributed in the hope that it will be useful, 14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ;; GNU General Public License for more details. 17 | 18 | ;; You should have received a copy of the GNU General Public License 19 | ;; along with GNU Emacs; see the file COPYING. If not, write to the 20 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 21 | ;; Boston, MA 02111-1307, USA. 22 | 23 | ;;; Commentary: 24 | 25 | ;; See the manual and the file `rdebug.el' for more information. 26 | 27 | ;; This file contains code dealing primarily with the command buffer. 28 | 29 | ;;; Code: 30 | 31 | (require 'ring) 32 | (require 'rdebug-locring) 33 | 34 | (defun rdebug-command-initialization () 35 | "Initialization of command buffer common to `rdebug' and`rdebug-track-attach'." 36 | 37 | ;; This opens up "Gud" menu, which isn't used since we've got our 38 | ;; own "Debugger" menu. 39 | ;; (set (make-local-variable 'gud-minor-mode) 'rdebug) 40 | 41 | (set (make-local-variable 'rdebug-call-queue) '()) 42 | (set (make-local-variable 'rdebug-original-read-only) buffer-read-only) 43 | (make-local-variable 'rdebug-source-location-ring-size) ; ...to global val. 44 | (set (make-local-variable 'rdebug-source-location-ring) 45 | (make-ring rdebug-source-location-ring-size)) 46 | (make-local-variable 'rdebug-source-location-ring-index) 47 | (rdebug-locring-clear) 48 | 49 | (gud-def gud-args "info args" "a" 50 | "Show arguments of current stack frame.") 51 | (gud-def gud-break "break %d%f:%l""\C-b" 52 | "Set breakpoint at current line.") 53 | (gud-def gud-cont "continue" "\C-r" 54 | "Continue with display.") 55 | (gud-def gud-down "down %p" "<" 56 | "Down N stack frames (numeric arg).") 57 | (gud-def gud-finish "finish" "\C-f" 58 | "Finish executing current function.") 59 | (gud-def gud-source-resync "up 0" "\C-l" 60 | "Show current source window") 61 | (gud-def gud-remove "clear %d%f:%l" "\C-d" 62 | "Remove breakpoint at current line") 63 | (gud-def gud-quit "quit" "Q" 64 | "Quit debugger.") 65 | 66 | (gud-def gud-statement "eval %e" "\C-e" 67 | "Execute Ruby statement at point.") 68 | (gud-def gud-tbreak "tbreak %d%f:%l" "\C-t" 69 | "Set temporary breakpoint at current line.") 70 | (gud-def gud-up "up %p" 71 | ">" "Up N stack frames to a newer frame (numeric arg).") 72 | (gud-def gud-where "where" 73 | "T" "Show stack trace.") 74 | 75 | (local-set-key [M-insert] 'rdebug-internal-short-key-mode) 76 | (local-set-key [M-down] 'rdebug-locring-newer) 77 | (local-set-key [M-up] 'rdebug-locring-older) 78 | (local-set-key [M-S-down] 'rdebug-locring-newest) 79 | (local-set-key [M-S-up] 'rdebug-locring-oldest) 80 | ;; (local-set-key "\C-i" 'gud-gdb-complete-command) 81 | (local-set-key "\C-c\C-n" 'comint-next-prompt) 82 | (local-set-key "\C-c\C-p" 'comint-previous-prompt)) 83 | 84 | ;; stopping location motion routines. 85 | 86 | (provide 'rdebug-cmd) 87 | 88 | ;;; Local variables: 89 | ;;; eval:(put 'rdebug-debug-enter 'lisp-indent-hook 1) 90 | ;;; End: 91 | 92 | ;;; rdebug-cmd.el ends here 93 | --------------------------------------------------------------------------------