This section of the tutorial uses the Java TextEdit example application for illustration. This application project contains both Java classes and an Objective-C class, and so it provides a good test case for exploring how to debug in this dual world. Before you begin the following tasks, copy the TextEdit example project, located at /System/Developer/Examples/Java/AppKit/TextEdit , to your temporary directory ( /tmp ).
To set up for the tasks illustrated in this section--debugging both Objective-C and Java code in the same executable--do the following:
If you are debugging a project of type JavaPackage, you must select the class with the entry point (main()
) before you begin debugging. To do this, select the class containingmain()
in the project browser; then open the Project Inspector and, in the File Attributes display, click the "Has Java main" checkbox.
When you have built the TextEdit application and have an executable containing symbols understood by the Java Debugger, run the debuggers from Project Builder. Project Builder starts up both
gdb
and the Java Debugger. In Yellow Box applications,
gdb
is started before the Java Debugger because the entry point,
main()
, contains Objective-C code.
The gdb debugger starts up, and prints output to the console view similar to this:
> Debugging 'TextEdit'...~GDB is free software and you are welcome to distribute copies of it~ under certain conditions; type "show copying" to see the conditions.~There is absolutely no warranty for GDB; type "show warranty" for details.~GDB 970507 (powerpc-apple-macosx), Copyright 1995 Free Software Foundation, Inc.~Reading symbols from /tmp/TextEdit/TextEdit.debug/TextEdit...done.~~(gdb)
This action runs gdb until it stops at a breakpoint automatically set at the entry point; it writes output to the console view that is similar to the following:
gdb) Starting program: /tmp/TextEdit/TextEdit.debug/TextEdit -NSPBDebug ~donote_1345_84422926_1994577324_1~/usr/local/standards/commonalias: No such file or directory.~~Breakpoint 1, 0x3b04 in start ()~Dynamic Linkeditor at 0x41100000 offset 0x0~Executable at 0x2000 offset 0x0~/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit at 0x43300000 offset 0x0~/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation at 0x42500000 offset 0x0~/System/Library/Frameworks/System.framework/Versions/B/System at 0x41300000 offset 0x0~(gdb)
The procedure is the same as for Java code; see Set and Manipulate Breakpoints for details.
The gdb debugger writes more output to the console view, after which it links in the necessary dynamic libraries and runs the Java Debugger (indicated by the prompt "JavaDebug>>"):
(gdb) Continuing.~/System/Library/Frameworks/JavaVM.framework/Versions/A/JavaVM at 0x5cd00000 offset 0x0~/usr/lib/java/libObjCJava.A.dylib at 0x53d00000 offset 0x0~/System/Library/Frameworks/JavaVM.framework/Libraries/libjava.A.dylib at 0x5c100000 offset 0x0~/System/Library/Frameworks/JavaVM.framework/Libraries/libzip.A.dylib at 0x5cb00000 offset 0x0~/System/Library/Frameworks/JavaVM.framework/Libraries/libdebugit.A.dylib at 0x5bf00000 offset 0x0~/System/Library/Frameworks/JavaVM.framework/Libraries/libagent.A.dylib at 0x5bd00000 offset 0x0~~JavaDebug>> /usr/lib/java/libFoundationJava.B.dylib at 0x50300000 offset 0x0~/System/Library/Frameworks/JavaVM.framework/Libraries/libmath.A.dylib at 0x5c500000 offset 0x0~/usr/lib/java/libAppKitJava.B.dylib at 0x50c00000 offset 0x0
You are now ready to set Java breakpoints and begin debugging the application. A suggested breakpoint location is at one of the constructors of the Document class.
Now do something with the TextEdit application that causes execution to stop at one of your breakpoints.
The Java Debugger runs in the Java VM and so it is running whether the target is running or not. However,
gdb
requires that the entire target process be stopped, and to ensure this it stops the Java VM. This means that when you switch from the Java Debugger to
gdb
, not only the target is stopped but the Java VM is stopped. You must click the Continue button (or enter the
continue
command) to restart the Java VM and the Java Debugger.
With both gdb and the Java Debugger running on a debugging target, you can use Project Builder's controls to perform most common debugging tasks in both Java and non-Java code. Using the "breakpoint band" next to source-code files, you can set and manipulate breakpoints in any file. When a breakpoint is hit, you can click the appropriate button on the Launch panel to step into or over code and to inspect frames, values, and objects. The correct debugger is used for the task at hand.
However, there might be occasions when you want more explicit control, and for this you need to switch between debuggers on the command line. When debugging Objective-C (and C and C++) code and Java code simultaneously, you must keep in mind that the Java VM is still running when the Java Debugger is debugging code in the stopped target; however, gdb can only debug code when all processes involving the target--including the Java VM--are stopped.
Here is how you switch between debuggers in a session. The following scenario assumes you have both debuggers active and that the target is currently executing Java code:
The Java Debugger prompt ("JavaDebug>>") appears in the Launch console. You can now perform Java debugging tasks that require the target to be stopped.
The Java Debugger relinquishes control to gdb : the "(gdb)" prompt appears and all process are stopped, including the Java VM. You can now perform debugging tasks in gdb .