J2c attempts preserves all field names, local variable names, and line
numbers present in Java bytecode.  This allows one to use gdb as a
nearly source-level debugger for Java code.  Fully source-level
debugging is not possible, because gdb does not understand j2c's
name-mangling scheme.  However, once you learn to mentally
translate source level method, variable, and class names into j2c's
mangled syntax, debugging with gdb can be quite natural.

Because many Java programmers have little experience with C debuggers,
this section attempts to provide an overview of gdb's features as it
introduces j2c's name mangling rules and the commands in your virtual
machine's @file{.gdbinit} file.

In the tutorial spirit, let's begin by starting gdb.  J2c is normally
run using @code{./ovm @var{main}}.  To run j2c in gdb, the following
commands should be used instead:
@example
$ gdb ovm
(gdb) r  @var{main}
@end example

@menu
* Using gdb::           Where to learn more
* Statics::             Introduction to j2c variable mangling
* Breakpoints::         J2c method mangling and gdb
* Navigation::          Review of gdb basics
* Locals::              More j2c variable mangling and gdb
* Core files::          More gdb basics
* EXC_BAD_ACCESS::      Mac Madness
* Bad Line Numbers::    Because inlining is hard
@end menu

@node Using gdb 
@subsection Using gdb

Gdb comes with extensive online documentation.  Much of the
doucmentation is available within gdb itself through the @command{help}
command.  J2c defines a couple useful commands that are documented
through @command{help}.  @code{help user-defined} will list them, and 
@code{help @var{cmd}} will display help for a particular command.
While gdb's built-in help can be useful, the reference manual contains
more complete documentation, including a breif tutorial.  The location
and format of the reference manual varies between platforms.

On Macs, gdb's online reference manual is available through
@uref{file://localhost/Developer/Documentation/DeveloperTools/gdb/gdb/gdb_toc.html}.
The gdb source distribution also includes a double-sided quick reference
card, which Apple has been thoughtful enough to package as a @file{.pdf}
in @file{/Developer/Documentation/DeveloperTools/gdb/refcard.pdf}.

Gdb's online reference manual is available on linux boxes
through emacs and the standalone @command{info} command.  In emacs, type 
@kbd{@key{ctrl}-h i}, search for gdb, and follow the link by either
middle-clicking on the bold text, or hitting return while the cursor
is on bold text.  Redhat does not seem to install the quick reference
card anywhere, but the Apple  version is available at 
@file{/p/sss/project/apple-gdb-refcard.pdf}.

@node Statics
@subsection Examining static fields

The values of static fields are readily available in gdb, but to find
them, you need to understand a little bit about j2c's naming
convention.  The convention is based on JNI but appropriately extended
to handle mulitple domains and classloaders, and to assign names to
fields and local variables.

The command
@example
pstatic e_s3_core_domain_S3Domain
@end example
prints all static fields of the class @code{s3.core.domain.S3Domain}
defined in the executive domain.  Each field's name is prefixed by
@code{ovm_}, and some are subject to other mangling.  For instance,
the java field @code{globalInstanceCounter_} becomes 
@code{ovm_globalInstanceCounter_1} in C++.

JNI maps most characters in a Java identifier to the corresponding
ascii character, but there are some exceptions:
@itemize @bullet
@item @samp{.} and @samp{$} become @samp{_}
@item @samp{_} becomes @samp{_1}
@item other characters that C does not allow (such as @samp{<}, @samp{>},
and anything character not present in 7 bit ASCII is encoded as 
@samp{_} followed by a 5 digit hex string.
@end itemize

System classes (including all classes in the executive domain, and
classes in the user domain's runtime library) are mapped to C++
structs whose names consist of a domain prefix (@code{e_} or
@code{u1_}), followed by the JNI encoding of the class name.  This
convention is not sufficient in the presence of multiple classloaders,
so j2c adds a per-classloader suffix to all non-system classes.  For
example, the fields of an application class named @code{HelloWorld}
would be defined in the C++ structure @code{u1_HelloWorld_c2}, because
the application classoader will always be assigned the unique
identifier 2.

@node Breakpoints
@subsection Breakpoints, ...

A breakpoint is set by supplying a C++ function name to the
@command{break} or @command{b} command.  J2c maps a Java method
definition to a toplevel C++ function name by JNI encoding the simple
name of the method's class, and the method name, choosing a unique
integer, and combining all three seperated by underscores.

Suppose we wish to set a breakpoint on the executive domain
@code{Object} constructor.  Gdb's tab completion can come to our aid.
Typing @kbd{b Object__@key{tab}@key{tab}} results in the following:
@example
(gdb) b Object__0003c
Object__0003cclinit_0003e_13477(u1_java_lang_Object_static)
Object__0003cclinit_0003e_13477(u1_java_lang_Object_static*)
Object__0003cinit_0003e_26(u1_java_lang_Object)
Object__0003cinit_0003e_26(u1_java_lang_Object*)
Object__0003cinit_0003e_7(e_java_lang_Object)
Object__0003cinit_0003e_7(e_java_lang_Object*)
(gdb) b Object__0003c
@end example
Since we don't care about static inintializers or user-domain object, 
@kbd{i@key{tab}7} will complete the method name we care about.

It is often useful to break when an exception is raised.  This can be
done in a number of ways.  J2c currently calls the helper function
@code{j2cThrow} each time a java exception is thrown, so setting a
breakpoint on this function will break on every exception.

@code{j2cThrow} takes an @code{Oop} argument (@code{HEADER *o} in
C++), but we generally care @code{o}'s runtime type rather than it's
static type.  The command @code{pclass o} will display the runtime type
the exception being thrown.

If you issue the command @code{list j2cThrow}, you will notice that
java exceptions are mapped to C++ by throwing a pointer to the
exceptions runtime type.  Hence, we can use gdb's C++ exception
support to set Java catchpoints.  For instance, we can stop on every
bad array dereference in the executive domain with
@example
catch throw e_java_lang_ArrayIndexOutOfBoundsException *
@end example

@node Navigation
@subsection Navigation

Once the program has hit a breakpoint, it can be run step by step
using one of the following commands:
@itemize @bullet
@item @command{next}, also available with the abbreviation @command{n}: executes
the program until the next line of the current function.

This instruction can take an integer parameter to say how many times
we want it to  be repeated. For instance, @code{next 4} will move 4
lines forward in the execution of the program.

@item @command{step}, or @command{s}: executes the program until the next source
line is reached.  If a function with debugging information is called,
step will descend into this funciton.

@item @command{continue}, or @command{cont}: continue until the program hits another
breakpoint. This command does also take an optional integer argument
that tells how many times the commmand should be repeated.

@item @command{finish}, or @command{fin}: continue until the current function
returns to the caller, and show the value returned.
@end itemize

Gdb allows you to examine a program's call stack whether the program
is stopped due to a breakpoint, stopped in @code{abort()}, or frozen in
a core file.  
@itemize @bullet
@item @command{bt} or @command{where}: print the program's stack trace
@item @command{frame} or @command{f}: select a frame within the stack.  You can
examine local variables within the selected frame using @command{print}.
@item @command{up}: selects the frame the previously selected frame was
called from
@item @command{down}: selects the frame the previously selected frame calls.
@end itemize

@node Locals
@subsection Examining local variables

In general, j2c is able to preserve java local variable names.  These
names are mangled in the same manner as fields, so that @code{this}
becomes @code{ovm_this}.  If we are in a call to
@code{S3Domain.makeThrowable} for the user domain, we can examine the
receiver like so
@example
print *(e_s3_core_domain_S3JavaUserDomain *) ovm_this
@end example

Note, when precise GC is enabled, reference variables are not stored in C++
local variables, but in a stack-allocated structure called frame, so
the above example becomes
@example
print *(e_s3_core_domain_S3JavaUserDomain *) frame.ovm_this
@end example

Sometimes, j2c is unable to map bytecode-level local variable numbers
to source level variable names.  In these situations, it is useful to
look at all C++ variables in the method, and try to guess where a Java
variable is hiding.

There are differences between Apple gdb v5.3 and FSF gdb v5.3.  The
most notable Apple extension is @code{show locals}.  This command
prints the names and values of all local variables in the current
function.  You can get similar results under Linux with the command,
@code{show scope @var{current-line-number}}.

@node Core files
@subsection Inspecting a core dump

If j2c segfaults, the resulting core file can be loaded in gdb using
the following command:

@example
gdb ovm core
@end example

You will not be able to run the program, but you will be able to see
where it crashed and inspect the values that were present in memory at
that time.

@node EXC_BAD_ACCESS
@subsection Preventing Segmentation Faults on the Mac

Under MacOS X, gdb interacts very poorly with user-defined
@code{SIGSEGV} handlers, such as the one responsible for write
barriers and @code{NullPointerException} generation in Ovm.  To the
best of our knowledge, there is no way to continue past a segmentation
fault under MacOS's gdb.  Ovm provides two ways to work around this
problem.
@enumerate
@item
The runtime flag @option{-disable-image-barrier} prevents segmentation
faults when writing to the bootimage section of the program (ei, the img
file).

@item
The system property @var{test.disableExceptions} can be set to prevent
NullPointerExceptions within the regression test suite.
@end enumerate
Thus, @samp{r -disable-image-barrier -Dtest.disableExceptions} can be
used to run regression tests to completion, even under gdb.

@node Bad Line Numbers
@subsection Compiling Virtual Machines for Debugging

By default, Ovm inlines very small methods.  This can improve build
time, since gcc will compile fewer functions; however, inlining can
sometimes make debugging more difficult.  With j2c, inlining can
sometimes lead to bad line number information, and can make
soome breakpoints difficult or impossible to set.  These problems can
be avoided by compiling with @samp{-opt=debug}, and are described in
more detail below.

When inlining has been performed,  J2c's notions of the current source
file and the current line number can sometimes disagree.  If gdb can't
find the current line, it is probably looking in the wrong file.
Often you can determine the real position in the program by looking at
@file{ovm_inline.cc}.  Searching for the file and line gdb reports can
help.

Ovm's inliner removes methods that are not called out of line.  This
helps reduce the build time, but can lead to trouble when you need to
set a breakpoint at an inlined method.  If there is no C++ function
corresponding to the method you want to stop at, you can try breaking
at the first line of the method, or some line that will be non-empty
from gcc's perspective.  However, recompiling with @samp{-opt=debug}
will have little impact on @code{gen-ovm}'s execution speeed, and may
be the easiest solution.

