Next: , Up: Calling from Program   [Contents][Index]


2.3.1 Debugging a Running Shell Script

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 bashdb-trace and it is located in the directory where the other bash debugger files live. For example on GNU/Linux if it is in directory /usr/local/share/bashdb, you would first add to a BASH script the line:

    source /usr/local/share/bashdb/bashdb-trace

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 bashdb-trace may be lost. One the other hand if you know your debugging will be confined to just the scope of the source command there is no problem.

Here’s a complete example. In file debugit.sh

# This is my extra debug hook
  source /usr/share/bashdb/bashdb-trace # adjust location

  echo $$
  while : ; do
        date=$(date)
        echo "$date"
        sleep 2
  done

Now run:

  $ bash ./debugit.sh
  Bourne-Again Shell Debugger, release bash-3.1-0.08
  Copyright 2002, 2003, 2004, 2006 Rocky Bernstein
  This is free software, covered by the GNU General Public License, and you are
  welcome to change it and/or distribute copies of it under certain conditions.

  9435
  Thu Jun 19 02:43:06 EDT 2008
  Thu Jun 19 02:43:08 EDT 2008

Sent it an "interrupt" signal

  kill -INT 9435

And back to the running program:

  Program received signal SIGINT (2)...
  ->0 in file `./debugit.sh' at line 251  # not sure where 251 came from!
  ##1 main() called from file `./debugit.sh' at line 0
  bashdb<0> where
  ->0 in file `./debugit.sh' at line 9    # but this line number is now right
  ##1 main() called from file `./debugit.sh' at line 0
  bashdb<1> list 1
    1:   # Set up some interrupt handlers to go into the debugger
    2:   source /usr/share/bashdb/bashdb-trace
    3:
    4:   echo $$
    5:   while : ; do
    6:   date=$(date)
    7:   echo "$date"
    8:   sleep 2
    9:==>done
  bashdb<2> step
  (./debugit.sh:5):
  5:      while : ; do
  bashdb<3> step
  (./debugit.sh:6):
  6:      date=$(date)
  bashdb<4> continue -

The command continue - not only continues execution but it removes the debug trap allowing the program to run at full speed. It is suitable only if there are no breakpoints that you care to stop at.

By default, bashdb-trace sets up a handler for the ‘INT’ exception. If you down’t want this or you want enter the debugger on a different signal to be use, _Dbg_handler. With this function you can specify whether to show a call stack, stop (enter the debugger) and/or print an indication that the a signal was seen.

Here are some examples:

    _Dbg_handler INT print showstack nostop  # this is the default
    _Dbg_handler INT                         # same thing
    _Dbg_hander                              # same thing
    _Dbg_handler HUP print stop              # stop in debugger when getting

2.3.1.1 Explicit Debugging Calls.

As we saw in the last section bashdb-trace installs some signal handlers. However you can make an explicit call to the debugger

     _Dbg_debugger

Let’s show an example of that. We’ll even do it under a condition:

  for ((i=1; i<=10; i++)) ;
        (( 5 == i )) && { _Dbg_debugger }
        date=$(date)
        echo "$date"
        sleep 2
  done

The debugger will be called on the 5th iteration of this loop, when i has the value 5.

You can also supply the number of statements to skip and the options to _Dbg_debugger just as you would to the debugger itself. All of the options listed in Options for the bashdb script can be used with the exception of -c (run a command) and of course you don’t supply the name of a BASH script.

For example to stop at the next line and suppress the banner you could use _Dbg_debugger 1 -q in the above example.


Next: , Up: Calling from Program   [Contents][Index]