B.5 Using Linux as a Mac OS X Kernel-Debugging Host

In this section, I will detail the steps I performed to prepare a Linux system as a debugging host for the Mac OS X kernel:

Because Apple’s GNU Debugger (gdb) version that I used needs a GNU C Compiler (gcc) less than version 3 to build correctly, I downloaded and installed an ancient Red Hat 7.3 Linux system.[95] To install the Red Hat system, I chose the installation type Custom. When I was asked to select the packages to install (Package Group Selection), I chose only the packages Network Support and Software Development, as well as OpenSSH server from the individual package selection. These packages include all the necessary development tools and libraries to build Apple’s gdb under Linux. During the installation, I added an unprivileged user called tk with a home directory under /home/tk.

After I had successfully installed the Linux host, I downloaded the following software packages:

After I downloaded the necessary software packages onto the Linux host, I unpacked the two versions of gdb:

linux$ tar xvzf gdb-292.tar.gz
linux$ tar xvzf gdb-5.3.tar.gz

Then I replaced the mmalloc directory of Apple’s source tree with the one from GNU gdb:

linux$ mv gdb-292/src/mmalloc gdb-292/src/old_mmalloc
linux$ cp -R gdb-5.3/mmalloc gdb-292/src/

I applied the patch to Apple’s gdb version:

linux$ cd gdb-292/src/
linux$ patch -p2 < ../../osx_gdb.patch
patching file gdb/doc/stabs.texinfo
patching file gdb/fix-and-continue.c
patching file gdb/mach-defs.h
patching file gdb/macosx/macosx-nat-dyld.h
patching file gdb/mi/mi-cmd-stack.c

I used the following commands to build the necessary libraries:

linux$ su
Password:

linux# pwd
/home/tk/gdb-292/src

linux# cd readline
linux# ./configure; make

linux# cd ../bfd
linux# ./configure --target=i386-apple-darwin
 --program-suffix=_osx; make;make install

linux# cd ../mmalloc
linux# ./configure; make; make install

linux# cd ../intl
linux# ./configure; make; make install

linux# cd ../libiberty
linux# ./configure; make; make install

linux# cd ../opcodes
linux# ./configure --target=i386-apple-darwin --program
-suffix=_osx; make;make install

To build the debugger itself, I needed to copy some header files from the XNU kernel source code to the include directory of the Linux host:

linux# cd /home/tk
linux# tar -zxvf xnu-792.13.8.tar.gz
linux# cp -R xnu-792.13.8/osfmk/i386/ /usr/include/
linux# cp -R xnu-792.13.8/bsd/i386/ /usr/include/
cp: overwrite `/usr/include/i386/Makefile'? y
cp: overwrite `/usr/include/i386/endian.h'? y
cp: overwrite `/usr/include/i386/exec.h'? y
cp: overwrite `/usr/include/i386/setjmp.h'? y
linux# cp -R xnu-792.13.8/osfmk/mach /usr/include/

I then commented some typedefs in the new _types.h file to avoid compile-time conflicts (see line 39, lines 43 to 49, and lines 78 to 81):

linux# vi +38 /usr/include/i386/_types.h
[..]
     38 #ifdef __GNUC__
     39 // typedef __signed char           __int8_t;
     40 #else   /* !__GNUC__ */
     41 typedef char                    __int8_t;
     42 #endif  /* !__GNUC__ */
     43 // typedef unsigned char           __uint8_t;
     44 // typedef short                   __int16_t;
     45 // typedef unsigned short          __uint16_t;
     46 // typedef int                     __int32_t;
     47 // typedef unsigned int            __uint32_t;
     48 // typedef long long               __int64_t;
     49 // typedef unsigned long long      __uint64_t;
     ..
     78 //typedef union {
     79 //      char            __mbstate8[128];
     80 //      long long       _mbstateL;                      /* for alignment */
     81 //} __mbstate_t;
[..]

I added a new include to the file /home/tk/gdb-292/src/gdb/macosx/i386-macosx-tdep.c (see line 24):

linux# vi +24 /home/tk/gdb-292/src/gdb/macosx/i386-macosx-tdep.c
[..]
     24 #include <string.h>
     25 #include "defs.h"
     26 #include "frame.h"
     27 #include "inferior.h"
[..]

Finally, I compiled the debugger with the following commands:

linux# cd gdb-292/src/gdb/
linux# ./configure --target=i386-apple-darwin --program-suffix=_osx --disable-gdbtk
linux# make; make install

After the compilation completed, I ran the new debugger as root so that the necessary directories could be created under /usr/local/bin/:

linux# cd /home/tk
linux# gdb_osx -q
(gdb) quit

After that, the debugger was ready.

I unpacked the downloaded Kernel Debug Kit disk image file (dmg) under Mac OS X, transferred the files per scp to the Linux host, and named the directory KernelDebugKit_10.4.8. I also copied the XNU source code into the search path of the debugger:

linux# mkdir /SourceCache
linux# mkdir /SourceCache/xnu
linux# mv xnu-792.13.8 /SourceCache/xnu/

In Chapter 7, I described how the newly built kernel debugger can be used to connect to a Mac OS X machine.

[91]

[92]

[93]

[94]

[95]

[96]

[97]

[98]

[99]



[91] See the Solaris Modular Debugger Guide at http://dlc.sun.com/osol/docs/content/MODDEBUG/moddebug.html.

[96] Apple’s custom gdb version can be downloaded at http://www.opensource.apple.com/tarballs/gdb/gdb-292.tar.gz.

[97] The standard gdb version from GNU can be downloaded at http://ftp.gnu.org/pub/gnu/gdb/gdb-5.3.tar.gz.

[98] The patch for Apple’s GNU debugger is available at http://www.trapkit.de/books/bhd/osx_gdb.patch.

[99] The XNU version 792.13.8 can be downloaded at http://www.opensource.apple.com/tarballs/xnu/xnu-792.13.8.tar.gz.