Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

3792 lines (3201 sloc) 131.085 kb
\input texinfo @c -*-texinfo-*-
@setfilename ruby-debug.info
@set DBG ruby-debug
@set ttrdebug @code{rdebug}
@set ttDBG @code{@value{DBG}}
@set Emacs @sc{gnu} Emacs
@c Karl Berry informs me that this will add straight quotes in
@c typewriter text.
@c See the "Inserting Quote Characters" node in the Texinfo manual
@set txicodequoteundirected
@set txicodequotebacktick
@set RDEBUG_VERSION 0.11.6
@macro Example {}
@iftex
@cartouche
@end iftex
@smallexample
@end macro
@macro EndExample {}
@iftex
@end cartouche
@end iftex
@end smallexample
@end macro
@macro DBG {}
@value{DBG}
@end macro
@macro ttDBG {}
@value{ttrdebug}
@end macro
@c How to show optional variables.
@macro ovar{varname}
@r{[}@var{\varname\}@r{]}
@end macro
@settitle ruby-debug
@setchapternewpage odd
@c %**end of header
@include version.texi
@finalout
@c THIS MANUAL REQUIRES TEXINFO 4.0 OR LATER.
@c This is a dir.info fragment to support semi-automated addition of
@c manuals to an info tree.
@dircategory Programming & development tools.
@direntry
* ruby-debug: (ruby-debug). Ruby Debugger
@end direntry
@titlepage
@title Debugging with @code{ruby-debug}
@sp 1
@subtitle @value{EDITION} Edition
@subtitle @value{UPDATED-MONTH}
@author Rocky Bernstein, Kent Sibilev, and Mark Moseley
@page
@ifset WHERETO
@tex
{\parskip=0pt
\hfill (Send bugs and comments on ruby-debug to fill in...)\par
\hfill {\it Debugging with {\tt ruby-debug}\par
\hfill \TeX{}info \texinfoversion\par
}
@end tex
@end ifset
@end titlepage
@page
@ifnottex
@node Top, Summary, (dir), (dir)
@top Debugging with ruby-debug
This file describes ruby-debug, the Ruby Debugger,
version @value{RDEBUG_VERSION}
This is the @value{EDITION} Edition, @value{UPDATED}
@c Copyright (C) 2007 ...
@menu
* Summary:: Overview of Debugger with sample sessions
* Invocation:: Getting in and out
* Debugger Command Reference:: rdebug command reference
* Post-Mortem Debugging:: Debugging on an uncaught exception
* Debugger Module and Class:: ruby-debug's Debugger module and class
Appendix
* Using from GitHub::
Indexes (nodes containing large menus)
* Class Module Index:: An item for Class, Module, and Methods.
* Command Index:: An item for each command name.
* General Index:: An item for each concept.
@end menu
@end ifnottex
@contents
@node Summary
@chapter Summary of @code{ruby-debug}
The purpose of a debugger such as @DBG{} is to allow you to see what is
going on ``inside'' a Ruby program while it executes.
@ttDBG{} can do four main kinds of things (plus other things in support of
these) to help you catch bugs in the act:
@itemize @bullet
@item
Start your script, specifying anything that might affect its behavior.
@item
Make your script stop on specified conditions.
@item
Examine what has happened, when your script has stopped.
@item
Change things in your script, so you can experiment with correcting the
effects of one bug and go on to learn about another.
@end itemize
Although you can use @value{ttrdebug} to invoke your Ruby programs via
a debugger at the outset, there are other ways to use and enter the
debugger.
@menu
* First Sample Session:: A Simple Sample @code{rdebug} session
* Second Sample Session:: Second Session Delving a little deeper @code{rdebug} session
* Unit Testing Session:: Using the debugger in unit testing
* Debugger.start with a block:: Using the Debugger.start with a block
* Debugging Oddities:: How debugging Ruby may be different...
@end menu
@node First Sample Session
@section The First Sample @code{rdebug} Session (@code{list}, @code{display}, @code{print}, and @code{quit})
You can use this manual at your leisure to read all about @value{ttDBG}.
However, a handful of commands are enough to get started using the
debugger. The following sections illustrates these commands.
@iftex
In this sample session, we emphasize user input like this: @b{input},
to make it easier to pick out from the surrounding output.
@end iftex
Below is Ruby code to compute a triangle number of a given
length.@footnote{There are of course shorter ways to define @code{triangle}
such as:
@smallexample
def triangle(n) (n * (n+1)) / 2 end
@end smallexample
The code we use in this example and the next is more for pedagogical
purposes than how to write short Ruby code.}
@smallexample
$ @b{rdebug triangle.rb}
triangle.rb:4 def hanoi(n,a,b,c)
(rdb:1) @b{list}
[-1, 8] in ./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
(rdb:1) @b{l}
[9, 18] in ./triangle.rb
9 tri
10 end
11
12 t = triangle(3)
13 puts t
(rdb:1) @b{list 1,100}
[1, 100] in ./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 tri
10 end
11
12 t = triangle(3)
13 puts t
(rdb:1)
@end smallexample
@noindent
There are lots of command options, but we don't need them for now. See
@ref{rdebug command-line options} for a full list of command options.
Position information consists of a filename and line number,
e.g.@: @code{triangle.rb:4}. We are currently stopped before the first
executable line of the program; this is line 4 of
@code{triangle.rb}. If you are used to less dynamic languages and have
used debuggers for more statically compiled languages like C, C++, or
Java, it may seem odd to be stopped before a function definition. But
in Ruby line 4 is executed, the name @code{triangle} (probably) does
not exist so issuing a method call of @code{triangle} will raise a
``method not found'' error.
@DBG{}'s prompt is @code{(rdb:@emph{n})}. The @emph{n} is the thread
number. Here it is 1 which is usually the case for the main thread. If
the program has died and you are in post-mortem debugging, there is no
thread number. In this situation, the string @code{post-mortem} is
used in place of a thread number. If the program has terminated
normally, the string this position will be @code{ctrl}. The commands
which are available change depending on the program state.
The first command, @code{list} (@pxref{List}), prints 10 lines
centered around the current line; the current line here is line 4 and
is marked by @code{=>}, so the range the debugger would like to show
is -1..8. However since there aren't 5 lines before the current line,
those additional lines---``lines'' -1 and 0---are dropped and we print
the remaining 8 lines. The @code{list} command can be abbreviated
with @code{l} which is what we use next. Notice that when we use this
a second time, we continue listing from the place we last left
off. The desired range of lines this time is lines 9 to 18; but since
the program ends at line 13, only the remaining 5 lines are shown.
If you want to set how many lines to print by default rather than use
the initial number of lines, 10, use the @code{set listsize} command
(@pxref{Listsize}). To see the entire program in one shot, we gave an
explicit starting and ending line number.
If you use a front-end to the debugger such as the Emacs interface,
@c (@pxref{GNU Emacs})
you probably won't use @code{list} all that much.
Now let us step through the program.
@smallexample
(rdb:1) @b{step}
triangle.rb:12
t = triangle(3)
(rdb:1) @b{@key{<RET>}}
triangle.rb:5
tri = 0
(rdb:1) @b{p tri}
nil
(rdb:1) @b{step}
triangle.rb:6
0.upto(n) do |i|
(rdb:1) @b{p tri}
0
@end smallexample
The first @kbd{step} command (@pxref{Step}) runs the script one
executable unit. The second command we entered was just hitting the
return key; @ttDBG{} remembers the last command you entered was
@code{step}, so it runs that last command again.
One way to print the values of variables uses @code{p}. (Of course,
there are of course lots of other ways too.). When we look at the
value of @code{tri} the first time, we see it is @code{nil}. Again we
are stopped @emph{before} the assignment on line 5, and this variable
hasn't been set previously. However after issuing another ``step''
command we see that the value is 0 as expected.
However if every time we stop we want to see the value of @code{tri}
to see how things are going stop, there is a better way by setting a
display expression (@pxref{DisplayCommands}).
@smallexample
(rdb:1) @b{display tri}
1: tri = 0
@end smallexample
Now let us run the program until we return from the function. However
we'll want to see which lines get run.
@smallexample
(rdb:1) @b{display i}
2: i =
(rdb:1) @b{set linetrace on}
line tracing is on.
(rdb:1) @b{finish}
Tracing(1):triangle.rb:7 tri += i
1: tri = 0
2: i = 0
Tracing(1):triangle.rb:7 tri += i
1: tri = 0
2: i = 1
Tracing(1):triangle.rb:7 tri += i
1: tri = 1
2: i = 2
Tracing(1):triangle.rb:7 tri += i
1: tri = 3
2: i = 3
Tracing(1):triangle.rb:9 tri
1: tri = 6
2: i = 3
6
Tracing(1):triangle.rb:13 puts t
1: tri =
2: i =
1: tri =
2: i =
triangle.rb:13
puts t
(rdb:1) @b{quit}
Really quit? (y/n) @b{y}
@end smallexample
So far, so good. A you can see from the above to get out of the
debugger, one can issue a @code{quit} command. (@code{q} and
@code{exit} are just as good. If you want to quit without being
prompted, suffix the command with an exclamation mark, e.g.\@code{q!}.
@node Second Sample Session
@section Sample Session 2: Delving Deeper (@code{where}, @code{frame}, @code{restart}, @code{autoeval}, @code{break}, @code{ps})
In this section we'll introduce breakpoints, the call stack and
restarting. So far we've been doing pretty good in that we've not
encountered a bug to fix. Let's try another simple example. Okay
here's the program.
Below we will debug a simple Ruby program to solve the classic Towers
of Hanoi puzzle. It is augmented by the bane of programming: some
command-parameter processing with error checking.
@smallexample
$ @b{rdebug hanoi.rb}
hanoi.rb:3 def hanoi(n,a,b,c)
(rdb:1) @b{list 1,100}
[1, 100] in ./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)
(rdb:1)
@end smallexample
Recall in the first section I said that before the @code{def} is run
the method it names is undefined. Let's check that out. First let's
see what private methods we can call before running @code{def hanoi}
@smallexample
(rdb:1) @b{set autoeval on}
autoeval is on.
(rdb:1) @b{private_methods}
[:require_relative, :Digest, :default_src_encoding, :debug_program, ...
@end smallexample
The @code{set autoeval} (@pxref{Autoeval}) command causes any commands
that are not normally understood to be debugger commands to get
evaluated as though they were Ruby commands. I use this a lot, so I
set this by putting it the command file @code{.rdebugrc},
@pxref{Command Files}, that gets read when @code{ruby-debug} starts.
As showing the list output of @code{private_methods}, I find this kind
of list unwieldy. What you are supposed to notice here is that
method @code{hanoi} is not in this list. When you ask
@code{ruby-debug} for a list of method names via @code{method
instance}, it doesn't show output in this way; @code{ruby-debug} can
sort and put into columns lists like this using the print command, @code{ps}.
@smallexample
(rdb:1) @b{ps private_methods}
Array debug_program p spawn
Complex default_src_encoding pp sprintf
Digest eval print srand
Float exec printf syscall
Integer exit proc system
Pathname exit! process_options test
Rational fail putc throw
String fork puts trace_var
__callee__ format raise trap
__method__ gem rand untrace_var
` gets readline warn
abort global_variables readlines whence_file
at_exit initialize remove_instance_variable y
autoload initialize_copy require
autoload? iterator? require_relative
binding lambda select
block_given? load set_trace_func
caller local_variables singleton_method_added
catch loop singleton_method_removed
dbg_print method_missing singleton_method_undefined
dbg_puts open sleep
@end smallexample
Now let's see what happens after stepping:
@smallexample
(rdb:1) @b{private_methods.member?(:hanoi)}
false
(rdb:1) @b{step}
hanoi.rb:13
i_args=ARGV.length
(rdb:1) @b{private_methods.member?(:hanoi)}
true
(rdb:1)
@end smallexample
Okay, now where were we?
@smallexample
(rdb:1) @b{list}
[8, 17] in ./hanoi.rb
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
(rdb:1) @b{ARGV}
[]
@end smallexample
Ooops. We forgot to specify any parameters to this program. Let's try
again. We can use the @code{restart} command here.
@smallexample
(rdb:1) @b{restart 3}
Re exec'ing:
/usr/bin/rdebug hanoi.rb 3
hanoi.rb:3
def hanoi(n,a,b,c)
(rdb:1) @b{break 4}
Breakpoint 1 file hanoi.rb, line 4
(rdb:1) @b{continue}
Breakpoint 1 at hanoi.rb:4
./hanoi.rb:4 if n-1 > 0
(rdb:1) @b{display n}
1: n = 3
(rdb:1) @b{display a}
2: a = a
(rdb:1) @b{undisplay 2}
(rdb:1) @b{display a.inspect}
3: a.inspect = :a
(rdb:1) @b{display b.inspect}
4: b.inspect = :b
(rdb:1) @b{continue}
Breakpoint 1 at hanoi.rb:4
1: n = 2
3: a.inspect = :a
4: b.inspect = :c
./hanoi.rb:4
if n-1 > 0
(rdb:1) @b{c}
Breakpoint 1 at hanoi.rb:4
1: n = 1
3: a.inspect = :a
4: b.inspect = :b
./hanoi.rb:4
if n-1 > 0
(rdb:1) @b{where}
--> #0 Object.hanoi(n#Fixnum, a#Symbol, b#Symbol, c#Symbol) at line hanoi.rb:4
#1 Object.hanoi(n#Fixnum, a#Symbol, b#Symbol, c#Symbol) at line hanoi.rb:5
#2 Object.hanoi(n#Fixnum, a#Symbol, b#Symbol, c#Symbol) at line hanoi.rb:5
#3 at line hanoi.rb:35
(rdb:1)
@end smallexample
In the above we added a new command, @code{break}
(@pxref{Breakpoints}) which indicates to go into the debugger just
before that line of code is run. And @code{continue} resumes
execution. Notice the difference between @code{display a} and
@code{display a.inspect}. An implied string conversion is performed on
the expression after it is evaluated. To remove a display expression
we used @code{undisplay} is used. If we give a display number, just
that display expression is removed.
Above we also used a new command @code{where} (@pxref{Backtrace} to
show the call stack. In the above situation, starting from the bottom
line we see we called the hanoi from line 35 of the file
@code{hanoi.rb} and the hanoi method called itself two more times at
line 5.
In the call stack we show the file line position in the same format
when we stop at a line. Also we see the names of the parameters and
the types that those parameters @emph{currently} have. It's possible
that when the program was called the parameter had a different type,
since the types of variables can change dynamically. You alter the
style of what to show in the trace (@pxref{Callstyle}).
Let's explore a little more. Now were were we?
@smallexample
(rdb:1) @b{list}
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
(rdb:1) @b{undisplay}
Clear all expressions? (y/n) @b{y}
(rdb:1) @b{i_args}
NameError Exception: undefined local variable or method `i_args' for main:Object
(rdb:1) @b{frame -1}
#3 at line hanoi.rb:35
(rdb:1) @b{i_args}
1
(rdb:1) @b{p n}
3
(rdb:1) @b{down 2}
#2 Object.hanoi(n#Fixnum, a#Symbol, b#Symbol, c#Symbol) at line hanoi.rb:5
(rdb:1) @b{p n}
2
@end smallexample
Notice in the above to get the value of variable @code{n}, I have to
use a print command like @code{p n}; If I entered just @code{n}, that
would be taken to mean the debugger command ``next''. In the current
scope, variable @code{i_args} is not defined. However I can change to
the top-most frame by using the @code{frame} command. Just as with
arrays, -1 means the last one. Alternatively using frame number 3
would have been the same thing; so would issuing @code{up 3}.
Note that in the outside frame 3, the value of @code{i_args} can be
shown. Also note that the value of variable @code{n} is different.
@node Unit Testing Session
@section Using the debugger in unit testing (@code{ruby-debug/debugger}, @code{Debugger.start})
In the previous sessions we've been calling the debugger right at the
outset. I confess that this mode of operation is usually not how I use
the debugger.
There are a number of situations where calling the debugger at the outset is
impractical for a couple of reasons.
@enumerate
@item
The debugger just doesn't work when run at the outset. By necessity
any debugging changes to the behavior or the program in slight and
subtle ways, and sometimes this can hinder finding bugs.
@item
There's a lot of code which that needs to get run before the part you
want to inspect. Running this code takes time and you don't want the
overhead of the debugger.
@end enumerate
In this section we'll show how to enter the code in the middle
of your program, while delving more into the debugger operation.
In this section we will also use unit testing. Using unit tests will
greatly reduce the amount of debugging needed, while at the same time,
will increase the quality of your program.
What we'll do is take the @code{triangle} code from the first session
and write a unit test for that. In a sense we did write a mini-test
for the program which was basically the last line where we printed the
value of triangle(3). This test however wasn't automated: the
implication is that someone would look at the output and verify that
what was printed is what was expected.
And before we can turn that into something that can be
@code{required}, we probably want to remove that output. However I
like to keep in that line so that when I look at the file, I have an
example of how to run it. Therefore we will conditionally run this
line if that file is invoked directly, but skip it if it is
not.@footnote{@code{rdebug} resets @code{$0} to try to make things
like this work.}
@smallexample
if __FILE__ == $0
t = triangle(3)
puts t
end
@end smallexample
Let's call this file @code{tri2.rb}.
Okay, we're now ready to write our unit test. We'll use
@code{"test/unit"} which comes with the standard Ruby distribution.
Here's the test code; it should be in the same directory as tri2.rb.
@smallexample
#!/usr/bin/env ruby
require 'test/unit'
require_relative './tri2.rb'
class TestTri < Test::Unit::TestCase
def test_basic
solutions = []
0.upto(5) do |i|
solutions << triangle(i)
end
assert_equal([0, 1, 3, 6, 10, 15], solutions,
'Testing the first 5 triangle numbers')
end
end
@end smallexample
If you run it will work. However if you run @code{rdebug} initially,
you will not get into the test, because @code{test/unit} wants to be
the main program. So here is a situation where one may need to modify
the program to add an explicit @emph{entry} into the
debugger.@footnote{For some versions of rake and @code{rdebug} you can
in fact set a breakpoint after running @code{rdebug}
initially. Personally though I find it much simpler and more reliable
to modify the code as shown here.}
One way to do this is to add the following before the place you want
to stop:
@smallexample
require 'ruby-debug'
debugger
@end smallexample
Let's add this code just after entering @code{test_basic}:
@smallexample
...
def test_basic
@b{require "ruby-debug"}
@b{debugger}
solutions = []
...
@end smallexample
Now we run the program..
@smallexample
$ @b{ruby test-tri.rb}
Loaded suite test-tri
Started
test-tri.rb:9
solutions = []
(rdb:1)
@end smallexample
and we see that we are stopped at line 9 just before the
initialization of the list @code{solutions}.
Now let's see where we are...
@smallexample
(rdb:1) @b{where}
--> #0 TestTri.test_basic at line /home/rocky/ruby/test-tri.rb:9
(rdb:1)
@end smallexample
Something seems wrong here; @code{TestTri.test_basic} indicates that
we are in class @code{TestTri} in method @code{test_basic}. However we
don't see the call to this like we did in the last example when we
used the @code{where} command. This is because the debugger really
didn't spring into existence until after we already entered that
method, and Ruby doesn't keep call stack information around in a
way that will give the information we show when running @code{where}.
If we want call stack information, we have to turn call-stack tracking
on @emph{beforehand}. This is done by adding @code{Debugger.start}.
Here's what our test program looks like so after we modify it to start
tracking calls from the outset
@smallexample
#!/usr/bin/env ruby
require 'test/unit'
require 'tri2.rb'
require 'ruby-debug'
@b{Debugger.start}
class TestTri < Test::Unit::TestCase
def test_basic
@b{debugger}
solutions = []
0.upto(5) do |i|
solutions << triangle(i)
end
assert_equal([0, 1, 3, 6, 10, 15], solutions,
"Testing the first 5 triangle numbers")
end
end
@end smallexample
Now when we run this:
@smallexample
$ @b{ruby test-tri2.rb}
Loaded suite test-tri2
Started
test-tri2.rb:11
solutions = []
(rdb:1) @b{where}
--> #0 TestTri.test_basic at line test-tri2.rb:11
#1 MiniTest::Unit::TestCase.run(runner#MiniTest::Unit)
at line /usr/local/lib/ruby/1.9.1/minitest/unit.rb:458
#2 MiniTest::Unit.run_test_suites
at line /usr/local/lib/ruby/1.9.1/minitest/unit.rb:426
#3 MiniTest::Unit.run
at line /usr/local/lib/ruby/1.9.1/minitest/unit.rb:393
#4 at line /usr/local/lib/ruby/1.9.1/minitest/unit.rb:334
(rdb:1)
@end smallexample
Much better. But again let me emphasize that the parameter types are
those of the corresponding variables that @emph{currently} exist, and
this might have changed since the time when the call was made.
@node Debugger.start with a block
@section Using the @code{Debugger.start} with a block
We saw that @code{Debugger.start()} and @code{Debugger.stop()} allow
fine-grain control over where the debugger tracking should occur.
Rather than use an explicit @code{stop()}, you can also pass a block
to the @code{start()} method. This causes @code{start()} to run and
then @code{yield} to that block. When the block is finished,
@code{stop()} is run. In other words, this wraps a
@code{Debugger.start()} and @code{Debugger.stop()} around the block of
code. But it also has a side benefit of ensuring that in the presence
of an uncaught exception @code{stop} is run, without having to
explicitly use @code{begin} ... @code{ensure Debugger.stop() end}.
For example, in Ruby Rails you might want to debug code in one of the
controllers without causing any slowdown to any other code. And
this can be done by wrapping the controller in a @code{start()} with a
block; when the method wrapped this way finishes the debugger is
turned off, and the application proceeds at regular speed.
Of course, inside the block you will probably want to enter the
debugger using @code{Debugger.debugger()}, otherwise there would
little point in using the @code{start}. For example, you can do this
in @code{irb}:
@smallexample
$ @b{irb}
irb(main):001:0> @b{require 'ruby-debug'}
=> true
irb(main):002:0> @b{def foo}
irb(main):003:1> @b{x=1}
irb(main):004:1> @b{puts 'foo'}
irb(main):005:1> @b{end}
=> nil
irb(main):006:0> @b{Debugger.start@{debugger; foo@}}
(irb):3
(rdb:1) @b{s}
(irb):4
(rdb:1) @b{p x}
1
(rdb:1) @b{s}
foo
=> true
irb(main):007:0>
@end smallexample
There is a counter inside of @code{Debugger.start} method to make sure
that this works when another @code{Debugger.start} method is called
inside of outer one. However if you are stopped inside the debugger,
issuing another @code{debugger} call will not have any effect even if
it is nested inside another @code{Debugger.start}.
@node Debugging Oddities
@section How debugging Ruby may be different than debugging other Languages
If you are used to debugging in other languages like C, C++, Perl,
Java or even Bash@footnote{this is just an excuse to put in a
shameless plug for my bash debugger @url{http://bashdb.sf.net}}, there
may be a number of things that seem or feel a little bit different and
may confuse you. A number of these things aren't oddities of the
debugger per se, so much as a difference in how Ruby works compared to
those other languages. Because Ruby works a little differently from
those other languages, writing a debugger has to also be a little
different as well if it is to be useful.
In this respect, using the debugger may help you understand Ruby
better.
We've already seen two examples of such differences. One difference is
the fact that we stop on method definitions or @code{def}'s and that is
because these are in fact executable statements. In other compiled
languages this would not happen because that's already been done when
you compile the program (or in Perl when it scans in the program). The
other difference we saw was in our inability to show call stack parameter
types without having made arrangements for the debugger to track
this. In other languages call stack information is usually available
without asking assistance of the debugger.@footnote{However in C, and
C++ generally you have to ask the compiler to add such information.}
In this section we'll consider some other things that might throw
off new users to Ruby who are familiar with other languages and
debugging in them.
@menu
* Stack No Longer Shows Scope Nesting::
* Bouncing Around in Blocks (e.g. Iterators)::
* No Parameter Values in a Call Stack::
* Lines You Can Stop At::
@end menu
@node Stack No Longer Shows Scope Nesting
@subsection Stack No Longer Shows Scope Nesting
In the Ruby 1.8 ruby-debug, backtraces will show more stack frames
that you might find in other languages, such as C. In the Ruby 1.9
ruby-debug, this is no longer the case.
@node Bouncing Around in Blocks (e.g. Iterators)
@subsection Bouncing Around in Blocks (e.g.@: Iterators)
When debugging languages with coroutines like Python and Ruby, a
method call may not necessarily go to the first statement after the
method header. It's possible the call will continue after a
@code{yield} statement from a prior call.
@smallexample
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
@end smallexample
@smallexample
$ @b{rdebug primes.rb}
primes.rb:3
class SievePrime
(rdb:1) @b{set linetrace on}
line tracing is on.
(rdb:1) @b{step 9}
Tracing(1):primes.rb:4 @@odd_primes = []
Tracing(1):primes.rb:5 def self.next_prime(&block)
Tracing(1):primes.rb:23 SievePrime.next_prime do |prime|
Tracing(1):primes.rb:6 candidate = 2
Tracing(1):primes.rb:7 yield candidate
Tracing(1):primes.rb:24 puts prime
2
Tracing(1):primes.rb:25 break if prime > 10
Tracing(1):primes.rb:8 not_prime = false
Tracing(1):primes.rb:9 candidate += 1
primes.rb:9
candidate += 1
(rdb:1)
@end smallexample
The loop between lines 23--26 gets interleaved between those of
@code{Sieve::next_prime}, lines 6--19 above.
A similar kind of thing can occur in debugging programs with many threads.
@node No Parameter Values in a Call Stack
@subsection No Parameter Values in a Call Stack
In traditional debuggers in a call stack you can generally see the
names of the parameters and the values that were passed in.
Ruby is a very dynamic language and it tries to be efficient within
the confines of the language definition. Values generally aren't taken
out of a variable or expression and pushed onto a stack. Instead a new
scope created and the parameters are given initial values. Parameter
passing is by @emph{reference}, not by value as it is say Algol, C, or
Perl. During the execution of a method, parameter values can
change---and often do. In fact even the @emph{class} of the object can
change.
So at present, the name of the parameter shown. The call-style setting
@pxref{Callstyle} can be used to set whether the name is shown or the
name and the @emph{current} class of the object.
It has been contemplated that a style might be added which saves on
call shorter ``scalar'' types of values and the class name.
@node Lines You Can Stop At
@subsection Lines You Can Stop At
As with the duplicate stops per control (e.g.@: @code{if} statement),
until tools like debuggers get more traction among core ruby
developers there are going to be weirdness. Here we describe the
stopping locations which effects the breakpoint line numbers you can
stop at.
Consider the following little Ruby program.
@smallexample
'Yes it does' =~ /
(Yes) \s+
it \s+
does
/ix
puts $1
@end smallexample
The stopping points that Ruby records are the last two lines, lines 5
and 6.
Inside @code{ruby-debug} you an get a list of stoppable lines for a
file using the @code{info file} command with the attribute
@code{breakpoints}.
@ifset FINISHED
To be continued...
@itemize @bullet
@item more complex example with objects, pretty printing and irb.
@item line tracing and non-interactive tracing.
@item mixing in Debugger.debug with rdebug
@item post-mortem debugging and setting up for that
@item threading?
@item references to videos
@end itemize
@end ifset
@node Invocation
@chapter Getting in and out
@menu
* Starting the debugger:: How to enter the debugger
* Command Files:: Command files
* Quitting the debugger:: How to leave the debugger (quit, kill)
* Calling from Program:: Calling the debugger from inside your program
@end menu
It is also possible to enter the debugger when you have an uncaught
exception. See See also @ref{Post-Mortem Debugging}.
@node Starting the debugger
@section Starting the debugger
Although one can enter @DBG{} via Emacs (described in a later section)
and possibly others interfaces, probably the most familiar thing to do
is invoke the debugger from a command line.
A wrapper shell script called @code{rdebug} basically @code{require}'s
the gem package @code{ruby-debug} and then loads @code{rdebug}.
@smallexample
rdebug [rdebug-options] [--] @var{ruby-script} @var{ruby-script-arguments...}
@end smallexample
If you don't need to pass dash options to your program which might get
confused with the debugger options, then you don't need to add the
@option{--}.
To get a brief list of options and descriptions, use the @code{--help}
option.
@smallexample
$ @b{rdebug --help}
rdebug @value{RDEBUG_VERSION}
Usage: rdebug [options] <script.rb> -- <script.rb parameters>
Options:
-A, --annotate LEVEL Set annotation level
-c, --client Connect to remote debugger
--cport PORT Port used for control commands
-d, --debug Set $DEBUG=true
--emacs Activates full Emacs support
--emacs-basic Activates basic Emacs mode
-h, --host HOST Host name used for remote debugging
-I, --include PATH Add PATH to $LOAD_PATH
--keep-frame-binding Keep frame bindings
-m, --post-mortem Activate post-mortem mode
--no-control Do not automatically start control thread
--no-quit Do not quit when script finishes
--no-rewrite-program Do not set $0 to the program being debugged
--no-stop Do not stop when script is loaded
-nx Not run debugger initialization files (e.g. .rdebugrc
-p, --port PORT Port used for remote debugging
-r, --require SCRIPT Require the library, before executing your script
--restart-script FILE Name of the script file to run. Erased after read
--script FILE Name of the script file to run
-s, --server Listen for remote connections
-w, --wait Wait for a client connection, implies -s option
-x, --trace Turn on line tracing
Common options:
--verbose Turn on verbose mode
--help Show this message
--version Print the version
-v Print version number, then turn on verbose mode
@end smallexample
Options for the @code{rdebug} are shown in the following list.
@menu
* rdebug command-line options:: Options you can pass to rdebug
* rdebug default options:: How to Set Default Command-Line Options
@end menu
@node rdebug command-line options
@subsection Options you can pass to rdebug
You can run @DBG{} in various alternative modes---for example, as a
program that interacts directly with the program in the same process
on the same computer or via a socket to another process possibly on a
different computer.
Many options appear as a long option name, such as @option{--help}, and
a short one letter option name, such as @option{-h}. A double dash
(@option{--} is used to separate options which go to @code{rdebug} from
options that are intended to go to your Ruby script. Options (if any)
to @code{rdebug} should come first. If there is no possibility of the
Ruby script to be debugged getting confused with @code{rdebug}'s
option the double dash can be omitted.
@table @code
@item --help
@cindex @option{-h}
@cindex @option{--help}
This option causes @ttDBG{} to print some basic help and exit.
@item -v | --version
@cindex @option{-v}
This option causes @ttDBG{} to print its version number and exit.
@item -A | --annotate @var{level}
@cindex @option{-A}
@cindex @option{--annotation} @var{level}
Set gdb-style annotation @var{level}, a number. Additional information is output
automatically when program state is changed. This can be used by
front-ends such as GNU Emacs to post this updated information without
having to poll for it.
@item -c | --client
@cindex @option{-c}
@cindex @option{--client}
Connect to remote debugger. The remote debugger should have been set
up previously our you will get a connection error and @code{rdebug}
will terminate.
@item --cport @var{port}
@cindex @option{--cport} @var{port}
Port used for control commands.
@item --debug
@cindex @option{--debug}
Set @code{$DEBUG} to @code{true}. This option is compatible with
Ruby's.
@item --emacs
Activates GNU Emacs mode.
@c @pxref{GNU Emacs}.
Debugger output is tagged in such a way to allow GNU Emacs to track
where you are in the code.
@item --emacs-basic
Activates full GNU Emacs mode.
@c (@pxref{GNU Emacs}).
This is the equivalent of setting the options @option{--emacs-basic},
@code{annotate=3}, @option{--no-stop}, @option{-no-control} and
@option{--post-mortem}.
@item -h | --host @var{host-address}
Connect host address for remote debugging.
@item -I --include @var{PATH}
@cindex @option{-I} @var{PATH}
@cindex @option{--include} @var{PATH}
Add @var{PATH} to @code{$LOAD_PATH}
@item --keep-frame-binding
@cindex @option{--keep-frame-binding}
Bindings are used to set the proper environment in evaluating
expression inside the debugger. Under normal circumstances, I don't
believe most people will ever need this option.
By default, the debugger doesn't create binding object for each frame
when the frame is created, i.e. when a call is performed. Creating a
binding is an expensive operation and has been a major source of
performance problems.
Instead, the debugger creates a binding when there is a need to
evaluate expressions. The artificial binding that is created might be
different from the real one. In particular, in performing constant
and module name resolution.
However it's still possible to restore the old, slower behavior by
using this option or by setting @code{Debugger.keep_frame_binding =
true}. There are two possibilities for which you might want to use
this option.
First, if you think there's a bug in the evaluation of variables, you
might want to set this to see if this corrects things.
Second, since the internal structures that are used here @code{FRAME}
and @code{SCOPE} are not part of the Ruby specification, it is
possible they can change with newer releases; so here this option this
may offer a remedy. (But you'll probably also have to hack the C code
since it's likely under this scenario that ruby-debug will no longer
compile.) In fact, in Ruby 1.9 these structures have changed and that
is partly why this debugger doesn't work on Ruby 1.9.
@item -m | --post-mortem
@cindex @option{-m}
@cindex @option{--post-mortem}
If your program raises an exception that isn't caught you can enter
the debugger for inspection of what went wrong. You may also want to
use this option in conjunction with @option{--no-stop}. See also
@ref{Post-Mortem Debugging}.
@item --no-control
@cindex @option{--no-control}
Do not automatically start control thread.
@item --no-quit
@cindex @option{--no-quit}
Restart the debugger when your program terminates normally.
@item --no-rewrite-program
@cindex @option{--no-rewrite-program}
Normally @code{rdebug} will reset the program name @code{$0} from its
name to the debugged program, and set the its name in variable
@code{$RDEBUG_0}. In the unlikely even you don't want this use this option.
@item --no-stop
@cindex @option{--no-stop}
Normally the @code{rdebug} stops before executing the first
statement. If instead you want it to start running initially and will
perhaps break it later in the running, use this options.
@item -p | --port @var{port}
@cindex @option{-p} @var{port}
@cindex @option{--port} @var{port}
Port used for remote debugging.
@item -r | --require @var{library}
@cindex @option{-r}
@cindex @option{--require}
Require the library, before executing your script. However if the
library happened to be @code{debug}, we'll just ignore the require
(since we're already a debugger). This option is compatible with Ruby's.
@item --script @var{file}
@cindex @option{--script}
Require the library, before executing your script. However if the
library hap-pend to be @code{debug}, we'll just ignore the require
(since we're already a debugger). This option is compatible with Ruby's.
@item -s | --server
@cindex @option{-s}
@cindex @option{--server}
Debug the program but listen for remote connections on the default
port or port set up via the @option{--port} option. See also @option{--wait}.
@item -w | --wait
@cindex @option{-w}
@cindex @option{--wait}
Debug the program but stop waiting for a client connection first. This
option automatically sets @option{--server} option.
@item -x | --trace
@cindex @option{-x}
@cindex @option{--trace}
Turn on line tracing. Running @command{rdebug --trace @emph{rubyscript.rb}}
is much like running: @command{ruby -rtracer @emph{rubyscript.rb}}
If all you want to do however is get a linetrace, @code{tracer}, not
@code{rdebug}, may be faster:
@smallexample
$ @b{time ruby -rtracer gcd.rb 34 21 > /dev/null}
real 0m0.266s
user 0m0.008s
sys 0m0.000s
$ @b{time rdebug --trace gcd.rb 34 21 > /dev/null}
real 0m0.875s
user 0m0.448s
sys 0m0.056s
$
@end smallexample
@end table
@node rdebug default options
@subsection How to Set Default Command-Line Options
@DBG{} has many command-line options; it seems that some people want
to set them differently from the our defaults. For example, some
people may want @option{--no-quit --no-control} to be the default
behavior. One could write a wrapper script or set a shell alias to
handle this. @DBG{} has another way to do this as well. Before
processing command options if the file @code{$HOME/.rdboptrc} is found
(or, on Windows, @code{$HOME/rdbopt.ini}, it is loaded.
If you want to set the defaults in some other way, you
can put Ruby code here and set variable @code{options} which is an
OpenStruct. For example here's how you'd set @option{-no-quit} and
change the default control port to 5000.
@smallexample
# This file contains how you want the default options to ruby-debug
# to be set. Any Ruby code can be put here.
#
# debugger # Uncomment if you want to debug rdebug!
options.control = false
options.port = 5000
puts "rocky's rdboptrc run"
@end smallexample
Here are the default values in @code{options}
@smallexample
#<OpenStruct server=false, client=false, frame_bind=false, cport=8990, tracing=false, nx=false, post_mortem=false, port=8989, verbose_long=false, annotate=nil, control=true, restart_script=nil, quit=true, no_rewrite_program=false, stop=true, script=nil, host=nil, wait=false>
@end smallexample
@node Command Files
@section Command files
@cindex command files
A command file for @DBG{} is a file of lines that are @DBG{}
commands. Comments (lines starting with @kbd{#}) may also be included.
An empty line in a command file does nothing; it does not mean to repeat
the last command, as it would from the terminal.
@cindex init file
@cindex @file{.rdebugrc}
When you start @value{DBG}, it automatically executes commands from its
@dfn{init files}, normally called @file{.rdebugrc}.
On some configurations of @value{DBG}, the init file may be known by a
different name. In particular on MS-Windows (but not cygwin)
@file{rdebug.ini} is used.
During startup, @DBG{} does the following:
@enumerate
@item
Processes command line options and operands.
@item
Reads the init file in your current directory, if any, and failing
that the home directory. The home directory is the directory named in
the @code{HOME} or @code{HOMEPATH} environment variable.
Thus, you can have more than one init file, one generic in your home
directory, and another, specific to the program you are debugging, in
the directory where you invoke @DBG{}.
@item
Reads command files specified by the @samp{--script} option.
@end enumerate
You can also request the execution of a command file with the
@code{source} command, @pxref{Source}.
@node Quitting the debugger
@section Quitting the debugger
@cindex interrupt
An interrupt (often @kbd{C-c}) does not exit from @value{DBG}, but
rather terminates the action of any @DBG command that is in
progress and returns to @value{DBG} command level. Inside a debugger
command interpreter, use @code{quit} command (@pxref{Control, ,Quitting
the debugger}).
There way to terminate the debugger is to use the @code{kill}
command. This does more forceful @code{kill -9}. It can be used in
cases where @code{quit} doesn't work.
@node Calling from Program
@section Calling the debugger from inside your Ruby program
Running a program from the debugger adds a bit of overhead and slows
down your program a little.
Furthermore, by necessity, debuggers change the operation of the
program they are debugging. And this can lead to unexpected and
unwanted differences. It has happened so often that the term
``Heisenbugs'' (see @url{http://en.wikipedia.org/wiki/Heisenbug}) was
coined to describe the situation where the addition of the use of a
debugger (among other possibilities) changes behavior of the program
so that the bug doesn't manifest itself anymore.
There is another way to get into the debugger which adds no overhead
or slowdown until you reach the point at which you want to start
debugging. However here you must change the script and make an
explicit call to the debugger. Because the debugger isn't involved
before the first call, there is no overhead and the script will run
at the same speed as if there were no debugger.
There are three parts to calling the debugger from inside the script,
``requiring'' the debugger code, telling the debugger to start
tracking things and then making the call calling the debugger to
stop.
To get the debugger class accessible from your Ruby program:
@smallexample
require 'ruby-debug'
@end smallexample
After @code{require 'ruby-debug'}, it's possible to set some of the
debugger variables influence preferences. For example if you want to
have @ttDBG run a @code{list} command every time it stops you set the
variable @code{Debugger.settings[:autolist]}. @pxref{Debugger.settings} has a
list of variable settings and the default values. Debugger settings
can also be set in @code{.rdebugrc} as debugger
commands. @pxref{Command Files}
To tell the debugger to start tracking things:
@smallexample
Debugger.start
@end smallexample
There is also a @code{Debugger.stop} to turn off debugger tracking. If
speed is crucial, you may want to start and stop this around certain
sections of code. Alternatively, instead of issuing an explicit
@code{Debugger.stop} you can add a block to the @code{Debugger.start}
and debugging is turned on for that block. If the block of code raises
an uncaught exception that would cause the block to terminate, the
@code{stop} will occur. See @ref{Debugger.start with a block}.
And finally to enter the debugger:
@smallexample
debugger
@end smallexample
As indicated above, when @code{debugger} is run a @code{.rdebugrc}
profile is read if that file exists.
You may want to do enter the debugger at several points in the program
where there is a problem you want to investigate. And since
@code{debugger} is just a method call it's possible enclose it in a
conditional expression, for example:
@smallexample
debugger if 'bar' == foo and 20 == iter_count
@end smallexample
Although each step does a very specific thing which offers great
flexibility, in order to make getting into the debugger easier the
three steps have been rolled into one command:
@smallexample
require "ruby-debug/debugger"
@end smallexample
@node Debugger Command Reference
@chapter @code{ruby-debug} Command Reference
@menu
* Command Interfaces:: The kinds of interface used to interact with ruby-debug
* Command Syntax:: How to give commands to the ruby-debug
* Command Output:: How rdebug presents its output
* Help:: How to ask for help (help)
* Control:: Controlling the debugger (quit, restart, interrupt)
* DisplayCommands:: Executing expressions on stop (display, undisplay)
* PrintCommands:: Evaluating and Printing Expressions (p, pp, ps, pp, irb)
* PrintVars:: Printing Variables (var)
* List:: Examining Program Source Files (list)
* Edit:: Editing source files (edit)
* FrameCommands:: Examining the stack frame (where, up, down, frame)
* Stopping:: Stopping and continuing (break, watch, step, cont...)
* ruby-debug settings:: rdebug-settings (set args, set autoeval, ...)
* Program Information:: Program Status (info)
@end menu
@node Command Interfaces
@section Command Interfaces
There are several ways one can talk to @code{ruby-debug} and get
results. The simplest way is via a command-line interface directly
talking to the debugger. This is referred to below as a ``Local
Interface''. It's also possible to run the debugger and set up a port
by which some other process can connect and control the debug
session. This is called a ``Remote Interface''. When you want to gain
access to a remote interface you need to run @code{ruby-debug} using a
``Control Interface''. This interface might not be the same process as
the process running the debugged program and might not even be
running on the same computer.
Other front-ends may use one of these and build on top and provide
other (richer) interfaces. Although many of the commands are available
on all interfaces some are not. Most of the time in this manual when
we talk about issuing commands describing the responses elicited,
we'll assume we are working with the local interface.
@node Command Syntax
@section Command Syntax
Usually a command is put on a single line. There is no limit on how long
it can be. It starts with a command name, which is followed by
arguments whose meaning depends on the command name. For example, the
command @code{step} accepts an argument which is the number of times to
step, as in @code{step 5}. You can also use the @code{step} command with no
arguments. Some commands do not allow any arguments.
Multiple commands can be put on a line by separating each with a
semicolon (@code{;}). You can disable the meaning of a semicolon to
separate commands by escaping it with a backslash.
For example, if you have @code{autoeval} (@ref{Autoeval}) set, you
might want to enter the following code to compute the 5th Fibonacci
number:
@smallexample
# Compute the 5 Fibonaci number
(rdb:1) set autoeval on
(rdb:1) fib1=0; fib2=1; 5.times @{|temp| temp=fib1; fib1=fib2; fib2 += temp @}
SyntaxError Exception: compile error
/usr/bin/irb:10: syntax error, unexpected $end, expecting '@}'
5.times @{|temp| temp=fib1
^
(rdb:1) fib1=0\; fib2=1\; 5.times @{|temp| temp=fib1\; fib1=fib2\; fib2 += temp @}
5
(rdb:1) fib2
fib2
8
@end smallexample
You might also consider using the @code{irb} command, @ref{irb}, and
then you won't have to escape semicolons.
A blank line as input (typing just @key{<RET>}) means to repeat the
previous command.
In the ``local'' interface, the Ruby Readline module is used. It
handles line editing and retrieval of previous commands. Up arrow, for
example moves to the previous debugger command; down arrow moves to
the next more recent command (provided you are not already at the last
command). Command history is saved in file @code{.rdebug_hist}. A
limit is put on the history size. You can see this with the @code{show
history size} command. See @ref{History} for history parameters.
@node Command Output
@section Command Output
In the command-line interface, when @code{ruby-debug} is waiting for
input it presents a prompt of the form
@code{(rdb:}@emph{x}@code{)}. If debugging locally, @emph{x} will be
the thread number. Usual the main thread is 1, so often you'll see
@code{(rdb:1)}. In the control interface though @emph{x} will be
@code{ctrl} and in post-mortem debugging @code{post-mortem}.
In the local interface, whenever @code{ruby-debug} gives an error
message such as for an invalid command, or an invalid location
position, it will generally preface the message with
@code{***}. However if annotation mode is on that the message is put
in a @code{begin-error} annotation and no @code{***} appears.
@node Help
@section Getting help (@samp{help})
@cindex on-line documentation
@menu
* Help for Subcommands::
@end menu
Once inside @code{ruby-debug} you can always ask it for information on
its commands, using the command @code{help}.
@table @code
@kindex h @r{(@code{help})}
@kindex help @ovar{command-name}
@item help
@itemx h
You can use @code{help} (abbreviated @code{h}) with no arguments to
display a short list of named classes of commands:
@flushleft
@smallexample
(rdb:1) @b{help}
ruby-debug help v@value{RDEBUG_VERSION}
Type 'help <command-name>' for help on a specific command
Available commands:
backtrace delete enable help list ps save thread where
break disable eval info method putl set trace
catch display exit irb next quit show undisplay
condition down finish jump p reload source up
continue edit frame kill pp restart step var
@end smallexample
@end flushleft
@c the above line break eliminates huge line overfull...
@end table
@table @code
@item help @var{command}
With a command name as @code{help} argument, @DBG displays short
information on how to use that command.
@smallexample
(rdb:1) @b{help list}
ruby-debug help v@value{RDEBUG_VERSION}
l[ist] list forward
l[ist] - list backward
l[ist] = list current line
l[ist] nn-mm list given lines
* NOTE - to turn on autolist, use 'set autolist'
(rdb:1)
@end smallexample
@end table
@node Help for Subcommands
@subsection Help on Subcommands
A number of commands have many sub-parameters or
@emph{subcommands}. These include @code{info}, @code{set},
@code{show}, @code{enable} and @code{disable}.
When you ask for help for one of these commands, you will get help for
all of the subcommands that that command offers. Sometimes you may
want help that subcommand and to do this just follow the command with
its subcommand name. For example @code{help set annotate} will just
give help about the annotate command. Furthermore it will give longer
help than the summary information that appears when you ask for
help. You don't need to list the full subcommand name, but just enough
of the letters to make that subcommand distinct from others will
do. For example, @code{help set an} is the same as @code{help set annotate}.
Some examples follow.
@example
(rdb:1) @b{help info}
Generic command for showing things about the program being debugged.
--
List of info subcommands:
--
info args -- Argument variables of current stack frame
info breakpoints -- Status of user-settable breakpoints
info catch -- Exceptions that can be caught in the current stack frame
info display -- Expressions to display when program stops
info file -- Info about a particular file read in
info files -- File names and timestamps of files read in
info global_variables -- Global variables
info instance_variables -- Instance variables of the current stack frame
info line -- Line number and file name of current position in source file
info locals -- Local variables of the current stack frame
info program -- Execution status of the program
info stack -- Backtrace of the stack
info thread -- List info about thread NUM
info threads -- information of currently-known threads
info variables -- Local and instance variables of the current stack frame
@end example
@example
(rdb:1) @b{help info breakpoints}
Status of user-settable breakpoints.
Without argument, list info about all breakpoints. With an
integer argument, list info on that breakpoint.
@end example
@example
(rdb:1) @b{help info br}
Status of user-settable breakpoints.
Without argument, list info about all breakpoints. With an
integer argument, list info on that breakpoint.
@end example
@node Control
@section Controlling the debugger (@samp{quit}, @samp{restart}, @samp{interrupt}, @samp{source})
@menu
* Quit:: Quitting the debugger (quit)
* Restart:: Restarting Script execution (restart)
* Interrupt:: Interrupting the debugger (interrupt)
* Source:: Running Debugger commands (source)
@end menu
@node Quit
@subsection Quit (@samp{quit})
@table @code
@kindex quit @r{[}unconditionally@r{]}
@kindex q @r{(@code{quit})}
@item quit @r{[}unconditionally@r{]}
@item exit
@itemx q
To exit @value{DBG}, use the @code{quit} command (abbreviated
@code{q}), or alias @code{exit}.
A simple @code{quit} tries to terminate all threads in effect.
Normally if you are in an interactive session, this command will
prompt to ask if you really want to quit. If you don't want any
questions asked, enter the ``unconditionally''.
@end table
@node Restart
@subsection Restart (@samp{restart})
@table @code
@kindex restart @r{[}@var{program args}@r{]}
@kindex R @r{(@code{restart})}
@item restart
@itemx R
Restart the program. This is a re-exec - all debugger state is
lost. If command arguments are passed those are used. Otherwise the
last program arguments used in the last invocation are used.
In not all cases will you be able to restart the program. First, the
program should have been invoked at the outset rather than having been
called from inside your program or invoked as a result of post-mortem
handling.
Also, since this relies on the the OS @code{exec} call, this command
is available only if your OS supports that @code{exec}; OSX for
example does not (yet).
@end table
@node Interrupt
@subsection Interrupt (@samp{interrupt})
@table @code
@kindex interrupt
@kindex i
@item interrupt
@itemx i
Interrupt the program. Useful if there are multiple threads running.
@end table
@node Source
@subsection Running Debugger Commands (@samp{source})
@table @code
@kindex source @var{filename}
@item source @var{filename}
Execute the command file @var{filename}.
The lines in a command file are executed sequentially. They are not
printed as they are executed. If there is an error, execution
proceeds to the next command in the file. For information about
command files that get run automatically on startup, @pxref{Command Files}.
@end table
@node DisplayCommands
@section Executing expressions on stop (@samp{display}, @samp{undisplay})
@cindex automatic display
@cindex display of expressions
If you find that you want to print the value of an expression
frequently (to see how it changes), you might want to add it to the
@dfn{automatic display list} so that @value{DBG} evaluates a statement
each time your program stops or the statement is shown in line tracing.
Each expression added to the list is given a number to identify it; to
remove an expression from the list, you specify that number. The
automatic display looks like this:
@smallexample
(rdb:1) display n
1: n = 3
@end smallexample
@noindent
This display shows item numbers, expressions and their current values.
If the expression is undefined or illegal the expression will be
printed but no value will appear.
@smallexample
(rdb:1) display undefined_variable
2: undefined_variable =
(rdb:1) display 1/0
3: 1/0 =
@end smallexample
Note: this command uses @code{to_s} to in expressions; for example an
array @code{[1, 2]} will appear as @code{12}. For some datatypes like
an Array, you may want to call the @code{inspect} method, for example
@code{display ARGV.inspect} rather than @code{display ARGV}.
@table @code
@kindex display @ovar{expr}
@item display @var{expr}
Add the expression @var{expr} to the list of expressions to display
each time your program stops or a line is printed when linetracing is
on (@pxref{DisplayCommands}).
@item display
Display the current values of the expressions on the list, just as is
done when your program stops.
@kindex undisplay @ovar{num}
@item undisplay @ovar{num}
@itemx delete display @var{num}
Remove item number @var{num} from the list of expressions to display.
@kindex info display
@item info display
Show all display expressions
@ifset GDB_COMPLETED
@code{undisplay} does not repeat if you press @key{RET} after using it.
(Otherwise you would just get the error @samp{No display number @dots{}}.)
@end ifset
@kindex disable display
@item disable display @var{dnums}@dots{}
Disable the display of item numbers @var{dnums}. A disabled display
item is not printed automatically, but is not forgotten. It may be
enabled again later.
@kindex enable display
@item enable display @var{dnums}@dots{}
Enable display of item numbers @var{dnums}. It becomes effective once
again in auto display of its expression, until you specify otherwise.
@end table
@node PrintCommands
@section Evaluating and Printing Expressions (@samp{p}, @samp{pp}, @samp{putl}, @samp{ps}, @samp{irb})
One way to examine and change data in your script is with the
@code{eval} command (abbreviated @code{p}). A similar command is
@code{pp} which tries to pretty print the result. Finally @code{irb} is
useful when you anticipate examining or changing a number of things,
and prefer not to have to preface each command, but rather work as one
does in @code{irb}.
@menu
* eval:: eval or print an expression (eval, p)
* pp:: pretty print an expression (pp, ps, putl)
* irb:: running irb using the current context
@end menu
@node eval
@subsection Printing an expression (@samp{eval}, @samp{p})
@table @code
@kindex eval @var{expr}
@kindex p @r{(@code{eval})}
@item eval @var{expr}
@itemx p @var{expr}
Use @code{eval} or @code{p} to evaluate a Ruby expression, @var{expr},
same as you would if you were in @code{irb}. If there are many expressions
you want to look at, you may want to go into irb from the debugger.
@smallexample
@group
(rdb:p) p n
3
(rdb:1) p "the value of n is #@{n@}"
"the value of n is 3"
(rdb:1)
@end group
@end smallexample
@end table
@node pp
@subsection Pretty-Printing an expression (@samp{pp}, @samp{putl}, @samp{ps}))
@table @code
@item pp
@kindex pp @var{expr}
Evaluates and pretty-prints @var{expr}
@smallexample
@group
(rdb:1) @b{p $LOAD_PATH}
["/home/rocky/lib/ruby", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i586-linux", "/usr/lib/ruby/1.8"]
(rdb:1) @b{pp $LOAD_PATH}
["/home/rocky/lib/ruby",
"/usr/lib/ruby/site_ruby/1.8",
"/usr/lib/ruby/site_ruby/1.8/i586-linux",
"/usr/lib/ruby/1.8"]
@end group
@end smallexample
@kindex putl
@item putl
If the value you want to print is an array, sometimes a columnized
list looks nicer:
@smallexample
@group
(rdb:1) @b{putl $LOAD_PATH}
/home/rocky/lib/ruby /usr/lib/ruby/site_ruby/1.8
/usr/lib/ruby/site_ruby/1.8/i586-linux /usr/lib/ruby/1.8
@end group
@end smallexample
Note however that entries are sorted to run down first rather than
across. So in the example above the second entry in the list is
@code{/usr/lib/ruby/site_ruby/1.8/i586-linux} and the @emph{third} entry is
@code{/usr/lib/ruby/site_ruby/1.8}.
If the value is not an array @code{putl} will just call pretty-print.
@kindex ps
@item ps
Sometimes you may want to print the array not only columnized, but
sorted as well. The list of debugger help commands appears this way,
and so does the output of the @code{method} commands.
@smallexample
@group
(rdb:1) ps Kernel.private_methods
Digest initialize y
Pathname initialize_copy
Rational location_of_caller
active_gem_with_options method_added
alias_method method_removed
append_features method_undefined
attr module_function
attr_accessor private
attr_reader protected
attr_writer public
class_variable_get remove_class_variable
class_variable_set remove_const
define_method remove_instance_variable
extend_object remove_method
extended singleton_method_added
gcd singleton_method_removed
gem_original_require singleton_method_undefined
include timeout
included undef_method
@end group
@end smallexample
If the value is not an array, @code{ps} will just call pretty-print.
See also the @code{methods}.
@end table
@node irb
@subsection Run irb (@samp{irb})
@table @code
@kindex irb
@item irb
Run an interactive ruby session (@code{irb}) with the bindings
environment set to the state you are in the program.
When you leave irb and go back to the debugger command prompt we show
again the file, line and text position of the program in the same way
as when entered the debugger. If you issue a @command{list} without
location information, the default location used is the current line
rather than the position may have gotten updated via a prior
@command{list} command.
@smallexample
triangle.rb:4
def triangle(n)
(rdb:1) @b{list}
[-1, 8] in /home/rocky/ruby/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
@b{irb}
>> @b{(0..6).inject@{|sum, i| sum +=i@}}
=> 21
>> @b{exit}
triangle.rb:4
def triangle(n)
(rdb:1) @b{list # Note we get the same line range as before going into irb}
[-1, 8] in /home/rocky/ruby/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
@end smallexample
@end table
@node PrintVars
@section Printing Variables (@samp{var}, @samp{method})
@table @code
@item var const @var{object}
@kindex var const @var{expr}
Show the constants of @var{object}. This is basically listing
variables and their values in @var{object}@code{.constant}.
@item var instance @var{object}
@kindex var instance @var{expr}
Show the instance variables of @var{object}. This is basically listing
@var{object}@code{.instance_variables}.
@item info instance_variables
@kindex info instance_variables
Show instance_variables of @code{@@self}
@item info locals
@kindex info locals
Show local variables
@item info globals
@kindex info globals
Show global variables
@item info variables
@kindex info variables
Show local and instance variables of @code{@@self}
@item method instance @var{object}
@kindex method instance @var{object}
Show methods of @var{object}. Basically this is the same as running
@code{ps object.instance_methods(false)} on @var{object}.
@item method iv @var{object}
@kindex method iv @var{object}
Show method instance variables of @var{object}. Basically this is the same as running
@smallexample
obj.instance_variables.each do |v|
puts "%s = %s\n" % [v, obj.instance_variable_get(v)]
end
@end smallexample
on @var{object}.
@item signature @var{object}
@kindex method signature @var{object}
Show procedure signature of method @var{object}.
@emph{This command is available only if the nodewrap is installed.}
@smallexample
def mymethod(a, b=5, &bock)
end
(rdb:1) @b{method sig mymethod}
Mine#mymethod(a, b=5, &bock)
@end smallexample
on @var{object}.
@item method @var{class-or-module}
@kindex method @var{class-or-module}
Show methods of the class or module, @var{class-or-module}. Basically
this is the same as running @code{ps object.methods} on @var{class-or-module}.
on @var{class-or-module}.
@end table
@node List
@section Examining Program Source Files (@samp{list})
@cindex current line
@value{DBG} can print parts of your script's source. When your script
stops, @value{DBG} spontaneously prints the line where it stopped and
the text of that line. Likewise, when you select a stack frame
(@pxref{Selection}) @value{DBG} prints the line where execution in
that frame has stopped. Implicitly there is a default line
location. Each time a list command is run that implicit location is
updated, so that running several list commands in succession shows a
contiguous block of program text.
You can print other portions of source files by giving an explicit
position as a parameter to the list command.
If you use @value{DBG} through its Emacs interface, you may prefer to
use Emacs facilities to view source.
@c @pxref{GNU Emacs}.
@kindex list @ovar{line-number}
@kindex l @r{(@code{list})}
To print lines from a source file, use the @code{list} command
(abbreviated @code{l}). By default, ten lines are printed. Fewer may
appear if there fewer lines before or after the current line to center
the listing around.
There are several ways to specify what part of the file you want to print.
Here are the forms of the @code{list} command.
@table @code
@item list @var{line-number}
@itemx l @var{line-number}
Print lines centered around line number @var{line-number} in the
current source file.
@item list
@itemx l
Print more lines. If the last lines printed were printed with a
@code{list} command, this prints lines following the last lines
printed; however, if the last line printed was a solitary line printed
as part of displaying a stack frame (@pxref{Frames}), this prints lines
centered around that line.
@item list -
@itemx l -
Print lines just before the lines last printed.
@item list @var{first}-@var{last}
Print lines between @var{first} and @var{last} inclusive.
@item list =
Print lines centered around where the script is stopped.
@end table
Repeating a @code{list} command with @key{RET} discards the argument,
so it is equivalent to typing just @code{list}. This is more useful
than listing the same lines again. An exception is made for an
argument of @samp{-}; that argument is preserved in repetition so that
each repetition moves up in the source file.
@node Edit
@section Editing Source files (@samp{edit})
To edit the lines in a source file, use the @code{edit} command. The
editing program of your choice is invoked with the current line set to
the active line in the program. Alternatively, you can give a line
specification to specify what part of the file you want to print if
you want to see other parts of the program.
You can customize to use any editor you want by using the
@code{EDITOR} environment variable. The only restriction is that your
editor (say @code{ex}), recognizes the following command-line syntax:
@smallexample
ex +@var{number} file
@end smallexample
The optional numeric value +@var{number} specifies the number of the
line in the file where to start editing. For example, to configure
@value{DBG} to use the @code{vi} editor, you could use these commands
with the @code{sh} shell:
@smallexample
EDITOR=/usr/bin/vi
export EDITOR
gdb @dots{}
@end smallexample
or in the @code{csh} shell,
@smallexample
setenv EDITOR /usr/bin/vi
gdb @dots{}
@end smallexample
@table @code
@kindex edit @ovar{line-specification}
@item edit @ovar{line specification}
Edit line specification using the editor specified by the
@code{EDITOR} environment variable.
@end table
@node FrameCommands
@section Examining the Stack Frame (@samp{where}, @samp{up}, @samp{down}, @samp{frame})
When your script has stopped, one thing you'll probably want to know
is where it stopped and some idea of how it got there.
@cindex call stack
Each time your script performs a function or sends a message to a
method, or enters a block, information about this action is saved.
The frame stack then is this a history of the blocks that got you to
the point that you are currently stopped at.@footnote{More accurately
we should call this a ``block stack''; but we'll use the name that is
more commonly used. And internally in Ruby, there is ``FRAME''
structure which is yet slightly different.}
@cindex selected block
One entry in call stack is @dfn{selected} by @DBG{} and many
@DBG commands refer implicitly to the selected block. In
particular, whenever you ask @DBG to list lines without giving
a line number or location the value is found in the selected frame.
There are special @DBG commands to select whichever frame you
are interested in. @xref{Selection, ,Selecting a frame}.
When your program stops, @DBG{} automatically selects the
currently executing frame and describes it briefly, similar to the
@code{frame} command.
After switching frames, when you issue a @code{list} command without
any position information, the position used is location in the frame
that you just switched between, rather than a location that got
updated via a prior @code{list} command.
@menu
* Frames:: Stack frames
* Backtrace:: Backtraces (where)
* Selection:: Selecting a frame (up, down, frame)
@end menu
@node Frames
@subsection Stack frames
@cindex frame, definition
@cindex stack frame
The block stack is divided up into contiguous pieces called @dfn{stack
frames}, @dfn{frames}, or @dfn{blocks} for short; each frame/block has
a scope associated with it; It contains a line number and the
source-file name that the line refers. If the frame/block is the beginning
of a method or function it also contains the function name.
@cindex initial frame
@cindex outermost frame
@cindex innermost frame
When your script is started, the stack has only one frame, that of the
function @code{main}. This is called the @dfn{initial} frame or the
@dfn{outermost} frame. Each time a function is called, a new frame is
made. Each time a function returns, the frame for that function invocation
is eliminated. If a function is recursive, there can be many frames for
the same function. The frame for the function in which execution is
actually occurring is called the @dfn{innermost} frame. This is the most
recently created of all the stack frames that still exist.
@cindex frame number
@value{DBG} assigns numbers to all existing stack frames, starting with
zero for the innermost frame, one for the frame that called it,
and so on upward. These numbers do not really exist in your script;
they are assigned by @value{DBG} to give you a way of designating stack
frames in @value{DBG} commands.
@node Backtrace
@subsection Backtraces (@samp{where})
@cindex backtraces
@cindex tracebacks
@cindex stack traces
A backtrace is essentially the same as the call stack: a summary of
how your script got where it is. It shows one line per frame, for
many frames, starting with the place that you are stopped at (frame
zero), followed by its caller (frame one), and on up the stack.
@table @code
@kindex where
@kindex w @r{(@code{where})}
@itemx where
Print the entire stack frame; @code{info stack} is an alias for this command.
Each frame is numbered and can be referred to in the @code{frame}
command; @code{up} and @code{down} add or subtract respectively to
frame numbers shown. The position of the current frame is marked with
@code{-->}.
@smallexample
(rdb:1) where
--> #0 Object.gcd(a#Fixnum, b#Fixnum) at line /tmp/gcd.rb:6
#1 at line /tmp/gcd.rb:19
@end smallexample
@ifset FINISHED
@item backtrace @var{n}
@itemx bt @var{n}
@itemx where @var{n}
@itemx T @var{n}
Similar, but print only the innermost @var{n} frames.
@item backtrace -@var{n}
@itemx bt -@var{n}
@itemx where -@var{n}
@itemx T -@var{n}
Similar, but print only the outermost @var{n} frames.
@end ifset
@end table
@node Selection
@subsection Selecting a frame (@samp{up}, @samp{down}, @samp{frame})
Commands for listing source code in your script work on whichever
stack frame is selected at the moment. Here are the commands for
selecting a stack frame; all of them finish by printing a brief
description of the stack frame just selected.
@table @code
@kindex up @ovar{n}
@item up @ovar{n}
Move @var{n} frames up the stack. For positive numbers @var{n}, this
advances toward the outermost frame, to higher frame numbers, to
frames that have existed longer. Using a negative @var{n} is the same thing
as issuing a @code{down} command of the absolute value of the @var{n}.
Using zero for @var{n} does no frame adjustment, but since the current
position is redisplayed, it may trigger a resynchronization if there is
a front end also watching over things.
@var{n} defaults to one. You may abbreviate @code{up} as @code{u}.
@kindex down @ovar{n}
@item down @ovar{n}
Move @var{n} frames down the stack. For positive numbers @var{n}, this
advances toward the innermost frame, to lower frame numbers, to frames
that were created more recently. Using a negative @var{n} is the same
as issuing a @code{up} command of the absolute value of the @var{n}.
Using zero for @var{n} does no frame adjustment, but since the current
position is redisplayed, it may trigger a resynchronization if there is
a front end also watching over things.
@var{n} defaults to one.
@end table
@table @code
@kindex frame @r{[}@ovar{n} @r{[}thread @var{thread-num}@r{]}@r{]}
@cindex current stack frame
@item frame @ovar{n} @r{[}thread @var{thread-num}@r{]}
The @code{frame} command allows you to move from one stack frame to
another, and to print the stack frame you select. @var{n} is the the
stack frame number or 0 if no frame number is given; @code{frame 0}
then will always show the current and most recent stack frame.
If a negative number is given, counting is from the other end of the
stack frame, so @code{frame -1} shows the least-recent, outermost or
most ``main'' stack frame.
Without an argument, @code{frame} prints the current stack
frame. Since the current position is redisplayed, it may trigger a
resynchronization if there is a front end also watching over
things.
If a thread number is given then we set the context for evaluating
expressions to that frame of that thread.
@end table
@node Stopping
@section Stopping and Resuming Execution
One important use of a debugger is to stop your program @emph{before}
it terminates, so that if your script runs into trouble you can
investigate and find out why. However should your script accidentally
continue to termination, it can be arranged for @DBG to not to leave
the debugger without your explicit instruction. That way, you can
restart the program using the same command arguments.
Inside @value{DBG}, your script may stop for any of several reasons,
such as a signal, a breakpoint, or reaching a new line after a
debugger command such as @code{step}. You may then examine and
change variables, set new breakpoints or remove old ones, and then
continue execution.
@menu
* Breakpoints:: Breakpoints (break, catch, delete)
* Disabling:: Disabling breakpoints (disable, enable)
* Conditions:: Break conditions (condition)
* Resuming Execution:: Resuming execution (continue, step, next, finish)
@end menu
@node Breakpoints
@subsection Breakpoints (@samp{break}, @samp{catch}, @samp{delete})
@cindex breakpoints
A @dfn{breakpoint} makes your script stop whenever a certain point in
the program is reached. For each breakpoint, you can add conditions to
control in finer detail whether your script stops.
You specify the place where your script should stop with the
@code{break} command and its variants.
@cindex breakpoint numbers
@cindex numbers for breakpoints
@value{ttDBG} assigns a number to each breakpoint when
you create it; these numbers are successive integers starting with
one. In many of the commands for controlling various features of
breakpoints you use the breakpoint number to say which breakpoint you
want to change. Each breakpoint may be @dfn{enabled} or
@dfn{disabled}; if disabled, it has no effect on your script until you
enable it again.
@table @code
@kindex break @ovar{location}
@kindex b @r{(@code{break})}
@item break
Set a breakpoint at the current line.
@item break @var{linenum}
Set a breakpoint at line @var{linenum} in the current source file.
The current source file is the last file whose source text was printed.
The breakpoint will stop your script just before it executes any of the
code on that line.
@item break @var{filename}:@var{linenum}
Set a breakpoint at line @var{linenum} in source file @var{filename}.
What may be a little tricky when specifying the filename is getting
the name recognized by the debugger. If you get a message the message
``@code{No source file named ...}'', then you may need to qualify the
name more fully. To see what files are loaded you can use the @code{info
files} or @code{info file} commands. If you want the name @code{rdebug} thinks
of as the current file, use @code{info line}.
Here's an example:
@example
$ @b{rdebug ~/ruby/gcd.rb 3 5}
/home/rocky/ruby/gcd.rb:4 # Note this is the file name
def gcd(a, b)
(rdb:1) @b{break gcd.rb:6}
*** No source file named gcd.rb
(rdb:1) @b{info line}
Line 4 of "/home/rocky/ruby/gcd.rb"
(rdb:1) @b{break /home/rocky/ruby/gcd.rb:6}
Breakpoint 1 file /home/rocky/ruby/gcd.rb, line 6
(rdb:1) @b{break ~/ruby/gcd.rb:10} # tilde expansion also works
Breakpoint 2 file /home/rocky/ruby/gcd.rb, line 10
(rdb:1) @b{info file gcd.rb}
File gcd.rb is not cached
(rdb:1) @b{info file /home/rocky/ruby/gcd.rb}
File /home/rocky/ruby/gcd.rb
19 lines
@end example
@item break @var{class}:@var{method}
Set a breakpoint in class @var{class} method @var{method}. You can
also use a period @code{.} instead of a colon @code{:}. Note that two
colons @code{::} are not used. Also note a class @emph{must} be
specified here. If the method you want to stop in is in the main class
(i.e. the class that @code{self} belongs to at the start of the
program), then use the name @code{Object}.
@kindex catch @ovar{exception} @r{[} on | 1 | off | 0 @r{]}
@kindex cat @r{(@code{catch})}
@item catch @ovar{exception} @r{[} on | 1 | off | 0 @r{]}
Set catchpoint to an exception. Without an exception name show catchpoints.
With an ``on'' or ``off'' parameter, turn handling the exception on or
off. To delete all exceptions type ``catch off''.
@cindex delete breakpoints
@kindex delete @ovar{breakpoints}
@kindex del @r{(@code{delete})}
@item delete @ovar{breakpoints}
Delete the breakpoints specified as arguments.
If no argument is specified, delete all breakpoints (@DBG asks
confirmation. You can abbreviate this command as @code{del}.
@kindex info breakpoints
@cindex @code{$_} and @code{info breakpoints}
@item info breakpoints @ovar{n}
@itemx info break @ovar{n}
Print a table of all breakpoints set and not deleted, with the
following columns for each breakpoint:
@table @emph
@item Breakpoint Numbers (@samp{Num})
@item Enabled or Disabled (@samp{Enb})
Enabled breakpoints are marked with @samp{1}. @samp{0} marks breakpoints
that are disabled (not enabled).
@item File and Line (@samp{file:line})
The filename and line number inside that file where of breakpoint in
the script. The file and line are separated with a colon.
@item Condition
A condition (an arithmetic expression) which when true causes the
breakpoint to take effect.
@end table
@noindent
If a breakpoint is conditional, @code{info break} shows the condition on
the line following the affected breakpoint; breakpoint commands, if any,
are listed after that.
@code{info break} with a breakpoint number @var{n} as argument lists
only that breakpoint.
Examples:
@example
(rdb:1) @b{info break}
Breakpoints at following places:
Num Enb What
1 y gcd.rb:3
2 y gcb.rb:28 if n > 1
(rdb:1) @b{info break 2}
2 y gcb.rb:28 if n > 1
@end example
@end table
@node Disabling
@subsection Disabling breakpoints (@samp{disable}, @samp{enable})
Rather than deleting a breakpoint, you might
prefer to @dfn{disable} it. This makes the breakpoint inoperative as if
it had been deleted, but remembers the information on the breakpoint so
that you can @dfn{enable} it again later.
You disable and enable breakpoints and catchpoints with the
@code{enable} and @code{disable} commands, optionally specifying one
or more breakpoint numbers as arguments. Use @code{info break} to
print a list of breakpoints and catchpoints if you do not know which
numbers to use.
A breakpoint or catchpoint can have any different
states of enablement:
@itemize @bullet
@item
Enabled. The breakpoint stops your program. A breakpoint set
with the @code{break} command starts out in this state.
@item
Disabled. The breakpoint has no effect on your program.
@end itemize
You can use the following commands to enable or disable breakpoints
and catchpoints:
@table @code
@kindex disable breakpoints
@item disable @var{breakpoints}
Disable the specified breakpoints---or all breakpoints, if none are
listed. A disabled breakpoint has no effect but is not forgotten. All
options such as ignore-counts, conditions and commands are remembered in
case the breakpoint is enabled again later. You may abbreviate
@code{disable} as @code{dis}.
@kindex enable breakpoints
@item enable @var{breakpoints}
Enable the specified breakpoints (or all defined breakpoints). They
become effective once again in stopping your program.
@end table
Breakpoints that you set are initially enabled; subsequently, they
become disabled or enabled only when you use one of the commands
above. (The command @code{until} can set and delete a breakpoint of
its own, but it does not change the state of your other breakpoints;
see @ref{Resuming Execution, ,Resuming Execution}.)
@node Conditions
@subsection Break conditions (@samp{condition})
@cindex conditional breakpoints
@cindex breakpoint conditions
The simplest sort of breakpoint breaks every time your script reaches
a specified place. You can also specify a @dfn{condition} for a
breakpoint. A condition is just a Ruby expression.
Break conditions can be specified when a breakpoint is set, by using
@samp{if} in the arguments to the @code{break} command. A breakpoint
with a condition evaluates the expression each time your script
reaches it, and your script stops only if the condition is
@emph{true}. They can also be changed at any time
with the @code{condition} command.
@ifset FINISHED
You can also use the @code{if} keyword with the @code{watch} command.
The @code{catch} command does not recognize the @code{if} keyword;
@code{condition} is the only way to impose a further condition on a
catchpoint.
@end ifset
@table @code
@kindex condition
@item condition @var{bnum} @var{expression}
Specify @var{expression} as the break condition for breakpoint
@var{bnum}. After you set a condition, breakpoint @var{bnum} stops
your program only if the value of @var{expression} is true (nonzero).
@item condition @var{bnum}
Remove the condition from breakpoint number @var{bnum}. It becomes
an ordinary unconditional breakpoint.
@end table
@ifset FINISHED
When you use @code{condition}, @DBG checks @var{expression}
immediately for syntactic correctness, and to determine whether
symbols in it have referents in the context of your breakpoint. If
@var{expression} uses symbols not referenced in the context of the
breakpoint, @DBG prints an error message:
@example
No symbol "foo" in current context.
@end example
@end ifset
@noindent
The debugger does not actually evaluate @var{expression} at the time
the @code{condition} command (or a command that sets a breakpoint with
a condition, like @code{break if @dots{}}) is given, however.
Examples;
@example
condition 1 x>5 # Stop on breakpoint 0 only if x>5 is true.
condition 1 # Change that! Unconditionally stop on breakpoint 1.
@end example
@node Resuming Execution
@subsection Resuming Execution (@samp{step}, @samp{next}, @samp{finish}, @samp{continue}, @samp{jump})
A typical technique for using stepping is to set a breakpoint
(@pxref{Breakpoints}) at the beginning of the function or the section
of your script where a problem is believed to lie, run your script
until it stops at that breakpoint, and then step through the suspect
area, examining the variables that are interesting, until you see the
problem happen.
@cindex stepping
@cindex continuing
@cindex resuming execution
@dfn{Continuing} means resuming program execution until your script
completes normally. In contrast, @dfn{stepping} means executing just
one more ``step'' of your script, where ``step'' may mean either one
line of source code. Either when continuing or when stepping,
your script may stop even sooner, due to a breakpoint or a signal.
@menu
* Step:: running the next statement (step)
* Next:: running the next statement skipping over functions (next)
* Finish:: running until the return of a function or ``source'' (finish)
* Continue:: continuing execution (continue)
* Jump:: jumping to a new line (jump)
@end menu
@node Step
@subsubsection Step (@samp{step})
@table @code
@kindex step @r{[}+@r{]} @ovar{count}
@kindex s @r{(@code{step})}
@item step @r{[}+-@r{]} @ovar{count}
Continue running your program until the next logical stopping point
and return control to @value{DBG}. This command is abbreviated
@code{s}.
Like, the programming Lisp, Ruby tends implemented in a highly
expression-oriented manner. Therefore things that in other languages
that may appear to be a single statement are implemented in Ruby as
several expressions. For example, in an ``if'' statement or looping
statements a stop is made after the expression is evaluated but before
the test on the expression is made.
So it is common that a lines in the program will have several stopping
points where in other debuggers of other languages there would be only
one. Or you may have several statements listed on a line.
When stepping it is not uncommon to want to go to a different line on
each step. If you want to make sure that on a step you go to a
@emph{different} position, add a plus sign (@samp{+}).
@emph{Note: step+ with a number count is not the same as issuing
count step+ commands. Instead it uses count-1 step commands followed
by a step+ command. For example, @code{step+ 3} is the
same as @code{step; step; step+}, not @code{step+; step+; step+}}
If you find yourself generally wanting to use @code{step+} rather
than @code{step}, you may want to consider using @code{set
forcestep}, (@pxref{Forcestep}).
If you have @code{forcestep} set on but want to temporarily disable it
for the next step command, append a minus, or @code{step-}.
With a count, @code{step} will continue running as normal, but do so
@var{count} times. If a breakpoint is reached, or a signal not
related to stepping occurs before @var{count} steps, stepping stops
right away.
@end table
@node Next
@subsubsection Next (@samp{next})
@table @code
@kindex next @r{[}+-@r{]} @ovar{count}
@kindex n @r{(@code{next})}
@item next @r{[}+@r{]} @ovar{count}
This is similar to @code{step}, but function or method calls that
appear within the line of code are executed without stopping. As with
step, if you want to make sure that on a step you go to a
@emph{different} position, add a plus sign (@samp{+}). Similarly,
appending a minus disables a @code{forcestep} temporarily, and an
argument @var{count} is a repeat count, as for @code{step}.
@end table
@node Finish
@subsubsection Finish (@samp{finish})
@table @code
@kindex finish @ovar{frame-number}
@item finish @ovar{frame-number}
Execute until selected stack frame returns. If no frame number is
given, we run until the currently selected frame returns. The
currently selected frame starts out the most-recent frame or 0 if no
frame positioning (e.g@: @code{up}, @code{down} or @code{frame}) has
been performed. If a frame number is given we run until @var{frame} frames
returns.
If you want instead to terminate the program and debugger entirely,
use @code{quit} (@pxref{Quitting the debugger, ,Quitting the debugger}).
@end table
@node Continue
@subsubsection Continue (@samp{continue})
@table @code
@kindex continue @ovar{line-specification}
@kindex c @r{(@code{continue})}
@item continue @ovar{line-specification}
@itemx c @ovar{line-specification}
Resume program execution, at the address where your script last
stopped; any breakpoints set at that address are bypassed.
The optional argument @var{line-specification} allows you to specify a
line number to set a one-time breakpoint which is deleted when that
breakpoint is reached.
Should the program stop before that breakpoint is reached, for
example, perhaps another breakpoint is reached first, in
a listing of the breakpoints you won't see this entry in the list of
breakpoints.
@end table
@node Jump
@subsubsection Jump (@samp{jump})
@table @code
@kindex jump @r{[}+-@r{]} @ovar{line}
@item jump @r{[}+-@r{]} @ovar{line}
Change the next line to execute to the given line number.
@end table
@node ruby-debug settings
@section ruby-debug settings (@samp{set args}, @samp{set autoeval}..)
You can alter the way ruby-debug interacts with you using @code{set}
commands.
The various parameters to @code{set} are given below. Each parameter
name needs to to be only enough to make it unique. For example
@code{set force} is a suitable abbreviation for @code{set forcestep}.
The letter case is not important, so @code{set FORCE} or @code{set
Force} are also suitable abbreviations.
Many @code{set} commands are either ``on'' or ``off'', and you can
indicate which way you want set by supplying the corresponding
word. The number 1 can be used for ``on'' and 0 for ``off''. If none
of these is given, we will assume ``on''. A deprecated way of turning
something off is by prefacing it with ``no''.
Each @code{set} command has a corresponding @code{show} command which
allows you to see the current value.
@menu
* Args:: Annotation Level
* Autoeval:: Evaluate unrecognized commands
* Autolist:: Execute ``list'' command on every breakpoint
* Autoirb:: Invoke IRB on every stop
* Autoreload:: Reload source code when changed
* Basename:: Report file basename only showing file names
* Callstyle:: Show Report file basename only showing file names
* Forcestep:: Make sure 'next/step' commands always move to a new line
* Fullpath:: Display full file names in frames
* History:: Generic command for showing command history parameters.
* Keepframebindings:: Save frame binding on each call
* Linetrace:: line execution tracing
* Linetrace+:: line tracing style
* Listsize:: Number of lines to try to show in a 'list' command
* Post-mortem:: Whether post-mortem handling is in effect.
* Trace:: Display stack trace when 'eval' raises exception
* Width:: Number of characters the debugger thinks are in a line
@end menu
@node Args
@subsection Set/Show args
@table @code
@kindex set args @ovar{parameters}
@item set args @ovar{parameters}
Specify the arguments to be used if your program is rerun. If
@code{set args} has no arguments, @code{restart} executes your program
with no arguments. Once you have run your program with arguments,
using @code{set args} before the next @code{restart} is the only way to run
it again without arguments.
@kindex show args
@item show args
Show the arguments to give your program when it is started.
@end table
@node Autoeval
@subsection Set/Show auto-eval
@table @code
@kindex set autoeval @r{[} on | 1 | off | 0 @r{]}
@item set autoeval @r{[} on | 1 | off | 0 @r{]}
Specify that debugger input that isn't recognized as a command should
be passed to Ruby for evaluation (using the current debugged program
namespace). Note however that we @emph{first} check input to see if it
is a debugger command and @emph{only} if it is not do we consider it
as Ruby code. This means for example that if you have variable called
@code{n} and you want to see its value, you could use @code{p n},
because just entering @code{n} will be interpreted as the debugger
``next'' command.
See also @ref{irb} and @ref{Autoirb}.
When autoeval is set on, you'll get a different error message when you
invalid commands are encountered. Here's a session fragment to show
the difference
@smallexample
(rdb:1) @b{stepp}
Unknown command
(rdb:1) @b{set autoeval on}
autoeval is on.
(rdb:1) @b{stepp}
NameError Exception: undefined local variable or method `stepp' for ...
@end smallexample
@kindex show autoeval
@item show args
Shows whether Ruby evaluation of debugger input should occur or not.
@end table
@node Autolist
@subsection Execute ``list'' command on every breakpoint
@node Autoirb
@subsection Set/Show auto-irb
@table @code
@kindex set autoirb @r{[} on | 1 | off | 0 @r{]}
@item set autoirb @r{[} on | 1 | off | 0 @r{]}
When your program stops, normally you go into a debugger command loop
looking for debugger commands. If instead you would like to directly
go into an irb shell, set this on. See also @ref{Autoeval} or
@ref{irb} if you tend to use debugger commands but still want Ruby
evaluation occasionally.
@kindex show autoirb
@item show autoirb
Shows whether the debugger will go into irb on stop or not.
@end table
@node Autoreload
@subsection Set/Show auto-reload
@table @code
@kindex set autoreload @r{[} on | 1 | off | 0 @r{]}
Set this on if the debugger should check to see if the source has
changed since the last time it reread in the file if it has.
@end table
@node Basename
@subsection Set/Show basename
@table @code
@kindex set basename @r{[} on | 1 | off | 0 @r{]}
@item set basename @r{[} on | 1 | off | 0 @r{]}
Source filenames are shown as the shorter ``basename''
only. (Directory paths are omitted). This is useful in running the
regression tests and may useful in showing debugger examples as in
this text. You may also just want less verbose filename display.
By default filenames are shown as with their full path.
@kindex show basename
@item show basename
Shows the whether filename display shows just the file basename or not.
@end table
@node Callstyle
@subsection Set/Show call style
@table @code
@ifset FINISHED
@kindex set callstyle @r{[} short | last | tracked @r{]}
@item set forcestep @r{[} short | last | tracked @r{]}
@else
@kindex set callstyle @r{[} short | last
@item set forcestep @r{[} short | last
@end ifset
Sets how you want call parameters displayed; @code{short} shows just
the parameter names;
@ifset FINISHED
@code{last} shows the parameter names and the
class of these variables as they currently exist. Note the type could
have changed between when the call and its current
values.
@end ifset
@code{tracked} is the most accurate but this adds
overhead. On every call, scalar values of the parameters get
saved. For non-scalar values the class is saved.
@end table
@node Forcestep
@subsection Set/Show Forces Different Line Step/Next
@table @code
@kindex set forcestep @r{[} on | 1 | off | 0 @r{]}
@item set forcestep @r{[} on | 1 | off | 0 @r{]}
Due to the interpretive, expression-oriented nature of the Ruby
Language and implementation, each line often contains many possible
stopping points, while in a debugger it is often desired to treat each
line as an individual stepping unit.
Setting forcestep on will cause each @code{step} or @code{next}
command to stop at a different line number. See also @ref{Step} and
@ref{Next}.
@kindex show forcestep
@item show forcestep
Shows whether forcestep is in effect or not.
@end table
@node Fullpath
@subsection Set/Show Frame full path
@node History
@subsection Command History Parameters
@table @code
@item show commands
@kindex show commands
Display the last ten commands in the command history.
@item show commands @var{n}
@kindex show commands @var{n}
Print ten commands centered on command number @var{n}.
@item show history filename
@kindex show history filename
Show the filename in which to record the command history
(the list of previous commands of which a record is kept).
@item set history save @r{[} on | 1 | off | 0 @r{]}
@kindex set history save @r{[} on | 1 | off | 0 @r{]}
Set whether to save the history on exit.
@item show history save
@kindex show history save
Show saving of the history record on exit.
@item set history size @var{number}
@kindex set history size @var{number}
Set the maximum number of commands to save in the history.
@item show history size
@kindex show history size
Show the size of the command history, i.e. the number of previous
commands to keep a record of.
@end table
@node Keepframebindings
@subsection Save frame binding on each call
@node Linetrace
@subsection Set/Show Line tracing
@table @code
@kindex set linetrace @r{[} on | 1 | off | 0 @r{]}
@item set linetrace @r{[} on | 1 | off | 0 @r{]}
Setting linetrace on will cause lines to be shown before run.
@kindex show linetrace
@item show linetrace
Shows whether line tracing is in effect or not.
@end table
@node Linetrace+
@subsection Set/Show Line tracing style
@table @code
@kindex set linetrace+ @r{[} on | 1 | off | 0 @r{]}
@item set linetrace+ @r{[} on | 1 | off | 0 @r{]}
Setting linetrace+ on will cause consecutive trace lines not to be a
duplicate of the preceding line-trace line. Note however that this
setting doesn't by itself turn on or off line tracing.
@kindex show linetrace+
@item show linetrace
Shows whether the line tracing style is to show all lines or remove
duplicates linetrace lines when it is a repeat of the previous line.
@end table
@node Listsize
@subsection Set/Show lines in a List command
@table @code
@kindex set listsize @var{number-of-lines}
@item set listsize @var{number-of-lines}
Set number of lines to try to show in a @code{list} command.
@kindex show listsize
@item show listsize
Shows the list-size setting.
@end table
@node Post-mortem
@subsection Show Post-mortem handling
@table @code
@kindex show post-mortem
Shows wither post-mortem debugging is in effect. Right now we don't
have the ability to change the state inside the debugger.
@end table
@node Trace
@subsection Display stack trace when 'eval' raises exception
@node Width
@subsection Set/Show Line width
@table @code
@kindex set width @var{column-width}
@item set width @var{column-width}
Set number of characters the debugger thinks are in a line.
We also change OS environment variable @code{COLUMNS}.
@kindex show width
@item show width
Shows the current width setting.
@end table
@node Program Information
@section Program Information (@samp{info})
This @code{info} command (abbreviated @code{i}) is for describing the
state of your program. For example, you can list the current
parameters with @code{info args}, or list the breakpoints you have set
with @code{info breakpoints} or @code{info watchpoints}. You can get
a complete list of the @code{info} sub-commands with @w{@code{help
info}}.
@table @code
@kindex info args
@item info args
Method arguments of the current stack frame.
@kindex info breakpoints
@item info breakpoints
Status of user-settable breakpoints
@kindex info display
@item info display
All display expressions.
@kindex info files
@item info files
Source files in the program.
@kindex info file
@item info file @var{filename} @ovar{all|lines|mtime|sha1}
Information about a specific file. Parameter @code{lines} gives the
number of lines in the file, @code{mtime} shows the modification time
of the file (if available), @code{sha1} computes a SHA1 has of the
data of the file. @code{all} gives all of the above information.
@kindex info line
@item info line
Line number and file name of current position in source.
@kindex info locals
@item info locals
Local variables of the current stack frame.
@kindex info program
@item info program
Display information about the status of your program: whether it is
running or not and why it stopped. If an unhandled exception occurred,
the exception class and @code{to_s} method is called.
@kindex info stack
@item info stack
Backtrace of the stack. An alias for @code{where}. @xref{Backtrace}.
@kindex info thread
@item info thread @ovar{thread-number} @r{[} terse | verbose@r{]}
If no thread number is given, we list info for all
threads. @code{terse} and @code{verbose} options are possible. If terse,
just give summary thread name information. See information under @code{info threads} for
more detail about this summary information.
If @code{verbose} is appended to the end of the command, then the entire
stack trace is given for each thread.
@kindex info threads @r{[} terse | verbose@r{]}
@item info threads
List information about currently-known threads. This information
includes whether the thread is current (+), if it is suspended ($), or
ignored (!); the thread number and the top stack item. If
@code{verbose} is given then the entire stack frame is shown. Here is
an example:
@smallexample
(rdb:7) info threads
1 #<Thread:0xb7d08704 sleep> ./test/thread1.rb:27
!2 #<Debugger::DebugThread:0xb7782e4c sleep>
3 #<Thread:0xb777e220 sleep> ./test/thread1.rb:11
4 #<Thread:0xb777e144 sleep> ./test/thread1.rb:11
5 #<Thread:0xb777e07c sleep> ./test/thread1.rb:11
6 #<Thread:0xb777dfb4 sleep> ./test/thread1.rb:11
+ 7 #<Thread:0xb777deec run> ./test/thread1.rb:14
(rdb:1)
@end smallexample
Thread 7 is the current thread since it has a plus sign in front. Thread 2 is
ignored since it has a @code{!}. A ``verbose'' listing of the above:
@smallexample
(rdb:7) info threads verbose
1 #<Thread:0xb7d08704 sleep>
#0 Integer.join at line test/thread1.rb:27
#1 at line test/thread1.rb:27
!2 #<Debugger::DebugThread:0xb7782e4c sleep>
3 #<Thread:0xb777e220 sleep>
#0 sleep(count#Fixnum) at line test/thread1.rb:11
#1 Object.fn(count#Fixnum, i#Fixnum) at line test/thread1.rb:11
#2 at line test/thread1.rb:23
4 #<Thread:0xb777e144 sleep>
#0 sleep(count#Fixnum) at line test/thread1.rb:11
#1 Object.fn(count#Fixnum, i#Fixnum) at line test/thread1.rb:11
#2 at line test/thread1.rb:23
5 #<Thread:0xb777e07c sleep>
#0 sleep(count#Fixnum) at line test/thread1.rb:11
#1 Object.fn(count#Fixnum, i#Fixnum) at line test/thread1.rb:11
#2 at line test/thread1.rb:23
6 #<Thread:0xb777dfb4 sleep>
#0 sleep(count#Fixnum) at line test/thread1.rb:11
#1 Object.fn(count#Fixnum, i#Fixnum) at line test/thread1.rb:11
#2 at line test/thread1.rb:23
+ 7 #<Thread:0xb777deec run>
#0 Object.fn(count#Fixnum, i#Fixnum) at line test/thread1.rb:14
#1 at line test/thread1.rb:23
@end smallexample
@kindex info variables
@item info variables
Local and instance variables.
@end table
@node Post-Mortem Debugging
@chapter Post-Mortem Debugging
@cindex post-mortem debugging
It is also to possible enter the debugger when you have an uncaught
exception that is about to terminate our program. This is called
@emph{post-mortem debugging}. In this state many, of the debugger commands
for examining variables and moving around in the stack still
work. However some commands, such as those which imply a continuation
of running code, no longer work.
The most reliable way to set up post-mortem debugging is to use the
@option{--post-mortem} option in invoking @code{rdebug}. See @ref{rdebug
command-line options}. This traps/wraps at the debugger ``load'' of
your Ruby script. When this is done, your program is stopped after
the exception takes place, but before the stack has been
unraveled. (Alas, it would be nice to if one could allow resetting the
exception and continuing, but details of code in Ruby 1.8's
@code{eval.c} prevent this.)
If however you haven't invoked @code{rdebug} at the outset, but
instead call @code{ruby-debug} from inside your program, to set up
post-mortem debugging set the @code{post_mortem} key in
@code{Debugger.start}. Here's an example modified from
@url{http://www.datanoise.com/articles/2006/12/20/post-mortem-debugging}:
@smallexample
$ @b{cat t.rb }
require 'rubygems'
require 'ruby-debug' ; Debugger.start(:post_mortem => true)
def t1
raise 'test'
end
def t2
t1
end
t2
$ @b{ruby t.rb }
t.rb:8: raise 'test'
(rdb:post-mortem) @b{l=}
[3, 12] in t.rb
3
4 Debugger.start
5 Debugger.post_mortem
6
7 def t1
=> 8 raise 'test'
9 end
10 def t2
11 t1
12 end
(rdb:post-mortem)
@end smallexample
Alternatively you can call @code{Debugger.post_mortem()} after rdebug has
been started. The @code{post_mortem()} method can be called in two
ways. Called without a block, it installs a global @code{at_exit()} hook
that intercepts exceptions not handled by your Ruby script. In
contrast to using the @option{--post-mortem} option, when this hook
occurs after the call stack has been rolled back. (I'm not sure if
this in fact makes any difference operationally; I'm just stating it
because that's how it works.)
If you know that a particular block of code raises an exception you
can enable post-mortem mode by wrapping this block inside a
@code{Debugger.post_mortem} block
@smallexample
def offender
1/0
end
...
require "ruby-gems"
require "ruby-debug"
Debugger.post_mortem do
...
offender
...
end
@end smallexample
Once inside the debugger in post-mortem debugging, the prompt should
be @code{(rdb:post-mortem)}.
@node Debugger Module and Class
@chapter The Debugger Module and Class
@menu
* Debugger Module:: ruby-debug's Debugger module
* Debugger Class:: Debugger class
* Kernel routines:: Routines added to Kernel
@end menu
@node Debugger Module
@section The Debugger Module
@menu
* Debugger.run::
@ifset LATER
* Debugger.post-mortem::
@end ifset
* Debugger.context::
* Debugger.settings::
@end menu
@node Debugger.run
@subsection @code{Debugger.start}, @code{Debugger.started?}, @code{Debugger.stop}, @code{Debugger.run_script}
In order to provide better debugging information regarding the stack
frame(s) across all threads, ruby-debug has to intercept each call,
save some information and on return remove it. Possibly, in Ruby 1.9
possibly this will not be needed. Therefore one has to issue call to
indicate start saving information and another call to stop. Of course,
If you call ruby-debug from the outset via @code{rdebug} this is done
for you.
@table @code
@item Debugger.start(@ovar{options}) @ovar{block}
@vindex @code{Debugger.start(options)}
@vindex @code{Debugger.start(block)}
Turn on add additional instrumentation code to facilitate debugging. A
system even table hook is installed and some variables are set up to
access thread frames.
This needs to be done before entering the debugger; therefore a call
to the debugger issue a @code{Debugger.start} call if necessary.
If called without a block, @code{Debugger.start} returns @code{true} if
the debugger was already started. But if you want to know if the
debugger has already been started @code{Debugger.started?} can tell
you.
If a block is given, the debugger is started and @code{yields} to
block. When the block is finished executing, the debugger stopped with
the @code{Debugger.stop method}. You will probably want to put a call
to @code{debugger} somwhere inside that block
But if you want to completely stop debugger, you must call
@code{Debugger.stop} as many times as you called Debugger.start
method.
The first time Debugger.start is called there is also some additional
setup to make the @code{restart} command work. In particular, @code{$0} and
@code{ARGV} are used to set internal debugger variables.
Therefore you should make try to make sure that when
@code{Debugger.start} is called neither of these variables has been
modified. If instead you don't want this behavior you can pass an
options has and set the @code{:init} key to @code{false}. That is
@smallexample
Debugger.start(:init => false) # or Debugger.start(@{:init => false@})
@end smallexample
If you want post-mortem debugging, you can also supply
@code{:post_mortem => true} in @code{Debugger.start}.
@item Debugger.started?
@vindex @code{Debugger.started?}
Boolean. Return @code{true} if debugger has been started.
@item Debugger.stop
@vindex @code{Debugger.stop}
Turn off instrumentation to allow debugging. Return @code{true} is returned
if the debugger is disabled, otherwise it returns @code{false}.
@emph{Note that if you want to stop debugger, you must call Debugger.stop
as many times as you called the @code{Debugger.start} method.}
@item Debugger.run_script(@var{debugger-command-file}, out = handler.interface)
@vindex @code{Debugger.run_script}
Reads/runs the given file containing debugger commands. @code{.rdebugrc} is run this way.
@item Debugger.last_exception
@vindex @code{Debugger.last_exception}
If not @code{nil}, this contains @code{$!} from the last exception.
@end table
@node Debugger.context
@subsection @code{Debugger.context}
As mentioned previously, @code{Debugger.start} instruments additional
information to be obtained about the current block/frame stack. Here
we describe these additional @code{Debugger.context} methods.
Were a frame position is indicated, it is optional. The top or current frame
position (position zero) is used if none is given.
@table @code
@item Debugger.context.frame_args @ovar{frame-position=0}
@vindex @code{Debugger.context.frame_args}
If track_frame_args? is true, return information saved about call
arguments (if any saved) for the given frame position.
@item Debugger.context.frame_args_info @ovar{frame-position=0}
@vindex @code{Debugger.context.frame_args_info}
@item Debugger.context.frame_class @ovar{frame-position=0}
@vindex @code{Debugger.context.frame_args_info}
Return the class of the current frame stack.
@item Debugger.context.frame_file @ovar{frame-position=0}
@vindex @code{Debugger.context.frame_file}
Return the filename of the location of the indicated frame position.
@item Debugger.context.frame_id @ovar{frame-position=0}
@vindex @code{Debugger.context.frame_id}
Same as @code{Debugger.context.method}.
@item Debugger.context.frame_line @ovar{frame-position=0}
@vindex @code{Debugger.context.frame_line}
Return the filename of the location of the indicated frame position.
@item Debugger.context.frame_method @ovar{frame-position=0}
@vindex @code{Debugger.context.frame_method}
Symbol of the method name of the indicated frame position.
@item Debugger.context.stack_size
@vindex @code{Debugger.context.stack_size}
Return the number the size of the frame stack. Note this may be less
that the actual frame stack size if debugger recording
(@code{Debugger.start}) was turned on at after some blocks were added
and not finished when the @code{Debugger.start} was issued.
@end table
@node Debugger.settings
@subsection @code{Debugger.settings}
@vindex @code{Debugger.settings}
Symbols listed here are keys into the Array @code{Debugger.settings}.
These can be set any time after the @code{ruby-debug} is loaded. For example:
@smallexample
require "ruby-debug/debugger"
Debugger.settings[:autoeval] = true # try eval on unknown debugger commands
Debugger.listsize = 20 # Show 20 lines in a list command
@end smallexample
@table @code
@item :argv
Array of String. @code{argv[0]} is the debugged program name and
@code{argv[1..-1]} are the command arguments to it.
@item :autoeval
Boolean. True if auto autoeval on. @xref{Autoeval}.
@item :autoirb
Fixnum: 1 if on or 0 if off. @xref{Autoirb}.
@item :autolist
Fixnum: 1 if on or 0 if off.
@item :basename
Boolean. True if basename on. @xref{Basename}.
@item :callstyle
Symbol: @code{:short} or @code{:last}. @xref{Callstyle}.
@item :debuggertesting
Boolean. True if currently testing the debugger.
@item :force_stepping
Boolean. True if stepping should go to a line different from the last
step. @xref{Forcestep}.
@item :full_path
Boolean. @xref{Fullpath}.
@item :listsize
Fixnum. Number of lines to show in a @code{list} command. @xref{Listsize}.
@item :reload_source_on_change
Boolean. True if we should reread the source every time it changes. @xref{Autoreload}.
@item :stack_trace_on_error
Boolean. True if we should produce a stack trace on error. @xref{Trace}.
@item :width
Fixnum. Number of characters the debugger thinks are in a line. @xref{Width}.
@end table
@node Debugger Class
@section The @code{Debugger} Class
@menu
* Debugger.Breakpoint:: Debugger::Breakpoint
* Debugger.Context:: Debugger::Context
* Debugger.Command:: Debugger::Command
@end menu
@table @code
@item add_breakpoint(file, line, expr)
@vindex @code{Debugger.add_breakpoint}
Adds a breakpoint in file @var{file}, at line @var{line}. If
@var{expr} is not nil, it is evaluated and a breakpoint takes effect
at the indicated position when that expression is true. You should
verify that @var{expr} is syntactically valid or a @code{SyntaxError}
exception, and unless your code handles this the debugged program may
terminate.
@item remove_breakpoint(bpnum)
@vindex @code{Debugger.remove_breakpoint}
When a breakpoint is added, it is assigned a number as a way to
uniquely identify it. (There can be more than one breakpoint on a
given line.) To remove a breakpoint, use @code{remove_breakpoint} with
breakpoint number @var{bpnum}.
@item breakpoints
@vindex @code{Debugger.breakpoints}
Return a list of the breakpoints that have been added but not removed.
@end table
@node Debugger.Breakpoint
@subsection The @code{Debugger::Breakpoint} Class
Breakpoint are objects in the @code{Debugger::Breakpoint} class.
@table @code
@item enabled?
@vindex @code{Debugger::Breakpoints.enabled?}
Returns whether breakpoint is enabled or not.
@item enabled=
@vindex @code{Debugger::Breakpoints.enabled=}
Sets whether breakpoint is enabled or not.
@item expr
@vindex @code{Debugger::Breakpoints.expr}
Expression which has to be true at the point where the breakpoint is
set before we stop.
@item expr=
@vindex @code{Debugger::Breakpoints.expr=}
@item hit_condition
@item hit_condition=
@vindex @code{Debugger::Breakpoints.condition}
@vindex @code{Debugger::Breakpoints.condition=}
@item hit_count
@vindex @code{Debugger::Breakpoints.hit_count}
Returns the hit count of the breakpoint.
@item hit_value
@vindex @code{Debugger::Breakpoints.hit_value}
Returns the hit value of the breakpoint.
@item hit_value=
@vindex @code{Debugger::Breakpoints.hit_value=}
Sets the hit value of the breakpoint.
@item id
@cindex @code{Debugger::Breakpoints.id}
A numeric name for the breakpoint which is used in listing breakpoints
and removing, enabling or disabling the breakpoint
@item pos
@vindex @code{Debugger::Breakpoints.pos=}
Returns the line number of this breakpoint.
@item pos=
@vindex @code{Debugger::Breakpoints.pos=}
Sets the line number of this breakpoint.
@item source
@vindex @code{Debugger::Breakpoints.source}
Returns the file name in which the breakpoint occurs.
@item source=
@vindex @code{Debugger::Breakpoints.source=}
Sets the file name in which the breakpoint occurs.
@end table
@node Debugger.Context
@subsection The @code{Debugger::Context} Class
Callbacks in @code{Debugger:Context} get called when a stopping point
or an event is reached. It has information about the suspended program
which enable a debugger to inspect the frame stack, evaluate variables
from the perspective of the debugged program, and contains information
about the place the debugged program is stopped.
@table @code
@item at_line(@var{file}, @var{line})
@vindex Debugger::Context::at_line(@var{file}, @var{line})
This routine is called when the debugger encounters a ``line'' event for
which it has been indicated we want to stop at, such as by hitting a
breakpoint or by some sort of stepping.
@item at_return(@var{file}, @var{line})
@vindex Debugger::Context::at_return(@var{file}, @var{line})
This routine is called when the debugger encounters a ``return'' event for
which it has been indicated we want to stop at, such as by hitting a
@code{finish} statement.
@item debug_load(@var{file}, @var{stop-initially})
@vindex Debugger::Context::debug_load(@var{file}, @var{stop-initially})
This method should be used to debug a file. If the file terminates
normally, @code{nil} is returned. If not a backtrace is returned.
The @var{stop-initially} parameter indicates whether the program
should stop after loading. If an explicit call to the debugger is in
the debugged program, you may want to set this @code{false}.
@end table
@node Debugger.Command
@subsection The @code{Debugger::Command} Class
Each command you run is in fact its own class. Should you want to extend
ruby-debug, it's pretty easy to do since after all ruby-debug is Ruby.
Each @code{Debugger#Command} class should have the a @code{regexp}
method. This method returns regular expression for command-line
strings that match your command. It's up to you to make sure this
regular expression doesn't conflict with another one. If it does, it's
undefined which one will get matched and run
In addition the instance needs these methods:
@table @code
@item execute
Code which gets run when you type a command (string) that matches the
commands regular expression.
@item help
A string which gets displayed when folks as for help on that command
@item help_command
A name used the help system uses to show what commands are available.
@end table
Here's a small example of a new command:
@smallexample
module Debugger
class MyCommand < Command
def regexp
/^\s*me$/ # Regexp that will match your command
end
def execute
puts "hi" # What you want to happen when your command runs
end
class << self
def help_command
'me' # String name of command
end
def help(cmd)
# Some sort of help text.
%@{This does whatever it is I want to do@}
end
end
end
@end smallexample
Now here's an example of how you can load/use it:
@smallexample
require 'rubygems'
require 'ruby-debug'
require '/tmp/mycmd.rb' # or wherever
Debugger.start
x=1
debugger
y=2
@end smallexample
And now an example of invoking it:
@smallexample
ruby /tmp/testit.rb:
/tmp/testit.rb:7
y=2
(rdb:1) help
ruby-debug help v0.10.3
Type 'help <command-name>' for help on a specific command
Available commands:
backtrace delete enable help method putl set trace
break disable eval info next quit show undisplay
catch display exit irb p reload source up
condition down finish list pp restart step var
continue edit frame me ps save thread where
^^ This is you
(rdb:1) help me
This does whatever it is I want to do
(rdb:1) me
hi
(rdb:1)
@end smallexample
@node Kernel routines
@section Additions to @code{Kernel}
@table @code
@item debugger @ovar{steps=1}
@vindex @code{Kernel::debugger}
Enters the debugger in the current thread after a stepping @var{steps} line-event steps.
Before entering the debugger startup script is read.
Setting @var{steps} to 0 will cause a break in the debugger subroutine
and not wait for eany line event to occur. This could be useful you
want to stop right after the last statement in some scope.
Consider this example:
@smallexample
$ cat scope-test.rb
require 'rubygems'
require 'ruby-debug' ; Debugger.start
1.times do
a = 1
debugger # implied steps=1
end
y = 1
$ scope-test.rb:8
y = 1
(rdb:1) p a
NameError Exception: undefined local variable or method `a' for main:Object
(rdb:1)
@end smallexample
The debugger will get at the line event which follows @samp{a=1}. This
is outside the @code{do} block scope where @var{a} is defined. If
instead you want to stop before leaving the @code{do} loop it is
possibly to stop right inside the @code{debugger}; call with 0 zero parameter:
@smallexample
$ cat scope-test.rb
require 'rubygems'
require 'ruby-debug' ; Debugger.start
1.times do
a = 1
debugger(0)
end
y = 1
$ scope-test.rb:8
../lib/ruby-debug-base.rb:175
Debugger.current_context.stop_frame = 0
(rdb:1) where
--> #0 Kernel.debugger(steps#Fixnum) at line ../lib/ruby-debug-base.rb:175
#1 at line scope-test.rb:6
#2 at line scope-test.rb:4
(rdb:1) up
#1 at line scope-test.rb:6
(rdb:1) p a
1
(rdb:1)
@end smallexample
As seen above you will have to position the frame up one to be back in
your debugged program rather than in the debugger.
@item breakpoint @ovar{steps=1}
@vindex @code{Kernel::breakpoint}
An alias for debugger.
@item binding_n @ovar{n=0}
@vindex @code{Kernel::binding_n}
Returns a @samp{binding()} for the @var{n}-th call frame. Note however
that you need to first call @samp{Debugger.start} before issuing this
call.
@end table
@node Using from GitHub
@appendix Building and Installing from the GitHub Repository
Here are Unix-centric instructions. If you have Microsoft Windows or
OSX some of the below may need adjusting.
@menu
* Prerequisites::
* Package Checkout::
* Trying Out::
* Running Regression Tests::
* Building the Documentation and Emacs files::
* Building for Microsoft Windows::
@end menu
@node Prerequisites
@section Prerequisites: To build the package you'll need at a minimum:
@itemize @bullet
@item
Ruby (of course). Currently only version 1.8.6 and above but not
version 1.9.@emph{x} work.
@item
Ruby development headers. This typically includes a file called @file{ruby.h}
@item
A C compiler like GNU C (@code{gcc})
@item
Rake
@item
Subversion (@code{svn}).
@end itemize
If you want to build the documentation and install Emacs files, you'll
also need:
@itemize @bullet
@item
a POSIX shell like bash
@item
autoconf
@item
automake
@item
GNU Make
@item
texinfo
@end itemize
@node Package Checkout
@section Basic Package Checkout and Installation
Check out the trunk of repository following the instructions at
@url{http://rubyforge.org/scm/?group_id=1900} For example on a Unixy system,
this may work:
@smallexample
mkdir ruby-debug
cd ruby-debug
svn checkout svn://rubyforge.org/var/svn/ruby-debug/trunk trunk
@end smallexample
In order to make the Ruby gems, @code{ruby-debug} and
@code{ruby-debug-base}, get yourself into the trunk directory after
the code has been checked out and run:
@smallexample
cd trunk # This is the same trunk checked out above.
rake package
@end smallexample
If all goes well you should have some gem files put in the directory
@code{pkg}. Use the gem command to install that.
@smallexample
sudo gem install ruby-debug-*.gem # See gem help for other possibilities
@end smallexample
If all goes well the rdebug script has been installed ruby-debug is
now ready to run. But if everything goes well you might want to run
the built-in regression tests to make sure everything is okay.
See step 3 below.
If the gem install didn't work,'t there may be a problem with your C
compiler or the Ruby headers are not installed.
@node Trying Out
@section Trying Out without Installing
You don't have to build a gem file to try out ruby debug. In fact when
developing new features for ruby-debug, developers often you want to
try it out @emph{before} installing. If you have a problem in the latter
part of step 1 you may want to try this approach since we go into a
little more detail as to what happens under the covers when you do the
gem install.
Run (from trunk)
@smallexample
rake lib
@end smallexample
This creates a Makefile and builds the ruby-debug shared library. (On
Unix the name is @code{ruby_debug.so}).
Once this is done you can run the debugger as you would rdebug using the
script @code{runner.sh}. For example (again from trunk)
@smallexample
./runner.sh ~/my-ruby-program.rb
@end smallexample
@node Running Regression Tests
@section Running the Regression Tests
We've put together some basic tests to make sure ruby-debug is doing
what we think it should do. To run these (from @code{trunk}):
@smallexample
rake test
@end smallexample
If you didn't build the ruby-debug shared library and skipped step 2,
don't worry @code{rake test} will do step 2 for you. You should see a
line that ends something like:
@smallexample
Finished in 2.767579 seconds.
12 tests, 35 assertions, 0 failures, 0 errors
@end smallexample
The number of seconds, tests, and assertions may be different from the
above. However you @emph{should} see exactly ``0 failures, 0 errors.''
@node Building the Documentation and Emacs files
@section Building the Documentation and Testing/Installing Emacs Files
Of course, I recommend you read the ruby-debug manual that comes with
the package. If you have the prerequisites described above, run this
once:
@smallexample
sh ./autogen.sh
@end smallexample
Then run:
@smallexample
./configure
make
make test # Runs Emacs regression tests
sudo make install # Or arrange to do this as root
@end smallexample
@node Building for Microsoft Windows
@section Building for Microsoft Windows
Microsoft Windows is ``special'' and building @code{ruby-debug-base}
on it requires extra care. A problem here seems to be that the
``One-click'' install is compiled using Microsoft Visual Studio C, version 6
which is not sold anymore and is rather old.
Instead I suggest building via mingw/msys.
@url{http://eigenclass.org/hiki.rb?cmd=view&p=cross+compiling+rcovrt&key=mingw}
has instructions on how to do. Some amendments to these instructions.
First, those instructions are a little GNU/Linux centric. If you are
using Ubuntu or Debian, then this should be the easiest to follow the
instructions. On Ubuntu or Debian there is a mingw3 Debian
package. Installing that will give you the cross compiler that is a
prerequisite. Alternatively if you are running MS Windows I notice
that cygwin also has a mingw package. Or possibly you could use MinGW
directly. For other OS's you might have to build a cross-compiler,
i.e. gcc which emits win32 code and can create a win32 DLL.
After you have a cross compiler you need to download the Ruby source
and basically build a ruby interpreter. The cross-compile.sh script
works although when I downloaded it, it had lots of blank space at the
beginning which will mess up the Unix magic interpretation. That is
remove the blanks in front of @code{#/bin/sh}.
On my system, this script fails in running @code{make ruby} because the
fake.rb that got created needed to have a small change:
@smallexample
ALT_SEPARATOR = "\"; \
@end smallexample
should be:
@smallexample
ALT_SEPARATOR = "\\"; \
@end smallexample
After fixing this, run @code{make ruby}. Also, I needed to run
@code{make rubyw}.
And then @code{make install} as indicated.
Once all of that's in place, the place you want be is in
@code{ruby-debug/trunk/ext/win32}, not @code{ruby-debug/ext}.
So let's say you've installed the cross-compiled install ruby in
@code{/usr/local/ruby-mingw32/}. Here then are the commands to build @code{ruby-debug-base-}@emph{xxx}@code{-mswin32.gem}:
@smallexample
cd .../ruby-debug/trunk/ext/win32
ruby -I /usr/local/ruby-mingw32/lib/ruby/1.8/i386-mingw32 ../extconf.rb
make # Not rake
cd ../.. # back in ruby-debug/trunk
rake win32_gem
@end smallexample
@node Class Module Index
@unnumbered Class, Module Method Index
@printindex vr
@node Command Index
@unnumbered Command Index
@printindex ky
@node General Index
@unnumbered General Index
@printindex cp
@tex
% I think something like @colophon should be in texinfo. In the
% meantime:
\long\def\colophon{\hbox to0pt{}\vfill
\centerline{The body of this manual is set in}
\centerline{\fontname\tenrm,}
\centerline{with headings in {\bf\fontname\tenbf}}
\centerline{and examples in {\tt\fontname\tentt}.}
\centerline{{\it\fontname\tenit\/},}
\centerline{{\bf\fontname\tenbf}, and}
\centerline{{\sl\fontname\tensl\/}}
\centerline{are used for emphasis.}\vfill}
\page\colophon
% Blame: doc@cygnus.com, 1991.
@end tex
@bye
Jump to Line
Something went wrong with that request. Please try again.