Because many JavaDebug commands semantically correspond to gdb commands, Project Builder reuses the same controls and displays for controlling a Java debugging session. Some JavaDebug commands, however, cannot be invoked from the user interface. You must execute these commands from the command line. If you need to find out which Java Debugger commands are available, you can display a list of valid commands by entering anything that is not a valid command (such as "help") after the "JavaDebug>>" prompt:
JavaDebug> help
When JavaDebug starts up, a light gray band appears on the left edge of source-code files in the code editor. As in Objective-C debugging, you can set a breakpoint in Java code by double-clicking in this gray band next to the line of code where you want a breakpoint.
convert
method in
TempController.m
.A small pointer appears in the gray band.
Once you set a breakpoint you can move it within a file by dragging a pointer up and down the gray band. You can remove it by dragging the pointer off the gray band into the code editor. And you can temporarily disable a breakpoint, by Control-double-clicking the pointer, after which it turns gray (re-enable it by Control-double-clicking the pointer again). You can also use the Breakpoint display of the Task Inspector to enable and disable breakpoints:
Several Java Debugger commands let you set, disable, and otherwise manipulate breakpoints from the command line. For example, to set the same breakpoint as above, you can just specify the class and method, separated by a colon:
JavaDebug>> b TempController:convert Set breakpoint 2000 in method: convert at line 13 in file "TempController.java"
As in any kind of debugging, before you can perform any useful debugging task, such as stepping through code, you must run the program until it hits the next breakpoint.
Notice how as you step over lines the program counter changes to the next line to be executed.
tempDidChange
), click the Step Into button. The code editor displays
TempImageView.java
(or
TemperatureView.java
if you are using the view object implemented by that code) and the program counter points to the first line of the
tempDidChange
method.
You can also use Java Debugger commands to step into (
stepi
,
step
, and
si
) and step over (
next
) lines of code. The
finish
command lets you "step out," or complete the execution of the current stack frame. Note that pressing Return repeats the last step command entered.
At any point in debugging you can view the current stack frame.
The display lists the methods in the stack frame in the order of invocation; each line shows the arguments of a method. (Of course, the arguments of methods for which your project has no source code are not shown.) Double-click a line to display the method in the code editor.
The Java Debugger has several commands that you can use to get a backtrace and examine a frame. To show the stack frame, enter the
backtrace
or
bt
command:
JavaDebug>> bt [0]TempImageView.tempDidChange (TempImageView:38) pc = 0 [1]TempController.convert (TempController:20) pc = 73
To examine an individual frame, enter
frame
followed by the frame number:
JavaDebug>> frame 1 [1] convert(sender=<NSTextField: 0x1813508>)
Project Builder lets you examine data of three general types: value, reference, and object. Buttons on the Launch panel correspond to these types:
toString
method.Because the Java Debugger treats primitive types as objects, the "Print Value" and "Print Object" commands are equivalent.
Unless a variable (such as an instance variable) has global scope or is an argument, you must highlight it after the statement that assigns it a value has been executed.
Of course, you can give the same commands from the Java Debugger command line.
JavaDebug>> p* sender sender = (com.apple.yellow.application.NSTextField)0x368470 { private int instance = 53568 }
JavaDebug>> p* NSTextField NSTextField = 0x3646c0:class(com.apple.yellow.application.NSTextField) { superclass = 0x366408:class(com.apple.yellow.application.NSControl) loader = null private static boolean _alreadySqwaked = false public static final String ViewFrameDidChangeNotification = NSViewFrameDidChangeNotification public static final String ViewFocusDidChangeNotification = NSViewFocusDidChangeNotification public static final String ViewBoundsDidChangeNotification = NSViewBoundsDidChangeNotification public static final int NoBorder = 0 public static final int LineBorder = 1 public static final int BezelBorder = 2 public static final int GrooveBorder = 3 public static final int ViewNotSizable = 0 public static final int ViewMinXMargin = 1 public static final int ViewWidthSizable = 2 public static final int ViewMaxXMargin = 4 public static final int ViewMinYMargin = 8 public static final int ViewHeightSizable = 16 public static final int ViewMaxYMargin = 32 public static final String ControlTextDidBeginEditingNotification = NSControlTextDidBeginEditingNotification public static final String ControlTextDidEndEditingNotification = NSControlTextDidEndEditingNotification public static final String ControlTextDidChangeNotification = NSControlTextDidChangeNotification }
JavaBug>> p* this this = (TempImageView)0x39f5c8 { private int instance = 25616120 protected NSImage coldImage = (com.apple.yellow.application.NSImage)0x39f670 protected NSImage moderateImage = (com.apple.yellow.application.NSImage)0x39f688 protected NSImage hotImage = (com.apple.yellow.application.NSImage)0x39f3f0 }
With the Java Debugger, you can debug multiple threads in an application, switching among them to set breakpoints, examine stack frames and data, and perform other debugging tasks. The Java Debugger displays threads in groups; each thread has its own unique number within a group. To switch to another thread, you enter the
thread
command with the thread's group number as an argument.
To find out a thread's number, enter the
group
command (Project Builder has no controls equivalent to the
group
and
thread
commands):
JavaDebug>> group Group: system 1 Finalizer thread cond. waiting 2 JavaDebug cond. waiting 3 Debugger agent running 4 Breakpoint handler cond. waiting 5 Step handler cond. waiting 6 Agent input cond. waiting 7 main suspended 8 myThread cond. waiting Group: main 1 main suspended ··CURRENT GROUP is "system" ··CURRENT THREAD within the group is "main"
In addition to the names and numbers of threads, the output shows the current states. To switch to a thread, enter the
thread
command with a thread number.
JavaDebug>> thread 8 Current thread now myThread, state=cond. waiting