This file describes the BASH debugger, the BASH symbolic debugger. This is the 4.0-0.3 Edition, 10 April 2009, for BASH. Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008, 2009 Rocky Bernstein
|
The purpose of a debugger such as the BASH debugger is to allow you to see what is going on “inside” a bash script while it executes. the BASH debugger can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:
Although you can use the BASH debugger to debug scripts written in BASH , it can also be used just as a front-end for learning more about programming in BASH . As an additional aid, the debugger can be used within the context of an existing script with its functions and variables that have already been initialized; fragments of the existing can be experimented with by entering them inside the debugger.
|
You can use this manual at your leisure to read all about the BASH debugger. However, a handful of commands are enough to get started using the debugger. This chapter illustrates those commands. Below we will debug a script that contains a function to compute the factorial of a number: fact(0) is 1 and fact(n) is n*fact(n-1).
The command invocation uses the option “-L .” Here we assume that
the
Position information consists of a filename and line number,
e.g.
The first debugger command we gave
-
, we listed a window of
lines
before
where we were executing. Because the window, 10
lines, is larger than the number of lines to the top of the file we
printed only 9 lines here. The next command,
Ooops... The variable n isn't initialized. (1) The first step command steps the script one instruction. It may seem odd that the line printed is exactly the same one as before. What has happened though is that we've “stepped” into the subshell needed to run `fact 0` ; we haven't however started running anything inside that subshell yet though.
To indicate that which piece of the multi-part line
To indicate that we are now nested in a subshell, notice that the command number, starting with 3, or the third command entered, now appears in parenthesis. Each subshell nesting adds a set of parenthesis.
The first
step
command steps the script one instruction; it
didn't advance the line number, 9, at all. That is because we were
stopping before the command substitution or backtick is to take
place. The second command we entered was just hitting the return key;
bashdb remembers that you entered
Next, we print the value of the variable n . Notice we need to add a preceding dollar simple to get the substitution or value of n. As we will see later, if the pe command were used this would not be necessary. We now modify the file to add an assignment to local variable n and restart.
This time we use the
Again we just use <RET> to repeat the last
We saw that we could step with a count into the function
fact(). However above took another approach: we set a stopping point or
“breakpoint” at line 5 to get us a little ways into the fact()
subroutine. Just before line 5 is to executed, we will get back into
the debugger. The
In addition to listing by line numbers, we can also list giving a
function name. Below, instead of setting a breakpoint at line 5 and
running “
When we stop at line 5 above, we have already run fact(0) and output
the correct results. The output from the program “fact 0 is: 1” is
intermixed with the debugger output. The
The last message in the output above ‘
Debugged program exited
normally.
’ is from the
BASH
debugger; it indicates script has finished
executing. We can end our bashdb session with the bashdb
Above we did our debugging session on the command line. If you are a GNU Emacs user, you can do your debugging inside that. Also there is a(nother) GUI interface called DDD that supports the BASH debugger.
|
One of the things I had found disappointing about the
default
Here's what I use:
Note that the string is in single quotes, not double quotes and there
is a newline in the string. By using single quotes, variables which
have a dollar in front of them in the string are expanded in the
current environment of the line that is about to be run rather than at
the time the variable
You might want to add this in your shell's start-up script, e.g.,
There is also facility inside the bash debugger showing position information when tracing a script. Here's a simple session.
An explanation of the output. The
level
is how many invocations
of
BASH
are in effect before the statement shown is
executed. The
subshell
is how many subshells you are nested
in. Subshells are used by command substitution—
Notice also that in contrast to
If what you want to do is trace the
entire
script as was done
above (and not stop in the debugger when the script is over), you can
get the same effect by using the
If you issue a break (e.g. send a
|
This chapter discusses how to start the BASH debugger, and how to get out of it. The essentials are:
There are also two front-ends available as well. One can also
enter the debugger inside emacs via the command
|
Note: it is important to use a debugger-enabled bash. You will get an error message if the debugger is run under a version of BASH that does not have debugging support. As mentioned above, one can enter the BASH debugger via Emacs or DDD. However you don't have to use either of these. And these still need a way on their own to get things started.
There are in fact two
other
ways to start the
BASH
debugger. The
first way is to pass the ‘
--debugger
’ option to bash with the
name of your script the scripts arguments following that, or with a
command string (
This calls a debugger initialization script. It works much like a BASH login profile which may set variables and define functions. But this shell profile is customized for debugging and as such arranges for itself to get called before each statement is executed. Although there are some problems at present in I/O redirection that the method described next doesn't have, it is expected that over time more features will be enabled in bash when the ‘ --debugger ’ option is in effect. By default, both debugging in Emacs via GUD ( Using the BASH debugger under Emacs ) and debugging via DDD work via this method.
The form ‘
bash --debugger -c ...
’ can be used to get into the
debugger without having to give a script name to debug. Sometimes you
may want to do this just to see how the debugger works: try some
debugger commands or maybe get online help. If you run
In order for the ‘
--debugger
’ option to work however, you must
have the debugger scripts installed in a place where the
BASH
debugger can find
them. For this reason, in developing the
BASH
debugger, I use a second
method more often; it doesn't require the bash debugger to be
installed. This method uses another script called
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
As with the first method,
There are two or three disadvantages however of running a debugger
this way. First
An option that you'll probably need to use if bashdb isn't installed but run out of the source code directory is ‘ -L ’ which specifies the directory that contains the debugger script files. You can further control how bashdb starts up by using command-line options. bashdb itself can remind you of the options available. Type
to display all available options and briefly describe their use.
When the bash debugger is invoked either by the
Options for the
|
bashdb
script
You can run the BASH debugger in various alternative modes—for example, in batch mode or quiet mode.
-h | --help
-V | --version
-A | --annodate
level
Add additional output which allows front-ends to track what's going on without having to poll for such vital information. The default annotation level is 0 (none). If you are running inside GNU Emacs using the Emacs code from this package, an annotation level 3 when set will allow for automatic tracking of frames and breakpoints. See section Annotation Level (‘ set annotate ’) .
-c | --command
cmd
-B | --basename
-n | --nx | --no-init
Do not execute commands found in any initialization files. Normally, BASH executes the commands in these files after all the command options and arguments have been processed. See section Command files .
-q | --quiet
“Quiet”. Do not print the introductory and copyright messages. These messages are also suppressed in batch mode.
-t | --terminal | --tty
tty
“Terminal output”. Set the file or terminal that you want debugger command output to go to. Note that the debugger output is independent of the debugged script output.
-x | --eval-command
-L | --library
directory
Set directory where debugger files reside to
directory
. The
default location is
-T | --tempdir
directory
|
An interrupt (often
C-c
) does not exit from the
BASH
debugger, but
rather terminates the action of any the
BASH
debugger command that is in
progress and returns to the
BASH
debugger command level. Inside a debugger
command interpreter, use
There way to terminate the debugger is to use the
|
Running a program from the debugger adds a bit of overhead and slows
down your program quite a bit. Addressing this better would mean some
serious changes to
BASH
internals, and judging from experience
in other languages there still the slowdown is still noticeable. If
you have a
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 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 aside from calling
|
In this section we'll show how to modify your script so that it enters the debugger when you send it a signal, and then we will show how you can call the debugger directly.
In either case, you'll need to modify the script to load some the
debugger code. The name of file to load is
Although I said that running under the debugger adds overhead which
slows down you program, the above command in of itself will
not
cause any slowdown. If possible, it's best to put this somewhere in
the main-line code rather than in a function or in a subshell. If it
is put in a function of subshell and you step outside of that,
some of the global variables set up in
Here's a complete example. In file ‘ debugit.sh ’
Now run:
Sent it an "interrupt" signal
And back to the running program:
The command
By default,
Here are some examples:
|
As we saw in the last section
Let's show an example of that. We'll even do it under a condition:
The debugger will be called on the 5th iteration of this loop, when
You can also supply the number of statements to skip and the options to
For example to stop at the next line and suppress the banner you could
use
|
You can also turn on and off line tracing. Here's an example
The
Again
|
|
After invoking the debugger you should be on the first stoppable line of your program to be debugged. At this point you can issue debugger commands to set breakpoints (see section Setting breakpoints ), or watchpoints (see section Setting watchpoints ), or start continue the execution of the program (see section Resuming Execution ).
restart
[
args
]
run
[
args
]
R
[
args
]
Use the
|
A command file for the BASH debugger is a file of lines that are the BASH debugger commands. Comments (lines starting with # ) 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. When you start the BASH debugger, it automatically executes commands from its init files , normally called ‘ .bashdbinit ’ (3) . During startup, the BASH debugger does the following:
The init file in your home directory can set options (such as ‘ set complaints ’) that affect subsequent processing of command line options and operands. Init files are not executed if you use the ‘ -x ’ option (see section bashdb script options ). On some configurations of the BASH debugger, the init file is known by a different name (these are typically environments where a specialized form of the BASH debugger may need to coexist with other forms, hence a different name for the specialized version's init file). These are the environments with special init file names:
You can also request the execution of a command file with the
source
filename
Execute the command file 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.
|
The arguments to your script can be specified by the arguments of the
set args
Specify the arguments to be used if your program is rerun. If
show args
Show the arguments to give your program when it is started.
|
By default, the script you run under the BASH debugger does input and output to the same terminal that BASH uses. Before running the script to be debugged, the debugger records the tty that was in effect. All of its output is then written to that. However you can change this when using the ‘ bashdb ’ script using the ‘ -t ’ option.
info terminal
Displays information recorded by the BASH debugger about the terminal modes your program is using.
Another way to specify where your script should do input and output is
with the
directs that processes started with subsequent
An explicit redirection in
When you use the
|
The BASH debugger and your program live in the same variable space so to speak. BASH does not have a notion of module scoping or lexical hiding (yet) as is found in modern programming langauges and in modern versions of the Korn shell. This then imposes some additional care and awareness.
Most of the variables and functions used inside the
BASH
debugger start
Note: there are some other variables that begin with just an
underscore (
A number of environment variables are also reserved for use; these
start with
Inside the debugger some variables may be redefined. In particular
In order to do its work The
BASH
debugger sets up a
|
You can abbreviate the long name of the
BASH
debugger command to the first
few letters of the command name, if that abbreviation is unambiguous;
and you can repeat the
|
A
BASH
debugger command is a single line of input. 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
A blank line as input to the BASH debugger (typing just <RET>) means to repeat the previous next or step command. Any text from a # to the end of the line is a comment; it does nothing. This is useful mainly in command files (see section Command files ).
|
Once inside the
BASH
debugger, you can always ask it for
information on its commands, using the command
help
h
You can use
help
command
With a command name as
In addition to
info
This command (abbreviated
|
quit
[
expression
]
quit
[
expression
[
subshell-levels
]
]
q
To exit the
BASH
debugger, use the
A simple
If you want only to terminate some number of subshells but not all of
them, you can give a count of the number of subshells to leave after
the return-code expression. To leave just one level of subshell
If the environment variable
kill
k
In situations where
|
One important use of a debugger is to stop your program before it terminates so that if your script might run into trouble, you can investigate and find out why. However should your script accidently continue to termination, the BASH debugger has arranged for it not to leave the debugger without your explicit instruction. That way, you can restart the program using the same command arguments.
Inside the
BASH
debugger, 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
|
A 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
A watchpoint is a special breakpoint that stops your script when the value of an expression changes. There is a different command to set watchpoints (see section Setting watchpoints ). But aside from that, you can manage a watchpoint like any other breakpoint: you delete enable, and disable both breakpoints and watchpoints using the same commands. You can arrange to have values from your program displayed automatically whenever BASH stops at a breakpoint. See section Automatic display . The BASH debugger 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 enabled or disabled ; if disabled, it has no effect on your script until you enable it again. Watchpoint numbers however are distinguished from breakpoint numbers by virtue of their being suffixed with the either an upper- or lower-case `W'. For example, to enable breakpoint entry 0 along with watchpoint entry 1 you would write ‘ enable 1 2w ’, the “2w” refers to the watchpoint; “2W” would work just as well.
|
Breakpoints are set with the
break
function
Set a breakpoint at entry to function function .
break
linenum
Set a breakpoint at line 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.
break
filename
:
linenum
Set a breakpoint at line linenum in source file filename ; filename has to be one of the files previously read in and has to be specified exactly as the name used when read in. For a list of read-in files, use the ‘ info files ’ command.
break … if
cond
Set a breakpoint with condition
cond
; evaluate the expression
cond
each time the breakpoint is reached, and stop only if the
value is nonzero—that is, if
cond
evaluates as true. The
expression is evaluated via the
Examples:
tbreak
args
Set a breakpoint enabled only for one stop.
args
are the
same as for the
info breakpoints
[
n
]
info break
[
n
]
info watchpoints
[
n
]
Print a table of all breakpoints, watchpoints set and not deleted, with the following columns for each breakpoint:
Breakpoint Numbers (‘
Num
’)
Enabled or Disabled (‘
Enb
’)
Enabled breakpoints are marked with ‘ 1 ’. ‘ 0 ’ marks breakpoints that are disabled (not enabled).
Count
The number of times that breakpoint or watchpoint has been hit.
File and Line (‘
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.
Condition
A condition (an arithmetic expression) which when true causes the breakpoint to take effect.
If a breakpoint is conditional,
Examples:
the BASH debugger allows you to set any number of breakpoints at the same place in your script. There is nothing silly or meaningless about this. When the breakpoints are conditional, this is even useful (see section Break conditions ).
|
You can use a watchpoint to stop execution whenever the value of an
expression changes, without having to predict a particular place where
this may happen. As with the
watch
var
Set a watchpoint for a variable. the BASH debugger will break when the value of var changes. In this command do not add a leading dollar symbol to var .
watche
expr
Set a watchpoint for an expression via the builtin “let” command.
the
BASH
debugger will break when
expr
is written into by the program
and its value changes. Not that this may not work for tracking
arbitrary string value changes. For that use
|
commands
[
bnum
]
…
command-list
…
end
Specify a list of commands for breakpoint number
bnum
. The commands
themselves appear on the following lines. Type a line containing just
To remove all commands from a breakpoint, type
With no
bnum
argument,
Pressing <RET> as a means of repeating the last debugger command is disabled within a command-list .
You can use breakpoint commands to start your program up again. Simply
use the
Any other commands in the command list, after a command that resumes
execution, are ignored. This is because any time you resume execution
(even with a simple
If the first command you specify in a command list is
The commands
For example, here is how you could use breakpoint commands to print the
value of
One application for breakpoint commands is to compensate for one bug so
you can test for another. Put a breakpoint just after the erroneous
line
of code, give it a condition to detect the case in which something
erroneous has been done, and give it commands to assign correct values
to any variables that need them. End with the
|
It may desirable to eliminate a breakpoint or watchpoint once it has done its job and you no longer want your script to stop there. This is called deleting the breakpoint. A breakpoint that has been deleted no longer exists; it is forgotten.
With the
It is not necessary to delete a breakpoint to proceed past it. the BASH debugger automatically ignores breakpoints on the first instruction to be executed when you continue execution.
clear
Delete any breakpoints at the next instruction to be executed in the selected stack frame (see section Selecting a frame ). When the innermost frame is selected, this is a good way to delete a breakpoint where your script just stopped. It may seem odd that we have an alias “d” for “clear.” It so happens that Perl's debugger use “d” for its delete command and the delete concept in Perl's debugger corresponds to “clear” in GDB. (Perl doesn't have a notion of breakpoint entry numbers). So in order to be compatible with both debugger interfaces, “d” is used as an alias for “clear.” Clear?
clear
function
clear
filename
:
function
Delete any breakpoints set at entry to the function function .
clear
linenum
d
linenum
delete
[
breakpoints
]
Delete the breakpoints, watchpoints specified as arguments.
If no argument is specified, delete all breakpoints (the
BASH
debugger asks
confirmation, unless you have
Note that for compatibility with Perl's debugger,
|
Rather than deleting a breakpoint or watchpoint, you might prefer to disable it. This makes the breakpoint inoperative as if it had been deleted, but remembers the information on the breakpoint so that you can enable it again later.
You disable and enable breakpoints, watchpoints, and catchpoints with
the
A breakpoint, watchpoint, or catchpoint can have any of four different states of enablement:
You can use the following commands to enable or disable breakpoints, watchpoints, and catchpoints:
disable
[
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
enable
[
breakpoints
]
Enable the specified breakpoints (or all defined breakpoints). They become effective once again in stopping your program.
Except for a breakpoint set with
|
The simplest sort of breakpoint breaks every time your script reaches a specified place. You can also specify a condition for a breakpoint. A condition is just a BASH expression.
Break conditions can be specified when a breakpoint is set, by using
‘
if
’ in the arguments to the
There is also a notion of a “one-time” breakpoint which gets deleted as soon as it is hit, so that that breakpoint is executed once only. Conditions are also accepted for watchpoints; you may not need them, since a watchpoint is inspecting the value of an expression anyhow—but it might be simpler, say, to just set a watchpoint on a variable name, and specify a condition that tests whether the new value is an interesting one.
condition
bnum
expression
Specify expression as the break condition for breakpoint bnum . After you set a condition, breakpoint bnum stops your program only if the value of expression is true (nonzero).
condition
bnum
Remove the condition from breakpoint number bnum . It becomes an ordinary unconditional breakpoint.
BASH
does
not actually evaluate
expression
at the time the
Examples;
|
A typical technique for using stepping is to set a breakpoint (see section Breakpoints; watchpoints ) 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. Continuing means resuming program execution until your script completes normally. In contrast, 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.
|
step
[
+|-
]
[
count
]
Continue running your script until control reaches a different source
line, then stop it and return control to the
BASH
debugger. An default
alias alias for this is
The
Sometimes you want to step ensure that the next line is different from
the one you currently are on. To do this, add the
With a count, continue running as in
|
next
[
count
]
Continue to the next source line in the current (innermost) stack frame.
This is similar to
An argument
count
is a repeat count, as for
|
finish
Continue running until just after function returns.
Currently,
the line shown on a return is the function header, unless the
Contrast this with the
|
skip
[
count
]
Skip execution of the next source line.
This may be useful if you have an action that “fixes” existing code in
the script. The
|
continue
[
- | line-specification
]
c
[
line-specification
]
Resume program execution, at the address where your script last stopped; any breakpoints set at that address are bypassed. The optional argument line-specification allows you to specify a location (a line number, function, or filename linenumber combination) to set a one-time breakpoint which is deleted when that breakpoint is reached. Should the program stop before that breakpoint is reached, in a listing of the breakpoints you will see this entry with the condition 9999 which indicates a one-time breakpoint.
If instead of a line specification you enter
To resume execution at a different place, you can use
|
debug
[
script-name
]
Debug into script-name . If no name is given the current source line is used. In either case the options are prepended to cause the debugger to run.
The nesting level of the debugger is saved inside environment variable
|
return
You can cancel execution of a function call or a subshell with the
The
In contrast, the
|
A signal is an asynchronous event that can happen in a program. The
operating system defines the possible kinds of signals, and gives each
kind a name and a number. For example, in Unix
Some signal handlers are installed and changed for the
BASH
debugger's
normal use:
Signal handlers that the debugged script might have installed are
saved and called before the corresponding debugger handler. Thus, the
debugged program should work roughly in the same fashion as when it is
not debugged. However there are some call-stack variables which
inevitably will differ. To try to hedge this a little so the behaviour
is the same, the
BASH
debugger will modify arguments to the traps if it
finds one of the call-stack that change as a result of the debugger
being in place. In particluar
The debugger also installs an interrupt handler
Some signals, including
BASH has the ability to detect any occurrence of a signal in your program. You can tell BASH in advance what to do for each kind of signal.
Normally,
BASH
is set up to let the non-erroneous signals like
|
handle
signal
keywords
…
Change the way BASH handles signal signal . signal can be the number of a signal or its name (with or without the ‘ SIG ’ at the beginning). The keywords say what change to make.
info signals
info handle
Print a table of all the kinds of signals and how BASH has been told to handle each one. You can use this to see the signal numbers of all the defined types of signals.
The keywords allowed by the
stop
BASH
should stop your program when this signal happens. This implies
the
nostop
BASH should not stop your program when this signal happens. It may still print a message telling you that the signal has come in.
print
BASH should print a message when this signal happens.
noprint
BASH should not mention the occurrence of the signal at all.
stack
BASH should print a stack trace when this signal happens.
nostack
BASH should not print a stack trace when this signal occurs.
|
signal
signal-name
|
signal-number
You can use the
|
In addition to
|
This
info args
info breakpoints
info display
info files
info functions
info line
info program
info signals
info source
info stack
info terminal
info variables
All global and static variable names
|
In contrast to
The distinction between
Here are three miscellaneous
show version
Show what version of BASH is running. You should include this information in BASH bug-reports. If multiple versions of BASH are in use at your site, you may need to determine which version of BASH you are running; as BASH evolves, new commands are introduced, and old ones may wither away. Also, many system vendors ship variant versions of BASH , and there are variant versions of BASH in GNU /Linux distributions as well. The version number is the same as the one announced when you start BASH .
show copying
Display information about permission for copying BASH .
show linetrace
Show if line tracing is enabled. See also Show position information as statements are executed (‘ set linetrace ’) .
show logging
Show summary information of logging variables which can be set via
show logging file
Show the current logging file.
show logging overwrite
show warranty
Display the GNU “NO WARRANTY” statement, or a warranty, if your version of the BASH debugger comes with one.
|
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. Each time your script performs a function call (either as part of a command substitution or not), or `source's a file, information about this action is saved. The call stack then is this a history of the calls that got you to the point that you are currently stopped at. One of the stack frames is selected by the BASH debugger and many the BASH debugger commands refer implicitly to the selected frame. In particular, whenever you ask the BASH debugger to list lines without giving a line number or location the value is found in the selected frame. There are special the BASH debugger commands to select whichever frame you are interested in. See section Selecting a frame .
When your program stops,
BASH
automatically selects the
currently executing frame and describes it briefly, similar to the
|
The call stack is divided up into contiguous pieces called stack frames , or frames for short; each frame is the data associated with one call to one function. The frame contains the line number of the caller of the function, the source-file name that the line refers to a function name (which could be the built-in name “source”)..
When your script is started, the stack has only one frame, that of the
function
the BASH debugger 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 the BASH debugger to give you a way of designating stack frames in the BASH debugger commands.
|
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 sare stopped at (frame zero), followed by its caller (frame one), and on up the stack.
backtrace
bt
where
T
Print a backtrace of the entire stack: one line per frame for all frames in the stack.
backtrace
n
bt
n
where
n
T
n
Similar, but print only the innermost n frames.
The names
Each line in the backtrace shows the frame number and the function name, the source file name and line number, as well as the function name. Here is an example of a backtrace taken a program in the regression-tests ‘ parm.sh ’.
The display for “frame” zero isn't a frame at all, although it has
the same information minus a function name; it just indicates that
your script has stopped at the code for line
|
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.
up
[
n
]
Move
n
frames up the stack. For positive numbers
n
, this
advances toward the outermost frame, to higher frame numbers, to
frames that have existed longer. Using a negative
n
is the same
as issuing a
n
defaults to one. You may appreviate
down
[
n
]
Move
n
frames down the stack. For positive numbers
n
, this
advances toward the innermost frame, to lower frame numbers, to frames
that were created more recently. Using a negative
n
is the same
as issuing a
n
defaults to one. You may abbreviate
All of these commands end by printing two lines of output describing the frame. The first line shows the frame number, the function name, the arguments, and the source file and line number of execution in that frame. The second line shows the text of that source line. For example:
After such a printout, the
frame
args
The
If a negative number is given, counting is from the other end of the
stack frame, so
Without an argument,
|
the BASH debugger can print parts of your script's source. When your script stops, the BASH debugger spontaneously prints the line where it stopped. Likewise, when you select a stack frame (see section Selecting a frame ), the BASH debugger prints the line where execution in that frame has stopped. You can print other portions of source files by explicit command. If you use the BASH debugger through its GNU Emacs interface, you may prefer to use Emacs facilities to view source; see Using the BASH debugger under GNU Emacs .
To print lines from a source file, use the
Here are the forms of the
list
linenum
l
linenum
Print lines centered around line number linenum in the current source file.
list
function
l
function
Print the text of function .
list
l
Print more lines. If the last lines printed were printed with a
list -
l -
Print lines just before the lines last printed.
By default, the
BASH
debugger prints ten source lines with any of these forms of
the
set listsize
count
Make the
show listsize
Display the number of lines that
Repeating a
In general, the
Here is a complete description of the possible arguments for
list
linespec
Print lines centered around the line specified by linespec .
list
first
increment
Print increment lines starting from first
list
first
Print lines starting with first .
list -
Print lines just before the lines last printed.
list .
Print lines after where the script is stopped.
list
As described in the preceding table. Here are the ways of specifying a single source line—all the kinds of linespec.
number
Specifies line
number
of the current source file.
When a
filename
:
number
Specifies line number in the source file filename .
function
Specifies the line that function function is listed on.
|
To edit the lines in a source file, use the
You can customize to use any editor you want by using the
The optional numeric value +
number
specifies the number of the
line in the file where to start editing. For example, to configure
the
BASH
debugger to use the
or in the
edit
[
line specification
]
Edit line specification using the editor specified by the
|
There are two commands for searching through the current source file for a BASH extended pattern-matching expression.
forward
bash-pattern
search
bash-pattern
The command ‘
forward
bash-pattern
’ checks each line,
starting with the one following the current line, for a match for
bash-pattern
which is an extended bash pattern-matching
expression. It lists the line that is found. You can use the synonym
‘
search
bash-pattern
’ or abbreviate the command name as
reverse
bash-pattern
The command ‘
reverse
bash-pattern
’ checks each line, starting
with the one before the last line listed and going backward, for a match
for
bash-pattern
. It lists the line that is found. You can abbreviate
this command as
|
One way to examine string data in your script is with the
print
expr
Use
print
p
If you omit expr , the BASH debugger displays the last expression again.
x
variable1
[
variable2...
]
x
expr
This is a smarter, more versatile “print” command, and although
sometimes
it might not be what you want, and you may want to resort to either
As with
The
If instead
expr
is a function, the function definition is
printed via
BASH
's
Since
V
[
!
]
[
pattern
]
If you want to all list variables and values or a set of variables by pattern, use this command.
|
The two most general commands and most “low-level” are
eval
e
In contrast to the commands of the last section the most general way
to examine data is through
If you expect output, you should arrange that in the command, such as
via
shell
command string
!!
If you need to execute occasional shell commands during your
debugging session, there is no need to leave or suspend the
BASH
debugger; you can
just use the
Invoke a shell to execute command string .
|
cd
Set working directory to
directory
for debugger and program
being debugged. Tilde expansion, variable and filename expansion is
performed on
directory
. If no directory is given, we print out the
current directory which is really the same things as running
Note that
pwd
Prints the working directory as the program sees things.
|
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 automatic display list so that the BASH debugger evaluates a statement each time your program stops. 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:
This display shows item numbers, expressions and their current values.
display
expr
Add the expression expr to the list of expressions to display each time your program stops.
display
undisplay
dnums
…
delete display
dnums
…
Remove item numbers dnums from the list of expressions to display.
disable display
dnums
…
Disable the display of item numbers dnums . A disabled display item is not printed automatically, but is not forgotten. It may be enabled again later.
enable display
dnums
…
Enable display of item numbers dnums . It becomes effective once again in auto display of its expression, until you specify otherwise.
info display
Print the list of expressions previously set up to display automatically, each one with its item number, but without showing the values. This includes disabled expressions, which are marked as such. It also includes expressions which would not be displayed right now because they refer to automatic variables not currently available.
|
alias
name
command
unalias
name
command
|
set annotate
integer
The annotation level controls how much information the BASH debugger prints in its prompt; right new it just controls whether we show full filenames in output or the base part of the filename without path information. Level 0 is the normal, level 1 is for use when the BASH debugger is run as a subprocess of GNU Emacs of DDD , level 2 is the maximum annotation suitable for programs that control the BASH debugger.
|
set autoeval
[
on | 1 | off | 0
]
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
first
check input to see if it
is a debugger command and
only
if it is not do we consider it
as Ruby code. This means for example that if you have variable called
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
show args
Shows whether Ruby evaluation of debugger input should occur or not.
|
set basename
[
on | 1
]
When set on, 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.
set basename
[
off | 0
]
Source filenames are shown as with their full path. This is the default.
|
set debugger
[
on | 1
]
Allow the possibility of debugging this debugger. Somewhat of an arcane thing to do. For gurus, and even he doesn't use it all that much.
set debugger
[
off | 0
]
Don't allow debugging into the debugger. This is the default.
|
Sometimes the
BASH
debugger gets confused about where to find the script
source file for the name reported to it by bash. To resolve relative
file names that bash supplies via
However somethimes this doesn't work and there is a way to override this.
file
script-file
Directs the
BASH
debugger to use
script-file
whenever bash would have
it refers to the filename given in
|
BASH
has “
The status of whether line tracing is enabled can be show via
set linetrace
[
on | 1
]
Turn on line tracing.
set linetrace
[
off | 0
]
Turn off line tracing.
|
You may want to save the output of the debugger commands to a file. There are several commands to control the debuggers's logging.
set logging
set logging
[
on | 1
]
Enable or Disable logging.
set logging file
filename
Change the name of the current logfile. The default logfile is ‘ bashdb.txt ’.
set logging overwrite
[
on | 1
]
By default, the debugger will append to the logfile. Set
set logging redirect
[
on | 1
]
By default, the debugger output will go to both the terminal and the
logfile. Set
show logging
Show the current values of the logging settings.
|
The BASH debugger indicates its readiness to read a command by printing a string called the prompt . This string is normally:
When variables inside the the prompt string are evaluated, the above becomes something like ‘ bashdb<5> ’ if this is the fifth command executed or perhaps ‘ bashdb<<2>> ’ if you have called the debugger from inside a debugger session and this is the second command inside the debugger session or perhaps ‘ bashdb<(6)> ’ if you entered a subshell after the fifth command.
You can change the prompt string with the
Note:
set prompt
newprompt
Directs the BASH debugger to use newprompt as its prompt string henceforth. Warning: changing the prompt can DDD 's ability to understand when the debugger is waiting for input.
show prompt
Prints a line of the form: ‘ bashdb's prompt is: your-prompt ’
|
the
BASH
debugger reads its input commands through bash which uses via the
readline
interface. This
GNU
library provides consistent
behavior for programs which provide a command line interface to the
user. Advantages are
GNU
Emacs-style or
vi
-style inline
editing of commands,
You may control the behavior of command line editing in
BASH
with the
command
set editing
set editing
[
on | 1
]
Enable command line editing (enabled by default).
set editing
[
off | 0
]
show editing
Show whether command line editing is enabled.
|
If you need to debug user-defined commands or sourced files you may find it useful to enable command tracing . In this mode each command will be printed as it is executed, prefixed with one or more ‘ + ’ symbols, the quantity denoting the call depth of each command.
set trace-commands on
Enable command tracing.
set trace-commands off
Disable command tracing.
show trace-commands
Display the current state of command tracing.
|
The debugger normally lists the line number and source line of the for the statement to be next executed. Often this line contains one expression or one statement and it is clear from this line what's going to happen. However BASH allows many expressions or statements to be put on a single source line; some lines contain several units of execution. Some examples of this behavior are listed below:
In the first line of the example above, we have three assignment statements on a single line. In the second line of the example above we have a statement which gets run only if a condition tests true. And in the third line of the example above, we have a command that gets run and then the output of that is substituted in an assignemnt statement. If you were single stepping inside the debugger, each line might get listed more than once before each of the actions that might get performed. (In the case of the conditional statement, the line gets listed only once when the condition is false.)
In order to assist understanding where you are, the enhanced version
of
BASH
maintains a dynamic variable
set showcommand
[
auto | on | 1 | off | 0
]
controls whether or not to show the saved
When the value is
Some examples:
|
The BASH debugger can keep track of the commands you type during your debugging sessions, so that you can be certain of precisely what happened. If the prompt has not been changed (see Prompt ), the history number that will be in use next is by default listed in the debugger prompt. Invalid commands and history commands are not saved on the history stack.
H
[
start-number
[
end-number
]
]
H
[
-count
]
!
[
-
]
n
:p
You can list what is in the history stack with
An alternate form is
Some examples:
history
[
[
-
]
n
]
!
[
-
]
n
Use this command to reexecute a given history number. If no number is given, the last debugger command in the history is executed.
An alternate form is
If a minus sign is used in in either form, n is taken as the count to go back from the end rather than as a absolute history number. Use these commands to manage the the BASH debugger command history facility.
set history save
set history save
[
on | 1
]
Record command history in a file, whose name may be specified with the
set history save
[
off | 0
]
set history size
size
Set the number of commands which
BASH
keeps in its history list.
This defaults to the value of the environment variable
show history
show history save
show history size
These commands display the state of the
BASH
history parameters.
show commands
Display the last ten commands in the command history.
show commands
n
Print ten commands centered on command number n .
show commands +
Print ten commands just after the commands last printed.
|
The
results in:
And
results in:
This is intended for use by front-ends such as GNU Emacs and DDD .
|
There are some front-ends that can use the BASH debugger as a back-end debugger.
|
A special interface allows you to use
GNU
Emacs to view (and
edit) the source files for the program you are debugging with
the
BASH
debugger. However you must be using
GNU
Emacs version 21 or
greater. (
To use this interface, use the command M-x bashdb in GNU Emacs. Give the executable file you want to debug as an argument. Make sure to use the version that comes with this package as this is newer than that supplied with GNU Emacs. The bashdb command starts the BASH debugger as a subprocess of Emacs, with input and output through a newly created Emacs buffer. Using the BASH debugger under Emacs is just like using the BASH debugger normally except for two things:
This applies both to the BASH debugger commands and their output, and to the input and output done by the program you are debugging. This is useful because it means that you can copy the text of previous commands and input them again; you can even use parts of the output in this way. All the facilities of GNU Emacs' Shell mode are available for interacting with your script. In particular, you can send signals the usual way—for example, C-c C-c for an interrupt, C-c C-z for a stop.
|
Each time the BASH debugger displays a stack frame, Emacs automatically finds the source file for that frame and puts an arrow (‘ => ’) at the left margin of the current line. Emacs uses a separate buffer for source display, and splits the screen to show both your the BASH debugger session and the source.
Explicit the
BASH
debugger
By default,
M-x bashdb
calls the
(preceded by
M-:
or
ESC :
, or typed in the
In the the
BASH
debugger I/O buffer, you can use the Emacs commands listed
below in addition to the standard Shell mode commands. The I/O buffer
name name is usually
Many of the commands listed below are also bound to a second key sequence which also can be used in the also be used in the source script. These are listed in Commands from the source script .
C-h m
Describe the features of Emacs' the BASH debugger Mode.
C-c C-f
Execute until exit from the selected stack frame. The Same as the
BASH
debugger
C-c C-l
Resynchronize the current position with the source window. The
GNU
Emacs command name is
C-c C-n
Execute to next source line in this function, skipping all function
calls. Same as the
BASH
debugger
With a numeric argument, run that many times. See (Emacs)Arguments section `Numeric Arguments' in The GNU Emacs Manual .
C-c C-r
Continue execution of your script Same as the
BASH
debugger
C-c C-s
Step one source line. Same as the
BASH
debugger
With a numeric argument, run that many times. See (Emacs)Arguments section `Numeric Arguments' in The GNU Emacs Manual .
C-c >
Go down a stack frame. Same as the
BASH
debugger
The
GNU
Emacs command name is
C-c <
Go up a stack frame. With a numeric argument, go up that many
stack frames. Same the
BASH
debugger
The
GNU
Emacs command name is
C-c a
Shows argument variables (e.g.
C-c R
Restart or run the script. Same as the
BASH
debugger
C-c T
Show stack trace. Same as the
BASH
debugger
In any source file, the Emacs command
C-x SPC
(
If you accidentally delete the source-display buffer, an easy way to get
it back is to type the command
The source files displayed in Emacs are in ordinary Emacs buffers which are visiting the source files in the usual way. You can edit the files with these buffers if you wish; but keep in mind that the BASH debugger communicates with Emacs in terms of line numbers. If you add or delete lines from the text, the line numbers that the BASH debugger knows cease to correspond properly with the code. See (Emacs)Debugger Operation section `Debugger Operation' in The GNU Emacs Manual .
|
C-x SPC
tells the
BASH
debugger to set a breakpoint on the source
line point is on. (
C-x C-a t
C-x C-a C-f
Restart or run the script. Same as the
BASH
debugger
C-x C-a T
Show stack trace. Same as the
BASH
debugger
C-x C-a <
Go up a stack frame. With a numeric argument, go up that many
stack frames. Same the
BASH
debugger
The
GNU
Emacs command name is
C-x C-a >
Go down a stack frame. Same as the
BASH
debugger
The
GNU
Emacs command name is
C-x C-a C-t
C-x C-a C-s
Step one source line. Same as the
BASH
debugger
With a numeric argument, run that many times. See (Emacs)Arguments section `Numeric Arguments' in The GNU Emacs Manual .
The
GNU
Emacs command name is
C-x C-a C-e
C-x C-a R
Restart or run the script. Same as the
BASH
debugger
C-x C-a C-d
Delete breakpoint.
C-x C-a C-p
C-x C-a C-n
Execute to next source line in this function, skipping all function
calls. Same as the
BASH
debugger
The
GNU
Emacs command name is
C-x C-a f C-f
C-x C-a C-r
Continue execution of your script Same as the
BASH
debugger
C-x C-a C-b
C-x C-a a
C-x C-a C-l
Move to current position in this source window. The
GNU
Emacs
command name is
|
It is also possible in GNU emacs to use a regular (“comint”) shell and set a mode to watch for the BASH debugger prompts. See (Emacs)Interactive Shell section `Shell' in The GNU Emacs Manual .
To run bash in a shell in Emacs but track source lines this, issue the
the command (from M-x)
|
the BASH debugger support is rather new in DDD . As a programming language, the BASH debugger is not feature rich: there are no record structures or hash tables (yet), no pointers, package variable scoping or methods. So much of the data display and visualization features of DDD are disabled. As with any scripting or interpreted language (e.g. Perl), one can't step by a single machine-language instruction. So the ddd Stepi/Nexti commands are disabled. Some BASH settings are essential for DDD to work correctly. These settings with their correct values are:
DDD sets these values automatically when invoking BASH ; if these values are changed, there may be some malfunctions. Pay special attention when the prompt has extra angle brackets (a nested shell) or has any parenthesis (is in a subshell). Quitting may merely exit out of one of these nested (sub)shells rather than leave the program.
|
Your bug reports play an essential role in making the BASH debugger reliable. Reporting a bug may help you by bringing a solution to your problem, or it may not. But in any case the principal function of a bug report is to help the entire community by making the next version of the BASH debugger work better. Bug reports are your contribution to the maintenance of the BASH debugger. In order for a bug report to serve its purpose, you must include the information that enables us to fix the bug.
|
If you are not sure whether you have found a bug, here are some guidelines:
|
Bug reports can sent via the sourceforge bug tracking mechansim at http://sourceforge.net/tracker/?group_id=61395&atid=497159 . Of course patches are very much welcome too. Those can also be sent via the same mechanism. The fundamental principle of reporting bugs usefully is this: report all the facts . If you are not sure whether to state a fact or leave it out, state it! Often people omit facts because they think they know what causes the problem and assume that some details do not matter. Thus, you might assume that the name of the variable you use in an example does not matter. Well, probably it does not, but one cannot be sure. Perhaps the bug is a stray memory reference which happens to fetch from the location where that name is stored in memory; perhaps, if the name were different, the contents of that location would fool the debugger into doing the right thing despite the bug. Play it safe and give a specific, complete example. That is the easiest thing for you to do, and the most helpful. Keep in mind that the purpose of a bug report is to enable us to fix the bug. It may be that the bug has been reported previously, but neither you nor we can know that unless your bug report is complete and self-contained. Sometimes people give a few sketchy facts and ask, “Does this ring a bell?” Those bug reports are useless, and we urge everyone to refuse to respond to them except to chide the sender to report bugs properly. To enable us to fix the bug, you should include all these things:
Here are some things that are not necessary:
|
The suggestion for a debugger for a Bourne-like shell came from the book “Learning the Korn Shell”, by Bill Rosenblatt Copyright (C) 1993 by O'Reilly and Associates, Inc. Others such as Cigy Cyriac, Chet Ramey, Rocky Bernstein, and Gary V. Vaughan expanded and improved on that.
However Bourne-Shell debuggers rely on a signal mechanism
(
Another failing of these debuggers was the inability to debug into functions or into sourced files, provide a stack trace, dynamically skip a statement to be run, unconditionally trace into a function or subshell, or stop when a subroutine, sourced file, or subshell completed. In truth, the crux of the problem lay in debugging support in BASH. Given that there was limited bash debugging support, it is not surprising that these debuggers could not do any of the things listed above and could debug only a single shell in a single source file: lines could be listed only from a single text, breakpoints were set into the text which was in fact a copy of the script name prepended with debugger routines.
In version 2.04 of BASH, Rocky Bernstein started hacking on BASH to
add call-stack information, source file information, allow for
debugging into functions and for reporting line numbers in functions
as relative to the file rather than the beginning of a function whose
origin line number was not accessible from BASH. He started changing
the user commands in bashdb to be like other more-advanced debuggers,
in particular
In version 2.05, the fundamental necessary change to the semantics of
This documentation was modified from the GNU Debugger (GDB) Reference manual.
The following have contributed directly or indrectly to bashdb: Rocky Bernstein (initial full-featured bashdb with stack tracing and multi-file support) Masatake YAMATO (help to merge Rocky's hack to the official bash source tree) Bill Rosenblatt (kshdb), Michael Loukides (kshdb), Cigy Cyriac (proto bashdb), Chet Ramey (proto bashdb), and Gary V. Vaughan (proto bashdb). Authors of per5ldb: Ray Lischner, Johan Vromans, and Ilya Zakharevich. Authors of GDB: Richard Stallman, Andrew Cagney, Jim Blandy, Jason Molenda, Stan Shebs, Fred Fish, Stu Grossman, John Gilmore, Jim Kingdon, and Randy Smith (to name just a few). Authors of GUD: Eric S. Raymond.
|
Version 2, June 1991
|
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software—to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
END OF TERMS AND CONDITIONS
|
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
The hypothetical commands ‘ show w ’ and ‘ show c ’ should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than ‘ show w ’ and ‘ show c ’; they could even be mouse-clicks or menu items—whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a “copyright disclaimer” for the program, if necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.
|
Version 1.1, March 2000
|
To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:
If you have no Invariant Sections, write “with no Invariant Sections” instead of saying which ones are invariant. If you have no Front-Cover Texts, write “no Front-Cover Texts” instead of “Front-Cover Texts being list ”; likewise for Back-Cover Texts. If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.
|
|
|
|
|
Recall that variables in BASH don't need to be declared before they are referred to and that the default value would be the a null value which here prints as an empty string. |
And in the interest of full disclosure, although
this was not shown in the example it is possible to add the
|
The DJGPP port of the BASH debugger uses the name ‘ bashdb.ini ’ instead, due to the limitations of file names imposed by DOS filesystems. |
On
DOS/Windows systems, the home directory is the one pointed to by the
|
|
This document was generated on April, 10 2009 using texi2html 1.78 . The buttons in the navigation panels have the following meaning:
where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:
This document was generated on
April, 10 2009
using
texi2html 1.78
.
|