Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Read Me About MachPortDump.txt
Read Me About MachPortDump |
========================== |
1.1 |
This sample dumps out the Mach port name space of a process. It is designed to be used as a tool by developers who are writing inter-process communication code on Mac OS X. Typically this code is based on Mach ports, or some higher-level wrapper around Mach ports. You can run this sample to check to see whether your code leaks ports. |
MachPortDump should be compatible with any versions of Mac OS X. It was built and tested on Mac OS X 10.4.x with Xcode 2.1. |
Packing List |
------------ |
The sample contains the following items: |
o Read Me About MachPortDump.txt -- This file. |
o MachPortDump.c -- C source code for the program. |
o MachPortDump.xcodeproj -- An Xcode 2.1 project for the program. |
o MachPortDump.xcode -- An Xcode 1.5 project for the program. |
o build -- A folder containing a built universal binary. |
Using the Sample |
---------------- |
To test the sample, you should change into the directory containing the pre-built executable. |
$ cd Desktop/MachPortDump/build/Development |
$ ls -lh |
total 24 |
-rwxr-xr-x 1 quinn staff 9K 1 Nov 13:30 MachPortDump |
If you run the program with the "-?" argument, you get usage. |
$ ./MachPortDump -? |
usage: MachPortDump [options] [ [ pid | name ]... ] |
Send, Receive, SendOnce, PortSet, DeadName = right reference counts |
DNR = dead name request |
-w wide output, with lots of extra info |
flg = N (no senders) P (port dead) S (send rights) |
seqno = sequence number |
mscount = make-send count |
qlimit = queue limit |
msgcount = message count |
sorights = send-once right count |
pset = port set count |
If you run the program with no arguments, it prints out a dump of its own Mach port name space. |
$ ./MachPortDump |
Name Send Receive SendOnce PortSet DeadName DNR |
---- ---- ------- -------- ------- -------- --- |
0x107 1 |
0x213 1 |
0x307 4 |
0x40b 2 |
0x50b 1 |
0x60b 1 |
0x707 1 |
0x80b 2 |
0x907 3 |
0xa03 1 |
0xc03 1 |
Each row represents a Mach port right name (that is, the small integer value used by the program as a 'handle' to the port right). Each column represents a count of the number of times that the name references a particular right. For example, in the above listing, the name 0x307 holds 4 send right references for a port, while the name 0xc03 holds a single receive right for a port. |
If you supply a process as an argument (either via PID or name), MachPortDump prints the name space for that process. |
$ ./MachPortDump Finder |
Mach ports for 'Finder' (385): |
Name Send Receive SendOnce PortSet DeadName DNR |
---- ---- ------- -------- ------- -------- --- |
0x107 1 |
0x207 1 |
0x313 1 |
0x40b 12 |
0x507 2 |
0x60f 1 |
0x707 1 |
0x807 1 |
0x90b 4128 |
0xa07 7 |
0xb07 1 |
0xc03 1 |
0xd03 1 |
0xe03 1 |
0xf03 1 yes |
0x1003 1 |
0x1103 48957 1 |
0x1203 1 |
[...] |
0xd833 1 1 |
0xd96b 1 |
0xda17 1 1 |
[...] |
In this example you can see that the Finder holds references to many Mach port rights, including a reference to a port set (0x1203) and a send-once right (0xd96b). Also note that some names (for example, 0xd833) can reference more than one type of right. Finally, note that Finder holds 48957 references to a particular send right (0x1103), which is probably a bug. I'll discuss this in more depth below. |
If you supply the "-w" flag, MachPortDump prints a bunch of extra information. |
$ ./MachPortDump -w Finder |
[...] |
I've not included any output because it's too wide to view meaningfully in a standard text document. You might want to pipe the output to a text editor with soft word wrap turned off. |
$ ./MachPortDump -w Finder | bbedit |
[...] |
Bug Hunting with MachPortDump |
----------------------------- |
If you program with Mach directly, or even if you only use high-level wrappers, it's quite easy to accidentally leak Mach port rights. MachPortDump can help you find those leaks. |
1. You can run MachPortDump against your program to see if any of the port rights have an excessive reference count. For example, the right with 48957 references in the Finder (shown above) is very likely to be a bug. |
2. You can run MachPortDump, capture its output, perform some operation, then run MachPortDump again, and compare its output to the original. If any new names exist, or any rights have an increased reference count, you should investigate why. |
3. It might make sense for you to copy chunks of MachPortDump into your own program to implement an automatic debugging facility. If you plan to do this, read the "Caveats" section (below) before proceeding. |
While debugging with MachPortDump, remember that many system services are based on top of Mach ports. Thus, if you notice a port right 'leak', it may be a leak of some other object. For example, in the System Configuration framework, the SCDynamicStoreRef object contains a reference to a Mach port; if you notice a Mach port leak, it might be that you're actually leaking a SCDynamicStoreRef. |
Building the Sample |
------------------- |
The sample was built using Xcode 2.1 on Mac OS X 10.4. You should be able to just open the project and choose Build from the Build menu. This will build the MachPortDump tool in the "build" directory. |
How it Works |
------------ |
Fundamentally this program relies on three Mach routines to do its job. |
o task_for_pid maps a BSD process ID (PID) to a send right for the controlling task port for the associated Mach task |
o mach_port_names returns a snapshot of a Mach task's port name space |
o mach_port_get_refs gets the reference count for a particular right |
These routines are all public Mach routines, although see the following section for critical information about the Mach API on Mac OS X. |
Caveats |
------- |
Apple strongly recommends that developers avoid using Mach APIs directly. Mach APIs represent the lowest-level interface to the kernel, and thus they are the most likely to change (or become unsupportable) as the kernel evolves. |
Apple strongly recommends that developers use high-level wrappers around Mach APIs where possible. For example, rather than use Mach messages directly, you could use CFMessagePort. You should only use Mach APIs if there is no higher-level alternatively. |
This sample uses Mach APIs directly, and thus seems to violate the above recommendations. However, this is justified by the last sentence of the previous paragraph: the job this sample does, displaying information about a Mach task's port right name space, is only possible via the use of Mach APIs. |
It might make sense for you to copy the techniques used by MachPortDump into your application, to help detect port right leaks and so on. However, I strongly recommend that you include this code only in your debug build. |
Credits and Version History |
--------------------------- |
If you find any problems with this sample, mail <dts@apple.com> and I'll try to fix them up. |
1.0 (Nov 2004) was the first shipping version. |
1.1 (Jul 2005) was updated to include an Xcode 2.1 project to produce universal binaries; there were no code changes required for it to run correctly on the Developer Transition Systems. |
Share and Enjoy. |
Apple Developer Technical Support |
Networking, Communications, Hardware |
20 Jul 2005 |
$Log: Read\040Me\040About\040MachPortDump.txt,v $ |
Revision 1.3 2005/07/20 15:00:44 eskimo1 |
Updated to describe version 1.1 changes. |
Revision 1.2 2004/11/12 16:23:29 eskimo1 |
Added a missing "be". |
Revision 1.1.1.1 2004/11/01 14:47:10 eskimo1 |
First Imported. |
Copyright © 2005 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2005-08-10