1 # bashdb.fns - Bourne-Again Shell Debugger functions
5 # Here after each statement in script being debugged.
6 # Handle single-step and breakpoints.
8 let _curline=$1-1 # no. of line that just ran
9 let "$_curline < 1" && let _curline=1
11 let "$_curline > $_firstline+$_BUFSIZ" && _readin $_curline
14 _msg "$PS4, line $_curline: ${_lines[$(($_curline-$_firstline+1))]}"
17 # if in step mode, decrement counter
18 let " $_steps >= 0" && let _steps="$_steps - 1"
20 # first check if line num or string brkpt. reached
21 if _at_linenumbp || _at_stringbp; then
22 _msg "Reached breakpoint at line $_curline"
23 _cmdloop # enter debugger
25 # if not, check whether break condition exists and is true
26 elif [ -n "$_brcond" ] && eval $_brcond; then
27 _msg "Break condition $_brcond true at line $_curline"
28 _cmdloop # enter debugger
30 # next, check if step mode and no. of steps is up
31 elif let "$_steps == 0"; then
32 _msg "Stopped at line $_curline"
33 _cmdloop # enter debugger
38 # Debugger command loop.
39 # Here at start of debugger session, when brkpt. reached, or after single-step.
43 # added support for default command (last one entered)
45 while read -e -p "bashdb> [$lastcmd $lastargs] " cmd args; do
46 if [ -z "$cmd" ]; then
54 # made commands to be debugger commands by default, no need for '*' prefix
57 bp ) _setbp $args ;; #set brkpt at line num or string
59 bc ) _setbc $args ;; # set break condition
61 cb ) _clearbp ;; # clear all brkpts.
63 g ) return ;; # start/resume execution
65 s ) let _steps=${args:-1}
66 return ;; # single-step N times(default 1)
68 x ) _xtrace ;; # toggle execution trace
70 pr ) _print $args ;; # print lines in file
72 \? | h | help ) _menu ;; # print command menu
74 hi ) history ;; # show command history
76 q ) _cleanup; exit ;; # quit
78 \! ) eval $args ;; # run shell command
80 * ) _msg "
\aInvalid command: $cmd" ; _menu ;;
86 # see if next line no. is a brkpt.
88 if [ -z "${_linebp}" ]; then
91 echo "${_curline}" | egrep "(${_linebp%\|})" >/dev/null 2>&1
96 # search string brkpts to see if next line in script matches.
100 if [ -z "$_stringbp" ]; then
103 l=${_lines[$_curline-$_firstline+1]}
104 echo "${l}" | egrep "*(${_stringbp%\|})*" >/dev/null 2>&1
109 # print message to stderr
115 # set brkpt(s) at given line numbers and/or strings
116 # by appending lines to brkpt file
121 [0-9]*) #number, set brkpt at that line
123 _linebp="${_linebp}$n|"
124 _msg "Breakpoint at line " $1
126 *) #string, set brkpt at next line w/string
127 _stringbp="${_stringbp}$@|"
128 _msg "Breakpoint at next line containing $@."
134 # list brkpts and break condition.
136 _msg "Breakpoints at lines:"
137 _msg "${_linebp//\|/ }"
138 _msg "Breakpoints at strings:"
139 _msg "${_stringbp//\|/ }"
140 _msg "Break on condition:"
145 # set or clear break condition
147 if [ -n "$@" ] ; then
149 _msg "Break when true: $_brcond"
152 _msg "Break condition cleared"
161 _msg "All breakpoints cleared"
165 # toggle execution trace feature
167 let _trace="! $_trace"
169 _msg "Execution trace \c"
170 let " $_trace" && _msg "on." || _msg "off."
177 # made commands to be debugger commands by default, no need for '*' prefix
179 _msg 'bashdb commands:
180 bp N set breakpoint at line N
181 bp string set breakpoint at next line containing "string"
182 bp list breakpoints and break condition
183 bc string set break condition to "string"
184 bc clear break condition
185 cb clear all breakpoints
186 g start/resume execution
187 s [N] execute N statements (default 1)
188 x toggle execution trace on/off (default on)
189 pr [start|.] [cnt] print "cnt" lines from line no. "start"
190 ?, h, help print this menu
191 hi show command history
194 ! cmd [args] execute command "cmd" with "args"
196 default: last command (in "[ ]" at the prompt)
198 Readline command line editing (emacs/vi mode) is available'
202 # erase temp files before exiting
204 rm $_dbgfile 2>/dev/null
208 # read $_BUFSIZ lines from $_guineapig into _lines array, starting from line $1
209 # save number of first line read in _firstline
214 SEDCMD="$_firstline,$(($_firstline+$_BUFSIZ))p"
216 sed -n "$SEDCMD" $_guineapig > /tmp/_script.$$
217 while read -r _lines[$_i]; do
219 done < /tmp/_script.$$
220 rm -f /tmp/_script.$$ 2>/dev/null
226 if [ -z "$1" ] || [ "$1" = . ]; then
234 SEDCMD="$_start,$(($_start+$_cnt))p"
236 pr -tn $_guineapig | sed -n "$SEDCMD"