8.0 CodeBuilder Programming Environment

8.1 CodeBuilder Development Tools
8.1.1 Programs, Libraries and Include Files
8.1.2 Documentation
8.1.3 Program Sources
8.2 PEF and XCOFF
8.3 Shared Libraries
8.3.1 Shared Library Production
8.3.2 Run-Time and Compile-Time Libraries
8.3.3 Run-Time and Compile-Time Naming Conventions
8.4 Traditional UNIX Libraries
8.5 Header Files
8.5.1 Pre-Defined Names
8.6 Compiling Sources
8.6.1 Ada
8.6.2 C
8.6.3 Objective-C
8.6.4 C++
8.6.5 Fortran
8.6.6 Java
8.7 Linking Executables
8.7.1 ld
8.7.2 mkpef
8.8 To make or pmake
8.9 Symbol Information
8.10 Debugging
8.10.1 Debugging Using gdb
8.10.2 Macintosh Debugging Tools
8.10.2.1 MacsBug
8.10.2.2 The Debugger
8.10.2.3 Macintosh Debugger for PowerPC
8.10.2.4 Metrowerks Debugger
8.10.3 Environment Variables for Debugging and Monitoring
8.10.3.1 DEBUGGERFIRST
8.10.3.2 STACKCHK
8.10.3.3 MEMSTATS
8.11 Making Macintosh Applications
8.11.1 Macintosh OS Header Definition Files
8.11.2 Macintosh OS Interface Libraries
8.11.3 Macintosh Application Startup Routine
8.11.4 Macintosh Application Construction
8.12 Cross-Development Tools And Targets
8.12.1 Default CodeBuilder Environment
8.13 Porting Software to CodeBuilder
8.13.1 Real Memory Issues
8.13.1.1 Stack Overrun
8.13.1.2 Allocating Memory in CodeBuilder
8.13.1.3 Calculating Memory Requirements
8.13.1.4 Setting the CodeBuilder Heap Size
8.13.1.5 Problem Areas
8.14 Programming Example
8.14.1 Rogue
8.14.2 Building the Executable
8.14.3 Debugging Using MacsBug or Other Macintosh Debuggers


8.0 CodeBuilder
Programming Environment


MachTen CodeBuilder provides a rich UNIX software development environment. The CodeBuilder software tool suite has been modified to work in real memory for Macintosh hardware. The traditional UNIX software development tools - ld, nm, ar, etc. - have been ported to run in PowerPC native mode and produce PowerPC native mode Code Fragments.


8.1 CodeBuilder Development Tools

8.1.1 Programs, Libraries and Include Files

CodeBuilder consists of a combination of programs, libraries, and include files from BSD4.4-Lite (hereafter simply referred to as BSD), GNU, Tenon Intersystems, and other sources. Most programs reside in /usr/bin and include files in /usr/include. Programs, libraries, and include files targeting a particular system architecture are stored in the subdirectories bin, lib, and include of a target directory in /usr. For the Power Macintosh, the target directory is named /usr/macppc. Support for other target architectures is planned for future releases. The tools in the target directories run on the host system, but produce objects and executables that run on the target system. Environment variables and symbolic links will help determine which tools are run.

CodeBuilder software development tools include:
TOOLS FOR MANAGING SOFTWARE DEVELOPMENT
Revision Control System (RCS)
Automates the storing, retrieval, logging, identification and merging of multiple revisions of text

TOOLS FOR SUPPORTING SOURCE CODE DEVELOPMENT
flex
Generates lexical analysis programs
indent
Formats C Code
yacc
"yet another compiler-compiler"

TOOLS FOR BUILDING LIBRARIES AND PROGRAMS
ar
Library archive utility.
as
PPC assembler.
cpp
GNU preprocessor.
g++
Wrapper for calling gcc with appropriate options for compiling and loading C++ objects.
g77
Wrapper for calling gcc with appropriate options for compiling and loading Fortran objects.
gcc
GNU CC compiler director: forks the appropriate tools for compiling and loading the objects specified.
gdb
Symbolic debugger.
gnatmake
GNAT make program.
ld
Combines several object files into one, resolving external references and searching libraries.
make
Executes a scripted set of commands to update one or more target files; GNU version.
nm
Prints lists of symbols in object files.
pmake
Executes a scripted set of commands to update one or more target files; BSD version.
ranlib
Converts archives to a form which ld can load more rapidly.
restool
Provides access to Macintosh file resources.
setstackspace
Adjusts size of program stack.

COMPILER ENGINES
cc1
GNU C language compiler
cc1plus
GNU C++ language compiler
f771
GNU Fortran language compiler
gnat1
GNU Ada language compiler
cc1obj
GNU Objective-C compiler

LIBRARIES
libc.a
the C library
libobjc.a
the Objective-C library
libcap.a
Columbia AppleTalk Protocol library
libcompat.a
Contains obsolete BSD4.3 functions for compatibility
libcurses.a
Old screen functions with cursor motion
libf2c.a
The GNU Fortran library
libfl.a
The library for flex
libg++.a
The GNU C++ library; includes libio.a functions
libgdbm.a
GNU database management functions
libgnat.a
The GNU Ada library
libgthreads.a
POSIX Threads functions
libio.a
New GNU C++ iostream classes
libiostream.a
Old GNU C++ iostream classes; use libio.a instead
libkaffe-agent.a
kaffe support library
libkaffe-native.a
kaffe support library
libkaffe-net.a
kaffe support library
libkaffe-vm.a
kaffe support library
libkvm.a
Kernel memory interface functions
libm.a
Math library
libncurses.a
New screen functions with cursor motion
libresolv.a
Domain Name Server interface functions
librpc.a
Remote procedure call library
librx.a
GNU regular expression functions
libstdc++.a
GNU ANSI C++ library
libterm.a
Terminal independent operation library package
libutil.a
Daemon support functions
liby.a
The library for yacc

TOOLS FOR BUILDING X WINDOWS PROGRAMS
imake
X platform independent make environment
libFS.a
Font Service library for X font clients
libICE.a
Inter Client Exchange library
liboldX.a
X11R4 support library
libolgx.a
OpenLook graphics library
libPEX5.a
PHIGS Extensions to X
libSM.a
X Session Management library
libX11.a
Core X protocol library
libXau.a
X security authorization library
libXaw.a
The Athena widget set of buttons, pull-down menus, labels, etc.
libXdmcp.a
X Display Manager Control Protocol library
libXext.a
X extensions library
libXi.a
Alternative input device extension library
libXIE.a
X Image Extensions library
libXmu.a
X miscellaneous utilities library
libXpm.a
X pixmap image library
libXt.a
X Intrinsics toolkit library
libXtst.a
X Test library
libXview.a
X View library


8.1.2 Documentation

CodeBuilder documentation is available in many formats. On-line documentation includes the ubiquitous UNIX man pages in /usr/share/man, and the GNU info files in /usr/share/info. The top level folder Documentation on the CodeBuilder CD provides extensive documentation in HTML and printable form. The HTML collection includes several GNAT documents, the Lovelace Ada tutorial, many GNU package info documents, and the UNIX man pages. The printable collection includes many BSD supplementary papers in PDF format, and PostScript versions of the man pages.


8.1.3 Program Sources

The sources distributed with CodeBuilder may be found in the top level folder of the CodeBuilder CD in the SourceFFS fast file system file. The source modules are organized into a number of directories indicative of their origin or use. The default mode of access is by way of /base/src, which is a mount point for /CDROM/Source_FFS CodeBuilder is configured to mount the CD (if present) on /CDROM. Other directories in /base are named after target system architectures, e.g. /base/macppc represents the Power Macintosh. The convention is that object files and executables are built in the target directories while the source directory remains "pure".

The BSD4.4-Lite and GNU source trees use different make programs which have slightly different Makefile syntax. Rather than force one camp into the other, CodeBuilder provides both make programs. One key difference is that BSD Makefiles reside in the source directory, while GNU Makefiles are created in the object directory by a configuration script. The BSD source directories point to the target object directory with a symbolic link named obj. The obj symbolic link refers to /var/obj which is a symbolic link to the desired target directory in /base. This allows for a quick change between target architectures, but also requires you to be conscious of which target is currently selected. The GNU Makefiles use the VPATH variable to point back to the source directory.

When porting or developing new UNIX programs for CodeBuilder, you should try to mimic or extend this file system organization if possible. Following this model may actually ease the job of porting software to the CodeBuilder system. These strategies make good use of the provided BSD4.4-Lite master Makefiles in /usr/share/mk, and ease both developing for multiple targets, and sharing your work with other CodeBuilder users. The symbolic link /base/src/local, which points to /usr/local/src, may be used to graft local source packages into this source-object organization.

In a later section of this chapter, the source for the UNIX game rogue is used as an example of a program that can be compiled, debugged, and run on a Power Macintosh using CodeBuilder. This source is in /base/src/bsd4.4/games/rogue, which further illustrates the structure of the BSD4.4-Lite source file hierarchy used in CodeBuilder.


8.2 PEF and XCOFF

CodeBuilder uses PEF (PowerPC Executable Format) as its binary executable standard. PEF is an Apple Computer standard for defining executable programs and executable code objects. The PEF standard is native to the PowerPC Macintosh architecture. By generating PEF, the CodeBuilder development tools achieve a large degree of synergy with other Power Macintosh development environments and the Power Macintosh OS. PEF executable files are composed of one or more elements called Code Fragments. The many advantages of Code Fragments include the runtime dynamic linking between fragments and automatic code and data sharing between applications with shared libraries of Code Fragments.

PEF formatted files are developed as the last step in the CodeBuilder software production process. Internally the CodeBuilder development tools rely on an IBM binary executable standard called XCOFF (eXtended Common Object File Format). This file format is much richer in the amount of information kept about an application and its structure and data at the expense of significantly larger disk file and longer dynamic relocation overhead. For CodeBuilder debugging purposes, it is possible to retain an XCOFF image of a PEF executable. See section "8.7 Linking Executables" for command line information to retain XCOFF file images.


8.3 Shared Libraries

The CodeBuilder development software supports the production of libraries of software that may be shared among application programs. Using shared libraries, a second copy of a program shares part of its memory with a first program instance. Shared libraries result in large memory savings when families of applications are executing at the same time. Secondarily, shared libraries also aid in the introduction of a new version. Since shared libraries are linked during the execution of a program rather than the development of a program, a new version of a shared library can be introduced simply by replacing an older version and restarting the applications that use it. In older non-shared organizations, each application would have to be re-linked with the new library and then introduced into a system.


8.3.1 Shared Library Production

To produce a shared library with the CodeBuilder development system, you must specify that you want a shared library to be produced by using the -Xlsharedlibrary flag on the compile or loader command line. You must also specify which symbols within the library that you want exported for linkage with an application. The command line flag -Xlexpall exports all global symbols in the shared library. The command line flag -Xlexport=<filename> exports the symbols named in the file <filename>. For example, if the file some_symbols contained the following lines:
symbA
symbB
symbC
Using the command line flag Xlexport=some_symbols, the three symbols would be found in the shared library and would be set up for export and linkage when an application program requested that the library be included in its import file list.


8.3.2 Run-Time and Compile-Time Libraries

The specification of the -Xlsharedlibrary flag will create two libraries - a run-time library and a compile-time library. The run-time library should be put in the run-time search path of the loader that is launching the application which requested that library for shared library import. In the case of CodeBuilder, which uses the Mac OS Code Fragment loader, the Tenon Application Libraries folder, which lives in the Extension folder, is in the search path for the MacOS Code Fragment loader, hence the run-time version of shared libraries should be put in this folder. The compile-time library should be used on the compile command line of applications during software compilation. The run-time library serves the purpose of providing a single copy of software to multiple applications. The compile-time library is used to resolve compile-time references between imported symbols in an application and exported symbols from a shared library.


8.3.3 Run-Time and Compile-Time Naming Conventions

It is important to understand the naming convention for the run-time and compile-time libraries. Compile-time libraries are named by adding a .a suffix to the output file specified on the command line. For example, the command line:
gcc -o /hfs/shlb/shrlib -sharedlibrary -expall *.o
will produce a run-time shared library in the file shrlib, and will produce a compile-time shared library in the file /hfs/shlb/shrlib.a that exports all symbols. Note that shared libraries must be created as HFS files because they require the setting of certain Macintosh resources via the MacOS Resource Manager.


8.4 Traditional UNIX Libraries

The traditional UNIX libraries (libc.a, libm.a, etc.) are implemented as shared libraries under CodeBuilder. These compile-time libraries reside in /usr/macppc/lib and the corresponding run-time libraries reside in System Folder: Extensions: Tenon Application Libraries.

When an application is created, the compile-time libraries must be used to satisfy symbolic references to functions and data declared in the support libraries. When an application is launched, the shareable runtime libraries are found by the Code Fragment Manager and loaded into memory if they are not already in use, and instantiated for use by the application.

Some compile-time libraries do not have a corresponding runtime library. These libraries are not shareable, hence the loader will statically bind them into the application execution image.

If another Power Macintosh software development environment (MPW, Metrowerks, etc.) is used to build CodeBuilder applications, the PEF libraries in System Folder: Extensions: Tenon Application Libraries should be used for both the compile time Header Call definitions and the run time dynamic linking. The XCOFF libraries in /usr/macppc/lib are usually not acceptable input to these Power Macintosh software development tools.


8.5 Header Files

CodeBuilder includes a number of header files which declare functions, data types, values, and macros for supported languages. The C include files are ANSI compliant. Machine independent files are located in /usr/include. Files dependent on a specific target architecture are located in /usr/<target>/include; /usr/macppc/include contains the include files specific to the Power Macintosh. By default, the preprocessor cpp scans the target dependent tree before the generic tree.


8.5.1 Pre-Defined Names

The following macro names are used extensively in the MachTen CodeBuilder header and source files to conditionally include (exclude) declarations, definitions, and code which are (are not) applicable to CodeBuilder:

__MACHTEN__ defined in all CodeBuilder environments
__MACHTEN_68K__ defined when developing for the CodeBuilder 68k environment
__MACHTEN_PPC__ defined when developing for the CodeBuilder PPC environment

Definitions, declarations, and code specific to CodeBuilder should be enclosed as follows:
#ifdef __MACHTEN__
/* Code generic to any CodeBuilder environment */
#endif

#ifdef __MACHTEN_68K__
/* 68K specific code */
#endif

#ifdef __MACHTEN_PPC__
/* PPC specific code */
#endif
Similarly, definitions, declarations, and code which CodeBuilder does not support should be enclosed as follows:
#ifndef __MACHTEN__
/* Code that is inappropriate for CodeBuilder */
#endif

#ifndef __MACHTEN_68K__
/* Code that is inappropriate for the 68K */
#endif

#ifndef __MACHTEN_PPC__
/* Code that is inappropriate for the PPC */
#endif


8.6 Compiling Sources

The GNU compiler tools are standard in CodeBuilder. In general, the process of creating an object file consists of preprocessing the source with cpp, performing macro substitutions, passing the output to the appropriate backend compiler engine which generates assembly code, and giving that to as which produces the machine object file in XCOFF format. The output of each of these stages is written to a temporary disk file by default. Executable programs are creating by loading the appropriate XCOFF files and needed libraries. All or part of this activity may be orchestrated with gcc, which executes the appropriate tools in turn.

The following sections present a very brief illustration of the commands for generating object files and executables. Optimization (-O) is used in the commands which invoke the backend compiler, causing it to try to produce code that is smaller and faster. Detailed documentation is available in various formats, including man pages, HTML documents, and PDF and PostScript files. The reference materials found in the Appendices may also prove useful.


8.6.1 Ada

Compiling and loading Ada source files is similar to that for C and C++, however, it requires a binding step between compilation and loading to check consistency and elaboration order. The backend compiler engine is /usr/macppc/bin/gnat1.

Using hello.adb as an example Ada source, the following command illustrates the typical command for generating a PEF executable:
gnatmake hello
gnatmake is a master program which invokes the tools to perform necessary compilation, binding, and linking, in the proper order. Alternatively, gcc may be used to generate an object file or assembly source as shown below:
gcc -c -O hello.adb
gcc -S -O hello.adb
These commands generate the files hello.o and hello.s, respectively. Intermediate files from the compilation tools are discarded.

Detailed documentation may be found on the CodeBuilder CD as well as in Appendices A1 and A2.


8.6.2 C

C source files are compiled with gcc. A symbolic link from cc to gcc is provided for compatibility with UNIX tradition. The backend compiler engine is /usr/macppc/bin/cc1. Files with a .c suffix are assumed normal C source files, and those with .i are interpreted as previously processed by cpp and passed directly to cc1.

Using hello.c as an example C source, the following command illustrates creating the PEF executable hello from the single source file (intermediate files are discarded):
gcc -O -o hello hello.c
Sometimes, the object file is needed, or even the intermediate assembly code or preprocessor output. Again using hello.c as our example, the following commands:
gcc -O -c hello.c
gcc -O -S hello.c
gcc -E -o hello.i hello.c
generate the files hello.o, hello.s, and hello.i, respectively.


8.6.3 Objective-C

Objective-C source files are compiled with gcc. A symbolic link from cc to gcc is provided for compatibility with UNIX tradition. The backend compiler engine is /usr/macppc/bin/cc1obj. Files with a .m suffix are assumed Objective-C source files, and those with .i are interpreted as previously processed by cpp and passed directly to cc1obj.

Using hello.m and Printer.m as example Objective-C sources, the following command illustrates creating the PEF executable hello from the two source files (intermediate files are discarded):
gcc -O -o hello hello.m Printer.m -lobjc
Sometimes, the object file is needed, or even the intermediate assembly code or preprocessor output. Again using hello.c as our example, the following commands:
gcc -O -c hello.m
gcc -O -S hello.m
gcc -E -o hello.i hello.m
generate the files hello.o, hello.s, and hello.i, respectively.


8.6.4 C++

C++ source files are compiled with g++. g++ is a special wrapper program which executes gcc with options appropriate for compiling (and loading) C++ sources. The backend compiler engine is /usr/macppc/bin/cc1plus. The file suffixes .C, .cc, .cxx, .cpp, and .c++ all denote C++ source files. Files with a .ii suffix are interpreted as previously processed by cpp and are passed directly to cc1plus.

Using hello.C as an example C++ source, the following command illustrates creating the PEF executable hello from the single source file (intermediate files are discarded):
g++ -O -o hello hello.C
Sometimes, the object file is needed, or even the intermediate assembly code or preprocessor output. Again using hello.C as our example, the following commands:
g++ -O -c hello.C
g++ -O -S hello.C
g++ -E -o hello.ii hello.C
generate the files hello.o, hello.s, and hello.ii, respectively.


8.6.5 Fortran

Fortran files are compiled with g77. g77 is a special wrapper program which executes gcc with options appropriate for compiling (and loading) Fortran sources. The backend compiler engine is /usr/macppc/bin/f771. The file suffixes .F, .f, and .for all denote Fortran source files.

Using hello.F as an example Fortran source, the following command illustrates creating the PEF executable hello from the single source file (intermediate files are discarded):
g77 -O -o hello hello.F
Sometimes, the object file is needed, or even the intermediate assembly code or preprocessor output. Again using hello.F as our example, the following commands:
g77 -O -c hello.F
g77 -O -S hello.F
g77 -E -o hello.i hello.F
generate the files hello.o, hello.s, and hello.i, respectively.


8.6.6 Java

CodeBuilder comes with Kaffe, a virtual machine to execute Java bytecode. Java source files have the suffix .java.

The following environment variables must be set before using kaffe:
setenv CLASSPATH .:/usr/share/kaffe/classes.zip
setenv KAFFEHOME /usr/share/kaffe
setenv LD_LIBRARY_PATH /usr/lib
The following command illustrates compiling Java source:
javac hello.java
It generates the file hello.class, which may be loaded and executed by:
kaffe hello
Note that the argument to kaffe is the class name, not the file name.


8.7 Linking Executables

8.7.1 ld

In CodeBuilder, ld, the link editor (also known as the loader), is used to produce executables and shared libraries. It combines object files together, searches specified libraries to resolve external function and data references, and produces IBM binary standard format XCOFF files. It relies on an external program called mkpef to translate XCOFF output to Apple PEF format for use on the PowerPC. Typically, the XCOFF version of the file is deleted after the PEF file is produced. Optionally, the XCOFF file may be saved by adding the -Xlxcoff parameter to the ld execution command. The XCOFF output is stored in a file with the same name as the target PEF file, with a trailing .xcoff . For example, if the loader is producing a file called myprog, the XCOFF version of the loader's output will be put in myprog.xcoff. This program is automatically called by gcc (in the default case), so typically you will not have to execute this program or build specific rules into your Makefile structure.

Since CodeBuilder runs in real memory, stack sizing considerations enter into the development of a program. CodeBuilder provides a -Xlstack = <stackbytes> parameter that provides the ability to set aside memory for the application stack. This value has a default of 60KB, which works well for most applications. However, some applications can have stack memory requirements that approach several megabytes and need their stack parameters set accordingly. This capability is also provided by the setstackspace utility, which is discussed further in the "Stack Overrun" portion of the section "8.13.1 Real Memory Issues".


8.7.2 mkpef

The mkpef program takes the XCOFF output of the CodeBuilder loader and produces a PEF executable image. This program is automatically called by the CodeBuilder loader (in the default case), so typically you will not have to execute this program or build mkpef rules into your Makefile structure.


8.8 To make or pmake

CodeBuilder provides both the GNU (/usr/bin/make) and BSD4.4-Lite (/usr/bin/pmake) implementations of the make utility. Both implementations are in wide use, and certain software packages depend upon unique features of one or the other.

GNU Makefiles are usually self-contained and reside in the object directory. GNU software packages typically require a configuration step which determines the capabilities and features of the host system and customizes the Makefile and supporting include files accordingly.

BSD Makefiles reside in the source directory and usually define a few parameters which direct included master scripts. The master scripts, located in /usr/share/mk, define rules and default parameters for building and installing executables, libraries, include files, man pages, and support data. A symbolic link named obj is usually created to point to the directory in which object files are built.


8.9 Symbol Information

CodeBuilder application symbol information is obtained by using the nm program. Nm works with XCOFF files optionally output from the compilation of an application. Use -Xlxcoff on the compilation command line to produce XCOFF output. Files containing XCOFF information are typically named with a .xcoff suffix. The command:
nm -n afile.xcoff
will produce symbol information relative to location zero for application data and text.


8.10 Debugging

Since CodeBuilder for the Power Macintosh uses the Apple-defined PEF format for executable code objects (Code Fragments), there are a number of alternatives for debugging CodeBuilder applications on the Power Macintosh. The traditional UNIX approach for CodeBuilder is gdb, but Apple and other third party debuggers are also available and will work with CodeBuilder PEF Code Fragments.


8.10.1 Debugging Using gdb

The preferred way to debug CodeBuilder applications is with the use of the CodeBuilder gdb application. This debugger provides source and assembly level debugging, complete with data structure display, single step code execution and source code specified break point specification. Gdb requires access to both the PEF and XCOFF formats of an executable program. Using the -g command during the production of the application will automatically produce PEF and XCOFF files.

The command:
gcc -g -o hello hello.c
will produce the PEF output file hello and the XCOFF output file named hello.xcoff. Note that the optimization flag (-O) has been left out to avoid confusing matchups between source code lines and the generated assembly code.

The CodeBuilder command:
gdb hello
will start execution of the gdb application which will automatically search for both PEF and XCOFF files. Once both files are found, UNIX standard gdb commands may be given to set break points, examine data and complete the debugging process. Further information on the gdb application can be found in the gdb manual page accessed via the CodeBuilder man command.


8.10.2 Macintosh Debugging Tools

First make sure that a debugger is not already installed on your system. Typically, if the message "Debugger Installed" is printed when the system is booting, it means that some form of debugger has already been installed on your system. If you have a debugger, investigate its origins and usage. It is possible that it will provide the debugging support you need.


8.10.2.1 MacsBug

MacsBug Ýis a Macintosh debugger which offers low-level debugging support on Power Macintoshes. MacsBug 6.5.3 works with CodeBuilder, providing assembly level debugging, break points and PowerPC exception handling. It interprets traceback data attached to each CodeBuilder generated subroutine showing routine name and parameter information.

If you do not already have a debugger installed, it is recommended that you install MacsBug 6.5.3 in your System Folder. It is located in "Utilities: Development Utilities:Debuggers:MacsBug 6.5.3" on the CodeBuilder CD. It will provide you with a backup if one of your applications crashes.

Using MacsBug you can display memory as PowerPC assembler code (use a command ilp <addr>. You can set a break point with the command brp <addr>. The g command is used to resume execution of the application. The s and so commands are used to single step and single step over (steps over subroutine calls).

By using the CFM command in MacsBug when the application is executing, the absolute addresses for both data and text areas are available. The sum of the data base address from the MacsBug CFM command and the offset information from the nm command provide an absolute memory location for a variable.
Ý: ftp://ftp.info.apple.com/Apple.Support.Area/Apple.Software.Updates/US/Macintosh/Utilities/MacsBug_6.5.3.sea.hqx

8.10.2.2 The Debugger

The Debugger (commonly referred to as the "Jasik" debugger after its author, Steve Jasik), supports Macintosh style (point & click) source debugging for both 68K and PPC platforms. The Debugger consumes approximately 2MB of RAM. Check the "Utilities: Debuggers: The Debugger" folder of this distribution for more information on obtaining this product.


8.10.2.3 Macintosh Debugger for PowerPC

The Macintosh Debugger for PowerPC is Apple's symbolic debugging tool for Power Macintosh. The newest revision (2.0d3) works in a "single headed" mode, which eliminates the requirement of needing two Macintoshes to debug PPC applications. This version of the debugger consumes approximately 5MB of RAM.

Apple's documentation describes some interesting features, including source debugging directly from the XCOFF file (i.e., the debugger has the makesym function built in), a flag to enter the debugger each time an application loads a Code Fragment, a method of mapping xSYM files to these newly-loaded Code Fragments, and an ability to present and trace Thread Manager stacks (each CodeBuilder application uses a Thread Manager Thread).


8.10.2.4 Metrowerks Debugger

The Metrowerks Code Warrior software development environment includes a symbolic source code debugger for Power Macintosh applications. This debugger would be a logical choice for debugging CodeBuilder applications if the applications are also being developed using the other Code Warrior tools.


8.10.3 Environment Variables for Debugging and Monitoring

Each CodeBuilder application is run with certain preset information known as the environment. The environment is a collection of variables stored as character strings. Each string specifies the name and value of one variable. Many environment variables are set during login and when starting a new shell.

For csh and tcsh, the commands to set and unset environment variables are:
setenv variable value
unsetenv variable

For sh and bash, the commands to set and unset environment variables are:
export variable=value
unset variable
Consult the man page for your shell of choice for the complete details on setting or unsetting environment variables, and the special shell script file(s) that are processed during start-up.

The environment variables DEBUGGERFIRST, STACKCHK, and MEMSTATS direct CodeBuilder to perform special debugging or monitoring actions when they are set to a non-zero value (typically 1). Remember that environment variables set in a given process are only propagated to child processes. It is often convenient to establish one terminal window with the desired "debugging environment", and to have additional terminal windows for editing and other activities. Unset the environment variables to discontinue their service.


8.10.3.1 DEBUGGERFIRST

When set, the environment variable DEBUGGERFIRST causes CodeBuilder to execute a Debugger() MacOS system call immediately before entering the 'main' function of the application. This allows you to set initial breakpoints, and to step through initial start-up actions such as C++ constructor calls. You must have previously installed a low-level debugger, such as MacsBug, for this to work. By default, CodeBuilder will trap this Debugger call. To allow the Debugger call to pass through to the MacOS and MacsBug, or other debuggers, rename the CodeBuilder application to "CodeBuilder.noexcept" and restart CodeBuilder.


8.10.3.2 STACKCHK


When set, the environment variable STACKCHK causes CodeBuilder report (on the console terminal) the amount of stack used when a program exits. This is done by zeroing the entire stack prior to executing the program, and scanning for the "highest" non-zero stack entry when the program quits. Note that stacks grow downward from a high address to a low address.


8.10.3.3 MEMSTATS

When set, the environment variable MEMSTATS causes CodeBuilder to report memory usage statistics when a program exits. The report includes the maximum amount of memory allocated and the number of buckets in use and available. A bucket is simply a buffer whose size is a power of 2. The report also tallies the number of calls to malloc, free, realloc, alloca, and the sbrk and sfree system calls. The information may help to identify inefficient memory usage.


8.11 Making Macintosh Applications

One of the benefits of producing PEF formatted binary images is that the CodeBuilder software development tools may be used to produce Apple standard application programs. To develop Macintosh applications, the software must use standard Apple interface libraries and Apple standard interface header definition files. It must also specify a Macintosh specific startup routine providing for proper startup data definition and proper program exit and follow Apple system programming rules (e.g. WaitNextEvent, MoreMasters, etc.).


8.11.1 Macintosh OS Header Definition Files

Macintosh applications must be built with Macintosh interface header definition files for data/code typing and parameter access. CodeBuilder includes Apple's C include files in the directory /usr/include/MacOS.

A family of these files is also typically included with every native Macintosh development program under a headers directory hierarchy. Access to these files by CodeBuilder development applications requires that these files have a CodeBuilder creator of "MUMM" and a "TEXT" type designation. The simplest method of converting a family of header files is to select a whole directory and drag the group of files to the CodeBuilder Unix<->Text application, drop the group on the application is let it change each of the files. The CodeBuilder Unix<->Text application is contained in the utilities directory of the CodeBuilder distribution.

Typically MPW and other development tools do not examine the creator or type of their constituent header or shared library interface files. This means that it is possible to modify the creator and type of one copy of files and have them used by both CodeBuilder and traditional Macintosh development applications.


8.11.2 Macintosh OS Interface Libraries

To include a standard Apple interface library with CodeBuilder application development commands requires a few careful preparation steps. The file creator must be modified and, potentially, a translation must be specified from the name of the library file to the fragment name used to access the shared library by the Macintosh system.

System interface libraries are available in all standard Apple software development systems (e.g. MPW, Metrowerks), typically in a libraries hierarchy of directories. Under a libraries hierarchy, there is a set of Power Macintosh interface libraries. To incorporate one of these libraries on a CodeBuilder command line, the Macintosh creator must be modified. Generally this has no affect on access to the library by the native development software. Modifying a library creator to "MUMM" will allow CodeBuilder to access the file as a binary file. The file should already have a Macintosh type identification of shlb which is used by CodeBuilder development tools to determine whether shared access to the PEF interface library is to be reflected in the final application.

File creator and type information is available by running finderinfo(1) or ResEdit and selecting the "Get Information" function from the File menu. Creator information can be modified under ResEdit with traditional Macintosh point and click methods.

Care must be taken not to make a copy of one of the libraries using CodeBuilder applications until the creator has been changed to "MUMM". Access to a library not created by "MUMM" will automatically create an Apple single version of the copied data and make it unusable by CodeBuilder development tools.

Interface library fragment names are the names of the Code Fragments that are used by the Macintosh system to dynamically relate application programs to a shared library. Each shared library has a fragment name which is typically the same as the name of the Macintosh file containing the fragment. A shared library Code Fragment name is contained in the shared library's CFRG resource. This resource may be viewed and modified with the ResEdit application. If the file name and Code Fragment name are the same, then no further action is necessary. The CodeBuilder development tools will place a reference in the resulting PEF output to a Code Fragment named with the same name as the name of the Macintosh file containing the Code Fragment.

However, if the library name and Code Fragment name are different, a translation between the two must be specified during the PEF production phase of the CodeBuilder development tools. To specify a non-standard file name to Code Fragment name mapping the mkpef application must be run as an explicit, separate program step with a mapping specification. To prepare for a separate mkpef step, the -Xlxcoff parameter must be specified during compilation or during the CodeBuilder loading phase. The -Xlxcoff parameter preserves the XCOFF formatted output file which will be used as explicit input to the mkpef application.

The mkpef application can then be run with the command:
mkpef -lfilename:=fragmentname -creator XXXX -type shlb inputfile.xcoff outputfile

Multiple file name-to-fragment name translations can be included on the same command line. A creator of something other than "MUMM" must be specified and a type of "shlb" must also be specified for a shared library or a type "APPL" for an application. Creator types should be registered with Apple at http://www.devworld.apple.com/dev/cftype.


8.11.3 Macintosh Application Startup Routine

Standard CodeBuilder applications use a startup routine that sets up a UNIX parameter and environment variables, calls a main subroutine and, on return from main, call the UNIX standard exit system call. A standard Macintosh application has different requirements for startup preparation. The initial routine must declare a QuickDraw variable named qd, call the main application and, on return, call the Macintosh standard ExitToShell system call. A pre-compiled file conforming to Macintosh startup requirements has been included with the CodeBuilder distribution under the file name /usr/lib/MacOS/Mac_start.o. A slightly modified version that enters the Macintosh debugger first is in /usr/lib/MacOS/Mac_debug.o.


8.11.4 Macintosh Application Construction

The newly modified interface libraries and header definition files must be specified during the compilation and linkage phases of the CodeBuilder code production process. This is specified using typical UNIX standard methods. Access to a directory of header definition files is specified using the -I parameter on a UNIX command line. The command line:
gcc -O -I/usr/include/MacOS -Dpascal="" -c hello.c
will define (with -D) pascal to be nothing for MacOS compatibility, and will search the /usr/include/MacOS directory for include files. It will also use optimization as usual for a faster and more compact binary.

The command line:
ld -o /hfs/APPL/hello -Xlcreator 'MISC' -Xltype APPL \
/usr/macppc/lib/MacOS/Mac_start.o \
hello.o \
/usr/macppc/lib/MacOS/InterfaceLib.a
will create an output file hello in the /hfs/APPL folder. Note that the application must be created as an HFS file because it requires the setting of certain Macintosh resources via the MacOS Resource Manager.

The ld command includes the Macintosh application initialization code from Mac_start.o as well as the graphic user interface code from InterfaceLib.a. We must specify the full name to both of these supplementary pieces of code. Since InterfaceLib.a is a shared library, exported symbols from the library will be treated as dynamic linkages to be satisfied during the runtime execution of the application. The Xlcreator and Xltype parameters specify a "MISC" creator and a standard Macintosh application type. The resulting "point & click" Macintosh program can be executed independently of CodeBuilder.


8.12 Cross-Development Tools And Targets

The macppc component of the target path names used in the BSD4.4-Lite and GNU Makefiles is necessitated by the future use of the CodeBuilder cross-development capabilities for either the 68K or Power Macintosh, (i.e., /base/mac68k/bsd4.4 would be the target directory for building the 68K versions of the BSD4.4-Lite applications). The locations of the development tools is also dictated by the cross-development capabilities of CodeBuilder. Note that all of the "machine specific" software development tools reside in /usr/macppc/bin, the libraries in /usr/macppc/lib, and header files in /usr/macppc/include. The non-machine specific pieces are in the traditional /usr/bin, /usr/lib, and /usr/include paths. Links to the machine specific development tools are set up in the corresponding directories.


8.12.1 Default CodeBuilder Environment

CodeBuilder may be used to develop code for either the 68KÝ or PPC environment. The selection of the target in a cross-development environment is controlled by the PATH and other environment variables and symbolic links.

Since CodeBuilder provides support for PowerPC targets, this environment is established as the default. More information on specifying the target in a cross-development environment will be provided when the multiple target capability is released.

Ý: This capability is still under development and is not included with the initial release of CodeBuilder.


8.13 Porting Software to CodeBuilder

Where possible, every effort has been made in CodeBuilder to provide as complete a BSD4.4-Lite UNIX environment as possible. However due to the lack of memory protection in MacOS, CodeBuilder is a "real memory" implementation of UNIX. Therefore, it cannot possibly mimic all of the "features" of virtual memory. Most applications are oblivious to the subtle differences between running under virtual memory or real memory. These differences are documented here so the programs that do depend on virtual memory can be easily diagnosed as such, and modified to run on CodeBuilder.


8.13.1 Real Memory Issues

8.13.1.1 Stack Overrun

CodeBuilder starts each process with a fixed size stack. If a subroutine defines lots of storage on the stack (automatic data in C), this could cause stack overrun, which will almost assuredly cause the system to crash. Alternatives for large automatics are to redefine them as static, or to allocate them with malloc or alloca. The default process stack size is 36K bytes. A larger process stack size may be specified using the setstackspace utility. A larger stack may also be specified when a program is built with the -Xlstack loader option (see section "8.7 Linking Executables".)

This is probably the number one real memory issue and should be investigated first when a program is sporadically failing within CodeBuilder. For example, an application may build and run fine on small datasets but crash when using larger datasets.


8.13.1.2 Allocating Memory in CodeBuilder

CodeBuilder allocates memory for its constituent applications in two ways. When an application is loaded into the system for the first time, a Macintosh system module called the Code Fragment Manager (CFM) is used to load and manage application Code Fragments. The CFM handles allocation of memory for new fragments, relocation of internal software references within a fragment and dynamic linkage between different but related Code Fragments. Secondary memory allocations occur when a running application requests memory which can obviously occur only after an application has been properly loaded by the CFM.

The CFM uses two areas of memory to store Code Fragments - CodeBuilder application memory, known as the CodeBuilder heap, and system memory. CodeBuilder application data fragments are allocated from CodeBuilder application memory. CodeBuilder application code fragments are allocated from system memory. In addition, if virtual memory has been enabled, access to pages of code are managed on a demand paged basis so that only software that has been referenced is actually loaded into memory. This facility is called Memory Mapped files.

Once an application is under execution, the application may make subsequent requests for memory (secondary memory allocations). These requests are allocated from Macintosh system memory.
A dynamic bar chart of allocated system memory, as well as CodeBuilder and other application memory, can be displayed by selecting the "About This Macintosh" entry in the Apple menu when Finder is the front application.

Sometimes, due to heavy system loads, either CodeBuilder memory or system memory allocations will be completely exhausted. By reallocating the size of the CodeBuilder memory space, it is possible to change the relative sizes of the two allocations. See section "8.13.1.4 Setting the CodeBuilder Heap Size" for directions on how to increase the CodeBuilder memory heap.

CodeBuilder typically fails to allocate memory in two ways - the CFM fails to find sufficient memory when loading an application, or the application itself fails during a secondary memory request. Both failures print an error message. When the CFM fails to find enough memory to load an application's data, the error message is CFM error -2810. Getting this error means that the CodeBuilder memory space is fully allocated; one solution is to quit CodeBuilder, increase the CodeBuilder heap size and re-launch CodeBuilder.

When CFM fails to find enough memory to load an application's code, the error message is Frag load err -108. Getting this error means that the system memory space is fully allocated. One solution is to quit CodeBuilder, decrease the CodeBuilder heap size, and re-launch CodeBuilder.

A secondary memory allocation is a request by the running application to allocate memory. This is typically achieved via the alloc() and malloc() family of library calls. Secondary memory allocations are completely independent of the CFM memory allocations, and can occur only after an application has been successfully loaded by the CFM. Secondary memory allocations are allocated from Macintosh system memory.

When a secondary memory request fails, an error code is returned to the application and the response to a user is application specific. When a secondary request fails, the system memory space is fully allocated. Possible solutions include quitting any Macintosh applications that might also be using system memory, closing any unused Finder windows, or ultimately quitting CodeBuilder and reducing its heap allocation size. Note that by reducing the size of the CodeBuilder heap, the size of the allocatable system memory is increased, so it is possible to iterate several times around increasing or decreasing the CodeBuilder heap size to best suit a particular system's memory profile.

8.13.1.3 Calculating Memory Requirements

The Code Fragment Loader loads the code (or executable) portion of CodeBuilder applications in the System heap, and the data portion of the CodeBuilder applications in the CodeBuilder heap. Therefore, a running CodeBuilder application consumes space in both the System and CodeBuilder heaps, and it is necessary to have space available in both of these heaps in order to successfully launch CodeBuilder applications.

The "About This Macintosh" dialog box (under the Apple Menu when Finder is the front application) provides an easy means to approximate how much space is available in both the System and the CodeBuilder heaps. However, is not easy to predict how much more memory a particular CodeBuilder application will require. CodeBuilder libraries (libc, libm, etc.) are shared libraries. CodeBuilder applications that reference these libraries share a single instantiation of the library's code. The library's data segments are not shared. Each CodeBuilder application allocates a private copy of the data segments for each shared library it references. This dynamic sharing of the CodeBuilder libraries, combined with the stack and memory allocations internal to CodeBuilder programs, makes it difficult to determine how much additional memory a CodeBuilder program will consume from the CodeBuilder and System heaps.

Examining the "About This Macintosh" display both the before and after launching a CodeBuilder application provides a way to approximate memory requirements. Using MacsBug (or another debugger) to dump the exact heap statistics provides a more precise means to calculate memory usage.


8.13.1.4 Setting the CodeBuilder Heap Size

Setting the size of the CodeBuilder heap varies the sizes of the code and data allocation pools. Increasing the size of the CodeBuilder heap generally increases the size of the data allocation memory area at the expense of decreasing the code allocation size. To set the CodeBuilder heap size, make sure that CodeBuilder is not running. Next, find the CodeBuilder application icon and highlight it with a single mouse click. Then pull down and select the "Get Info" selection in the Finder File menu. If the "Get Info" selection is not selectable, the CodeBuilder icon has not been highlighted with a single click. Re-select the CodeBuilder icon and the "Get Info" selection should become selectable. This will display information about the CodeBuilder application. The lower right-hand corner of the display will contain a Suggested Size setting for CodeBuilder. Select the box and raise or lower the setting according to your systems needs. Close the display by clicking the close box. Restart CodeBuilder and verify the new size by opening the dynamic memory display by double clicking the "About this Macintosh" in the Finder Apple Menu.


8.13.1.5 Problem Areas

Not having virtual memory means that programs deal with physical addresses and have limited available memory and a limited stack. The following real memory problems are known to exist:


etext, edata, end
In a virtual memory environment, programs can make assumptions about the relative locations of the programs text, data, and bss sections. In real memory these assumptions simply are not valid. Programs using the symbols etext, edata, and end probably require modifications to not depend on the relative locations of these symbols.
sbrk
Some programs that call sbrk() make the assumption that each successive call to sbrk will return memory addresses contiguous to the previous call. This is not possible to support in a "real memory" environment, thus these programs require modifications to work with CodeBuilder. In CodeBuilder, sbrk translates into a heap-oriented memory allocation call.
page boundary
Typical virtual memory implementations allocate memory on page boundaries, thus requests to allocate less than some minimum amount actually allocate this minimum. Some programs may accidentally depend on this by accessing past the minimum memory length requested, without causing problems. In a real memory implementation, memory is a scarce resource, and memory requests are typically rounded to a much smaller size, like a multiple of 16 or 32 bytes. Accidentally accessing past this real memory boundary will most certainly cause problems to the actual owner of this space.
out of memory during compile
Both the C compiler (gcc and cc1) and the make program (make) require a lot of memory to run. If you are compiling large files and have an elaborate program generation environment built up where a Makefile causes multiple copies of make to run at the same time, this will require large amounts of memory and may cause either the C compiler or make to fail during some memory allocation request, aborting the program generation. A potential solution to this problem is to use some of make's more sophisticated features, such as VPATH, and to reorganize the program generation process to be completely controlled from one or two make invocations.
fragmentation
In a real memory situation it is possibly to fragment memory in such a way that, although the total free memory is sufficient to satisfy a particular allocation request, none of the individual memory pieces is big enough to satisfy the request. This situation can be aggravated by use of the realloc() call, with successively larger sizes. Quitting, and then restarting CodeBuilder will solve this.
sticky bits
The compilers, cc1, cc1plus, f771, cclobs, and gnat1 are installed with the "sticky bit" set. This causes them to remain in memory once they are used until CodeBuilder quits. This speeds execution, but may reserve too much memory if you are using multiple languages and have limited memory. Removing the sticky bit will cause the programs to be loaded into memory each time they are used. This may be done as root by:
chmod 555 /usr/macppc/bin/filename.



8.14 Programming Example

8.14.1 Rogue

BSD4.4-Lite includes a number of games, some of which have a long history in the UNIX world. This example uses the game rogue as an example for software development for the Power Macintosh using CodeBuilder.


8.14.2 Building the Executable

First it is necessary to build the executable binary image for the rogue program. The Makefile has already been set up for the CodeBuilder environment, so you need only to execute the few steps below. (You should examine the Makefile for the details.)
cd /base/src/bsd4.4/games/rogue
pmake objdir
pmake
The first pmake command creates the directory that the symbolic link obj points to if it does not already exist; in this example it is /base/macppc/bsd4.4/games/rogue. This is the directory in which the objects and executable will be generated.


8.14.3 Debugging Using MacsBug or Other Macintosh Debuggers

The rogue sources have been modified to include a call to enter a Macintosh debugger. This Debugger() call is contained within an #ifdef DEBUG conditional, so this call is only made if the compile options include the -DDEBUG flag (pmake COPTS=-DDEBUG). The Debugger() library call has been added to libc. When this call is made, control is passed to the debugger and the debugger indicates that the next instruction to be executed is the first line after the Debugger() library call.

If you do not have a Power Macintosh debugger installed, do not use the Debugger() library call. It would result in a program error (unknown trap), and would cause CodeBuilder to quit executing. In order to pass this Debugger call through to the MacOS, rename the CodeBuilder application to "CodeBuilder.noexcept" and restart CodeBuilder.




[ Top of Page ][ 9.0 The X Window System ][ Table of Contents ]