Debugging Ptolemy II Actors

This page discusses debugging Ptolemy II actors using GNU Emacs and jdb.

Zoltan Kemenczy of Research In Motion Ltd. contributed changes to $PTII/bin/ptinvoke.in that use the Emacs gud.el file to provide source level debugging of Ptolemy II.

Christopher Hylands modified Zoltan's original notes.

Note that the debugger works best on distributions of Ptolemy II that include the Ptolemy II source files. The Windows installer and the WebStart versions of Ptolemy II do not include source files, so the debugger will be of little use under WebStart. Because the Windows installer and the WebStart editions do not include the source files, some of the hyperlinks below may be invalid.

See also the Ptolemy II Eclipse Page.

Contents

  • Emacs
  • Setting up Emacs
  • Invoking the debugger
  • Debugger Example
  • Set Breakpoints context menu choice
  • Emacs

    This page includes documentation on how to use the Java Debugger jdb and GNU Emacs to debug Java code.

    GNU Emacs is a powerful and complex editing and development environment. If you are unfamiliar with GNU Emacs, you should try running the GNU Emacs tutorial. In theory, it should be possible to debug Ptolemy using other debuggers, but we have not tried them.

    The gud.el file included in Ptolemy II requires a version of GNU emacs more recent than Emacs-20.7.1.

    The gud.el file will not work with Emacs-20.7.1 because M-x jdb results in:

    Symbol's function definition is void: easy-mmode-define-keymap
    
    We have tested the interface under Emacs-21.2.1.
    
    
    Below are the steps necessary to install Emacs under Windows.
    1. Emacs for Windows can be found at ftp://ftp.gnu.org/gnu/windows/emacs/latest

      The file to download isemacs-xx.x-bin-i386.tar.gz

    2. Untar or unzip the file in c:\Program Files so that c:\Program Files\emacs-xx.xx is created
    3. The c:\Program Files\emacs-xx.xx\README.W32 file says:
      To install Emacs, simply unpack all the files into a directory of your choice, but note that you might encounter minor problems if there is a space anywhere in the directory name. To complete the installation process, you can optionally run the program addpm.exe in the bin subdirectory. This will add some entries to the registry that tell Emacs where to find its support files, and put an icon for Emacs in the Start Menu under "Start -> Programs -> Gnu Emacs -> Emacs".
      So, go ahead and click on the addpm.exe icon, which will add an Emacs icon to the start menu.

    The GNU Emacs FAQ For Windows 95/98/ME/NT/XP and 2000 can be found at http://www.gnu.org/software/emacs/windows/ntemacs.html

    Setting up Emacs

    Emacs reads the file $HOME/.emacs at start up time.

    Under Windows 2000, you set the environment variables via the Environment tab of the System control panel (Start Menu -> Settings -> Control Panels -> System -> Advanced -> Environment Variables

    The HOME variable name your home directory using the DOS drive name with backslashes. For example, if your home directory is in c:\users\yourname, then you would enter the value c:\users\yourname

    While you are editing environment variables, be sure that $PTII is set. For details, see Set the value of the PTII environment variable

    The GNU Emacs FAQ For Windows 95/98/ME/NT/XP and 2000 at http://www.gnu.org/software/emacs/windows/ntemacs.html discusses the .emacs file further.

    To debug Ptolemy II, Emacs needs to be told where to find the gud.el file. Start up Emacs by using Start -> Programs -> Gnu Emacs -> Emacs and add the following to your $HOME/.emacs file.

    (setq load-path (append
                     (list
                      (expand-file-name 
    		   (concat (getenv "PTII") "/util/lisp")))
                     load-path
                     ))
    
    A more complete example .emacs file can be found at $PTII/util/lisp/ptemacs.el If you wish, you can copy this file to your $HOME/.emacs file. This file includes support for
    M-x shell
    Brings up a bash shell
    (TODO) Java indentation
    Java indentation that follows the Ptolemy II Style guide

    Using Emacs as a Text Editor Within Ptolemy II

    Optionally, you may want to associate Emacs as the text editor to use when text files are viewed within Ptolemy II.

    This feature is especially nice while running a vergil -debug session from within emacs and the user wants to set a breakpoint in an actor or director. Typical, one starts up vergil with vergil -debugControl-x SPACE to set a break point.

    To do this, you need to have Gnuserv installed and do some other set up.
    http://www.gnu.org/software/emacs/windows/faq2.html#assoc discusses how to install gnuserv/gnuclient

    1. Download http://www.wyrdrune.com/Files/gnuserv.zip
    2. Unzip it anywhere, for example c:/tmp/gnuserv
    3. Install gnuserv.el into emacs' load-path, in this case
      cd c:/tmp/gnuserv
      cp gnuserv.el $PTII/util/lisp
      
    4. Install the executables into your path
      cp Release/*.exe $PTII/bin
      
    5. Make sure that $PTII/bin is in your path.
      Under Windows XP, it is best if you add $PTII/bin (Under Windows XP, you set the environment variable via the Environment tab of the System control panel (Start Menu -> Control Panels -> System -> Advanced -> Environment Variables)
      The value that is added to the path should either be
      %PTII%\bin
      
      or you should expand PTII by hand
      c:\ptII\bin
      
    6. Add
      (load "gnuserv")
      (gnuserv-start)
      
      to your ~/.emacs file
    7. Edit $PTII/bin/ptinvoke.in and uncomment the line
      USERJAVAPROPERTIES=-Dptolemy.user.texteditor=emacs
      
      and then run
      make
      
      to update $PTII/bin/vergil etc.
    To test the facility start up emacs and then start up vergil and try File -> New -> Text Editor.

    Invoking the debugger

    The Ptolemy II start up scripts in $PTII/bin have the following options that interact with the debugger.
    Under Windows, these options will not work with the DOS scripts, you must run the shell script versions of these scripts.
    The easiest way to run these scripts under Windows is to start up the Cygwin bash shell.
    Another way is to use the DOS shell and preface the commands with bash -C:
    cd %PTI%
    bash -C ptolemy -debug ptolemy/domains/sdf/demo/Butterfly/Butterfly.xml
    
    -debug
    This starts the java VM in a mode that allows debugger connections. The nice thing is that you can run e.g. vergil, load models, run without a debugger until you encounter a problem (exception :-). Then you attach jdb to your vergil process, set to catch the exception and re-run... The exception is now caught by jdb in Emacs with all the source files and call stack available for examination.

    Notes:

    1. vergil runs a bit slower with this option.
    2. I have only tested the JVM attach on Windows with shared memory attaches (I would have preferred the socket approach but Sun didn't do it on Windows...) Someone should try the socket connection method on Solaris/Linux and update ptinvoke to select based on the system type...
    -jdb
    This starts using jdb instead of java to allow debugger control right from the start. Typically you provide this option in response to Emacs' M-x jdb prompt Run jdb (like this):
    ptolemy -jdb .../my.xml
    
    -q
    for "quiet" - it is not really a debug option, but eliminates the echo of the command line constructed by ptinvoke to start java.
    Note: Don't use -q with -jdb within Emacs. If you do, then the Emacs GUD mode will not be able to get the classpath.
    -profiler
    has the java profiler startup options canned (these could be passed using JAVAFLAGS, but then you have to remember and set/type them every time). Very useful to find out where ptolemy is spending most of the CPU time...

    Emacs GUD updates

    These have already been submitted to Richard Stallman and incorporated into the www.gnu.org Emacs CVS, but there are not yet in 21.2

    The following is a useful addition to a user's .emacs file (for the Windows shared memory attach) (setq gud-jdb-command-name "jdb -attach javadebug")

    The documentation of changes is in the gud-jdb-use-classpath and gud-jdb-classpath (and other gud-jdb-xxx) variables. The new method of finding java source files through the classpath of the JVM is automatically enabled so no special setup is needed.

    There are two primary ways to use the Emacs interface to debug Ptolemy:

    1. Use the -debug flag so that java starts up Ptolemy II and synchronizes with Emacs
    2. Use the -jdb flag so that jdb starts up Ptolemy II.

    -debug

    The -debug option is more commonly used than -jdb because with -debug, you can attach the debugger at any point during the run. To use -debug, just start your vergil from a bash or Emacs shell with:
    vergil -debug &
    
    You should see a message:
    Listening for transport dt_shmem at address: javadebug
    
    and the vergil window should come up.

    when you'd like to debug (e.g set breakpoints or catch exceptions), start jdb from Emacs by:

    M-x jdb
    
    Then type
    jdb -attach javadebug
    
    if you're on windows (on Unix "javadebug" would be replaced by the JVM debug server socket port number).

    You should get a buffer named *gud-...* with the Initializing jdb... message. After that switch to any Emacs buffer holding a source and go to a function that will be used during a run (e.g. Manager.run()). On a source line, press C-x SPACE. In the *gud-...* buffer, a breakpoint command is automatically entered for you (this is GUD at work).

    Now run the model... When the breakpoint is hit the source file (Manager.java) will be positioned at the breakpoint with a "=>" at the beginning of the line where the stop occurred. Now you can use C-c C-n (for "next" or "step-over") or C-c C-s (for "step" or "step-into") and a bunch of other short-cuts (like call stack browsing up/down)... An the "=>" follows your steps and brings up source files as needed (GUD again...:).

    Most of the standard gud-style commands are supported (check out the "GUD" menu in the *gud-..*

    -jdb

    The difference between -debug and -jdb is that -jdb can be used to debug initialization code that would have already been run by the time the application comes up.

    You can start ptolemy -jdb from a bash shell within Emacs, but that doesn't get you into GUD mode, which allows for easy breakpoint setting etc.

    To start vergil or ptolemy (or other) with jdb instead of java, enter start jdb from Emacs by:

    M-x jdb
    
    and then type:
    bash -C ptolemy -jdb ptolemy/domains/sdf/demo/Butterfly/Butterfly.xml
    

    Don't use the -q flag here because that will prevent GUD from getting the classpath (it finds it in the command line echo provided by ptinvoke. If you used a manual way of starting jdb (instead of ptinvoke), you would normally have to provide a -classpath argument which is what GUD is looking for).

    The windows version of Emacs is not cygwin-aware and it uses its own win32 api to start any subprocess and this looks for an ".exe" (or .bat)... This is why we have to insert "bash -C" (which is an exe in the path) to make sure that the ptolemy link will be caught and processed...

    If you then switch to a java source (that is in the classpath and/or sourcepath) and do C-x SPC, a breakpoint will be set.

    Debugger Example

    Below is an example of how to use the debugger
    1. Install emacs as per the Emacs step above.
    2. Set the Emacs load path as per the Setting up Emacs step above.
    3. Type M-x shell. In Emacs, M-x means
      "Hit the Esc key and then the x key."
    4. You will now be in a buffer named *shell*. In this buffer, start up vergil with
      $PTII/bin/vergil -debug $PTII/ptolemy/domains/sdf/demo/Spectrum/Spectrum.xml
      
    5. Run the simulation by doing View -> Run -> Go
    6. Start up the debugger by typing M-x jdb. If your .emacs file contains:
      (setq gud-jdb-command-name "jdb -attach javadebug")
      
      then after typing M-x jdb, the following lines should appear in the minibuffer at the bottom of the emacs window:
      Run jdb (like this): jdb -attach javadebug 
      
      If jdb -attach javadebug does not appear, then type it in. After the minibuffer contains jdb -attach javadebug hit Enter and jdb starts up.
    7. Now we will set a break point in the iterate() method of the Ramp actor. To do this, type in the following in the *gud-javadebug* buffer
      stop in ptolemy.actor.lib.Ramp.iterate
      
    8. Then rerun the model with View -> Run -> Go
    9. The debugger will stop execution in the iterate() method
    10. The Emacs debugger interface can bring up the source file where the break point is set, but the interface sometimes needs help finding the file. The quickest way is to view the file by typing C-x C-f and then $PTII/ptolemy/actor/lib/Ramp.java In Emacs documentation, C-x means
      "Hold the Control key down and then hit the x key" and then typing
      up
      down
      where
      
      in the *gud-javadebug* buffer
    11. To step through the code, type next
    12. To view the value of a variable, type print variable name
      In the example below, I typed next twice, and then viewed the value of the i variable:
        [7] java.lang.Thread.run (Thread.java:536)
      Thread-5[1] next
      > 
      Step completed: "thread=Thread-5", ptolemy.actor.lib.Ramp.iterate(), line=186 bci=17
      186    	for (int i = 0; i < count; i++) {
      
      Thread-5[1] next
      > 
      Step completed: "thread=Thread-5", ptolemy.actor.lib.Ramp.iterate(), line=187 bci=22
      187    	    _resultArray[i] = _stateToken;
      
      Thread-5[1] print i
       i = 0
      Thread-5[1] 
      

    To get further help with jdb, type help while in the *gud-javadebug* buffer.
    For further information about jdb, see JavaTM Platform Debugger Architecture.

    For further information about the Emacs Grand Unified Debugger (GUD) Interface, use the GNU Emacs Info help system.

    1. Click on the Help menu, or type M-x info
    2. Move the cursor to the Emacs line and type a m followed by hitting the Enter key.
    3. Move the cursor down to the Starting GUD line and type a m and hit return