The metamodel debugger mgdb is a wrapper around the Gnu
debugger, gdb. It allows the user to run a SystemC
simulation of a metamodel in the debugger, and to set breakpoints
directly in the metamodel (.mmm) source code, and to track
execution in that source code instead of the generated C++ code from
which the executable is compiled.
A graphical version mddd uses ddd, which is
itself a graphical wrapper
around gdb.
mgdb uses gdb and several standard Unix utilities,
which all must be on the user's PATH. The programs that must be on the
user's PATH include
sh,
rm,
sed,
awk,
sort,
touch,
echo,
comm and
gdb, version 6.1 or later
ddd (for mddd), version 3.2.1 or later
mgdb has been successfully tested on code compiled
with g++ version 3.3.3. It is known to fail to set breakpoints at expected
places when running on code produced with g++ version 3.2.
The user must have write access to the directory /tmp, since
the program writes temporary files there.
To compile metamodel code to create a SystemC simulation, the user
ordinarily runs the script $METRO/bin/systemc with the
source code file names as arguments, and then
"make -f systemc_sim.mk", where systemc_sim.mk
is a makefile created by the systemc program.
To compile for debugging, simply add the command-line option,
"-mmdebug" to the $METRO/bin/systemc
command, before the file names. For example:
$METRO/bin/systemc -mmdebug -top myPkg.myNetlist Foo.mmm Blah.mmm
This adds extra information to the generated C++ code of two basic types:
#line" preprocessor directives that relate each
executable C++ code line to a line in the corresponding metamodel
(.mmm) file, and
-mmdebug option, generated .cpp files will already
exist.
In order for them to be replaced by ones with the added debugging information,
they should be removed before compiling with -mmdebug, or
else the -w option should be added to the systemc
command to forcibly overwrite them. The latter may be the simplest way to
be sure that the build is consistent, if not all the generated .cpp files are in
the current directory.
The generated makefile called "systemc_sim.mk"
that is created when compiling with "-mmdebug"
is configured to remove all the generated .cpp
files when "make clean" is done.
However, if systemc is run without -mmdebug
before a "make clean" is done, systemc_sim.mk
will be replaced with a version that doesn't know how to remove all the
generated .cpp files.
In this case, debugging-version
files may get left still existing in various directories.
If this happens,
the current best solution is to recreate the debugging version of
systemc_sim.mk by running systemc again with
-mmdebug and doing a "make clean".
(Or, it may be easier to remove them by hand if there aren't that many of them.)
To run the debugger, execute the command:
$METRO/bin/mgdb run.x
or
$METRO/bin/mddd run.x
where run.x is the name of the executable file generated by
$METRO/bin/systemc.
Running either command with an initial argument of -h
displays a simple usage message and quits.
The first source file to be shown by the list command (or in
the source code window under mddd) on startup will not be a
metamodel source file, but some underlying C++ code. To display a
.mmm file of interest, use the list command
with an argument of the file name and a line number. For example:
> list architecture.mmm:1
Breakpoints can be set in the currently listed file using just the line
number:
> break 10
or in another file by preceding the line number with the file name and a colon:
> break behavior.mmm:7
The debugger accepts all of gdb's command-line options, although
many of them don't make sense for debugging metamodel code. The
-x init_file option can be useful for automatically
executing a stored set of commands on startup.
If the file mgdb.ini exists in the user's current directory
on startup, and is readable, that file will be assumed to contain startup
commands and will automatically be executed before any other files listed
with -x options.
The following are special commands provided by mgdb:
Like gdb's "next", this does not step into
methods, but treats them as one statement. Also, this ignores the
test-condition code of await statements, and stops only in
the await's critical-section code.
Since "next" will stop only at the next statement encountered
by the current process, any number of other process may do
any number of things before the next command stops.
mgdb commands redirect console output to
temporary files to gather information of various kinds.
If a segmentation fault or bus error should occur while output is being
redirected,
it will continue to be redirected, which can be very confusing to the user.
(If a where command produces no output, this is what has happened.)
The command delog displays the most recently redirected output
and restores the output stream to the user console.
The gdb "step" command currently
does not work in any useful way, since it executes the next command in the
.cpp code, which may have little to do with the next command
in the .mmm code.
Because mgdb uses gdb's logging feature to gather
information that it needs into temporary files, the user cannot use
gdb's logging features to save or redirect output.
See the description of the delog command, above. If you find
that your commands produce no output, try the delog command to
restore normal function.
next" command to step through
a for-loop, that the debugger will skip the "for (...)"
statement when the loop iterates, and
instead stop on the first statement in the body of the loop.
This is because the "next" command works by explicitly setting
breakpoints behind the scenes,
and gdb will only stop at a breakpoint set at
a for (...) statement once, on entry to the loop.
This in turn is because gdb considers only the
first statement among
multiple statements that appear on one line, and the first statement at
the top of a for-loop is the initialization statement, which is only executed
once, on entry to the loop.