.mmm
files
at runtime.
See $METRO/util/mgdb/README.txt
for details.
This page discusses debugging Metropolis Java code using GNU Emacs and jdb.
We need both styles of debugging because the Metropolis Java code reads in the .mmm files and generates C++ files.
Zoltan Kemenczy of Research In Motion Ltd. contributed changes
to Ptolemy that provided source level debugging of Ptolemy II.
These changes were then migrated over to Metropolis.
Christopher Brooks modified Zoltan's original notes.
The way debugging works is that $METRO/bin/metroinvoke.in
can use
$METRO/util/lisp/gud.el
to provide source level debugging of Metropolis
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 Metropolis
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-keymapWe have tested the interface under Emacs-21.2.1.
Below are the steps necessary to install Emacs under Windows.
ftp://ftp.gnu.org/gnu/windows/emacs/latest
The file to download isemacs-xx.x-bin-i386.tar.gz
c:\Program Files
so
that c:\Program Files\emacs-xx.xx
is created
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
$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
$METRO
is set. For details, see
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 Metropolis, 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 "METRO") "/util/lisp"))) load-path ))A more complete example
.emacs
file can be found at
$METRO/util/lisp/metroemacs.el
If you wish, you can copy this file to your $HOME/.emacs
file. This file includes support for
M-x shell
$METRO/bin
have the following options that interact with the debugger.
bash -C
:
cd %METRO% bash -C systemc -debug Your other arguments
-debug
Notes:
-jdb
systemc -jdb other systemc args
-q
-q
with -jdb
within
Emacs. If you do, then the Emacs GUD mode will not be able to get the
classpath.
-profiler
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 Metropolis:
-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 Metropolis binary from a bash or Emacs shell
with:
system -debug &You should see a message:
Listening for transport dt_shmem at address: javadebugand the program should contine
when you'd like to debug (e.g set breakpoints or catch exceptions), start jdb from Emacs by:
M-x jdbThen type
jdb -attach javadebugif 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. src/metropolis/metamodel/Compiler. main()). 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 (Compiler.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-..*
-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 a Metropolis script in $METRO/bin
with
the -jdb
argument, such as systemc -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 a Metropolis script with jdb instead of java, enter start jdb from Emacs by:
M-x jdband then type:
bash -C systemc -jdb jdb binaries
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 metroinvoke. If you used a manual way of starting jdb (instead of metroinvoke), 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 systemc 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.
M-x shell
. In Emacs, M-x
means
Esc
key and then the x
key."
*shell*
. In
this buffer, change to the test_new directory
cd $METRO/examples/test_new
make clean
$METRO/bin/systemc -debug
:
make DEBUG=-debug
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 javadebugIf
jdb -attach javadebug
does not appear, then type it
in.
After the minibuffer contains jdb -attach javadebug
hit Enter
and jdb starts up.
main()
method
of the Compiler actor. To do this, type in the following in
the *gud-javadebug*
buffer
stop in metropolis.metamodel.Compiler.main
cont
main()
method
main[1] stop in metropolis.metamodel.Compiler.main Deferring breakpoint metropolis.metamodel.Compiler.main. It will be set after the class is loaded. bmain[1] cont > Set deferred breakpoint metropolis.metamodel.Compiler.main Breakpoint hit: "thread=main", metropolis.metamodel.Compiler.main(), line=93 bci=0 93 _processArguments(args); main[1]
C-x C-f
and then $METRO/src/metropolis/metamodel/Compiler.java
In Emacs documentation, C-x
means
Control
key down and then hit the x
key"
and then typing
up down wherein the
*gud-javadebug*
buffer
next
print variable name
next
twice, and
then viewed the value of the args
variable:
main[1] where [1] metropolis.metamodel.Compiler.main (Compiler.java:93) main[1] next > Step completed: "thread=main", metropolis.metamodel.Compiler.main(), line=94 bci=4 94 System.out.print("Loading libraries"); main[1] next > Step completed: "thread=main", metropolis.metamodel.Compiler.main(), line=95 bci=12 95 _initCompiler(); main[1] print args[0] args[0] = "-classpath" main[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.
Help
menu, or type M-x info
Emacs
line and type a m
followed by hitting the Enter
key.
Starting GUD
line and
type a m
and hit return