]> git.saurik.com Git - apple/system_cmds.git/commitdiff
system_cmds-670.1.2.tar.gz os-x-1011 os-x-10111 v670.1.2
authorApple <opensource@apple.com>
Fri, 4 Sep 2015 17:35:54 +0000 (17:35 +0000)
committerApple <opensource@apple.com>
Fri, 4 Sep 2015 17:35:54 +0000 (17:35 +0000)
20 files changed:
dynamic_pager.tproj/generate_plist.sh [new file with mode: 0644]
fs_usage.tproj/fs_usage.c
getty.tproj/com.apple.getty.plist
getty.tproj/generate_plist.sh [new file with mode: 0644]
iostat.tproj/iostat.c
kpgo.tproj/kpgo.c [new file with mode: 0644]
lskq.tproj/common.h [new file with mode: 0644]
lskq.tproj/lskq.1 [new file with mode: 0644]
lskq.tproj/lskq.c [new file with mode: 0644]
lsmp.tproj/entitlements.plist
lsmp.tproj/port_details.c
lsmp.tproj/task_details.c
nvram.tproj/nvram.c
system_cmds.xcodeproj/project.pbxproj
trace.tproj/trace.1
trace.tproj/trace.c
zic.tproj/generate_zoneinfo.sh
zic.tproj/install_zoneinfo.sh
zprint.tproj/entitlements.plist [new file with mode: 0644]
zprint.tproj/zprint.c

diff --git a/dynamic_pager.tproj/generate_plist.sh b/dynamic_pager.tproj/generate_plist.sh
new file mode 100644 (file)
index 0000000..288f045
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/sh
+set -e
+set -x
+
+cp "${SCRIPT_INPUT_FILE_0}" "${SCRIPT_OUTPUT_FILE_0}"
+case "$PLATFORM_NAME" in
+iphone*|appletv*|watch*)
+    /usr/libexec/PlistBuddy -c "Add :LaunchOnlyOnce bool true" "${SCRIPT_OUTPUT_FILE_0}"
+    ;;
+macosx)
+    ;;
+*)
+    echo "Unsupported platform: $PLATFORM_NAME"
+    exit 1
+    ;;
+esac
index 0590569bda32b9ad590ff2b07dbb32d2c307adfa..83b1fda8588656d17b25838b5db125ee01cc9adb 100644 (file)
@@ -89,8 +89,9 @@ typedef struct LibraryRange {
        uint64_t e_address;
 } LibraryRange;
 
-LibraryRange framework32;
-LibraryRange framework64;
+LibraryRange framework32 = {0,0};
+LibraryRange framework64 = {0,0};
+LibraryRange framework64h = {0,0};
 
 
 #define        TEXT_R          0
@@ -225,6 +226,7 @@ int  need_new_map = 1;
 int  bias_secs = 0;
 long last_time;
 int  wideflag = 0;
+int  include_waited_flag = 0;
 int  columns = 0;
 
 int  one_good_pid = 0;    /* Used to fail gracefully when bad pids given */
@@ -720,6 +722,7 @@ int         quit();
 #define FMT_CHMODAT    44
 #define FMT_OPENAT  45
 #define FMT_RENAMEAT   46
+#define FMT_IOCTL_SYNCCACHE 47
 
 #define MAX_BSD_SYSCALL        526
 
@@ -2162,9 +2165,9 @@ main(argc, argv)
                        myname++;
        }
        
-       while ((ch = getopt(argc, argv, "bewf:R:S:E:t:")) != EOF) {
+       while ((ch = getopt(argc, argv, "bewf:R:S:E:t:W")) != EOF) {
 
-               switch(ch) {
+               switch(ch) {
 
                 case 'e':
                    exclude_pids = 1;
@@ -2177,6 +2180,10 @@ main(argc, argv)
                            columns = MAX_WIDE_MODE_COLS;
                    break;
 
+                       case 'W':
+                               include_waited_flag = 1;
+                               break;
+
               case 'f':
                   if (!strcmp(optarg, "network"))
                           filter_mode |= NETWORK_FILTER;
@@ -2280,6 +2287,7 @@ main(argc, argv)
                /* set up signal handlers */
                signal(SIGINT, leave);
                signal(SIGQUIT, leave);
+               signal(SIGPIPE, leave);
 
                sigaction(SIGHUP, (struct sigaction *)NULL, &osa);
 
@@ -2302,12 +2310,12 @@ main(argc, argv)
        if ((my_buffer = malloc(num_events * sizeof(kd_buf))) == (char *)0)
                quit("can't allocate memory for tracing info\n");
 
-       if (ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_i386.map", &framework32, "/var/db/dyld/dyld_shared_cache_i386")) {
-               ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_x86_64.map", &framework64, "/var/db/dyld/dyld_shared_cache_x86_64");
-       } else {
-               ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_ppc.map", &framework32, "/var/db/dyld/dyld_shared_cache_ppc");
-               ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_ppc64.map", &framework64, "/var/db/dyld/dyld_shared_cache_ppc64");
-       }
+    ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_i386.map", &framework32, "/var/db/dyld/dyld_shared_cache_i386");
+
+    if (0 == ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_x86_64h.map", &framework64h, "/var/db/dyld/dyld_shared_cache_x86_64h")){
+        ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_x86_64.map", &framework64, "/var/db/dyld/dyld_shared_cache_x86_64");
+    }
+
        SortFrameworkAddresses();
 
         cache_disk_names();
@@ -2440,7 +2448,9 @@ set_filter(void)
 
        setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_MACH,DBG_MACH_EXCP_SC)); //0x010c
        setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_MACH,DBG_MACH_VM)); //0x0130
-       setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_MACH,DBG_MACH_SCHED)); //0x0140
+
+       if (include_waited_flag)
+               setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_MACH,DBG_MACH_SCHED)); //0x0140
 
        setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_FSYSTEM,DBG_FSRW)); //0x0301
        setbit(type_filter_bitmap, ENCODE_CSC_LOW(DBG_FSYSTEM,DBG_DKRW)); //0x0302
@@ -2944,9 +2954,11 @@ sample_sc()
 
                case SPEC_ioctl:
                     if (kd[i].arg2 == DKIOCSYNCHRONIZECACHE)
-                            exit_event("IOCTL", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_IOCTL_SYNC, (double)now);
+                            exit_event("IOCTL", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_IOCTL_SYNCCACHE, (double)now);
                     else if (kd[i].arg2 == DKIOCUNMAP)
                             exit_event("IOCTL", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_IOCTL_UNMAP, (double)now);
+                    else if (kd[i].arg2 == DKIOCSYNCHRONIZE && (debugid & DBG_FUNC_ALL) == DBG_FUNC_NONE)
+                            exit_event("IOCTL", thread, type, kd[i].arg1, kd[i].arg2, kd[i].arg3, 0, FMT_IOCTL_SYNC, (double)now);
                     else {
                             if ((ti = find_event(thread, type)))
                                     delete_event(ti);
@@ -3327,6 +3339,10 @@ format_print(struct th_info *ti, char *sc_name, uintptr_t thread, int type, uint
 
        command_name = "";
 
+       // <rdar://problem/19852325> Filter out WindowServer/xcpm iocts in fs_usage
+       if (format == FMT_IOCTL && ti->arg2 == 0xc030581d)
+               return;
+
        if (RAW_flag) {
                l_usecs = (long long)((now - bias_now) / divisor);
 
@@ -3738,6 +3754,16 @@ format_print(struct th_info *ti, char *sc_name, uintptr_t thread, int type, uint
                      }
 
                      case FMT_IOCTL_SYNC:
+                     {
+                       /*
+                        * ioctl
+                        */
+                       clen += printf(" <DKIOCSYNCHRONIZE>  B=%d /dev/%s", arg3, find_disk_name(arg1));
+
+                       break;
+                     }
+
+                     case FMT_IOCTL_SYNCCACHE:
                      {
                        /*
                         * ioctl
@@ -4819,7 +4845,8 @@ lookup_name(uint64_t user_addr, char **type, char **name)
        if (numFrameworks) {
 
                if ((user_addr >= framework32.b_address && user_addr < framework32.e_address) ||
-                   (user_addr >= framework64.b_address && user_addr < framework64.e_address)) {
+            (user_addr >= framework64.b_address && user_addr < framework64.e_address) ||
+            (user_addr >= framework64h.b_address && user_addr < framework64h.e_address)) {
                              
                        start = 0;
                        last  = numFrameworks;
index d8cb902e73501efff9b6c185bc8176dddd46cec5..45b748ff7b76eb9cab914ebc76f2b9a38e88bd35 100644 (file)
@@ -2,6 +2,10 @@
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
+       <key>EnablePressuredExit</key>
+       <false/>
+       <key>EnableTransactions</key>
+       <false/>
        <key>KeepAlive</key>
        <true/>
        <key>Label</key>
diff --git a/getty.tproj/generate_plist.sh b/getty.tproj/generate_plist.sh
new file mode 100644 (file)
index 0000000..2170bc9
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/sh
+set -e
+set -x
+
+cp "${SCRIPT_INPUT_FILE_0}" "${SCRIPT_OUTPUT_FILE_0}"
+case "$PLATFORM_NAME" in
+iphone*|appletv*|watch*)
+    ;;
+macosx)
+    /usr/libexec/PlistBuddy -c "Add :Disabled bool true" "${SCRIPT_OUTPUT_FILE_0}"
+    ;;
+*)
+    echo "Unsupported platform: $PLATFORM_NAME"
+    exit 1
+    ;;
+esac
index 643df3dfdf26b29e3cf51442dc6113dd3788da8e..a3460538a801a24158c19f057bd5f37c52632bb4 100644 (file)
@@ -972,6 +972,12 @@ record_device(io_registry_entry_t drive)
                else
                        errx(1, "device does not have a preferred block size");
 
+               // radar:18700383
+               if (drivestat[num_devices].blocksize == 0) {
+                       warnx("%s claims a blocksize of 0; defaulting to 512. Its statistics may be inaccurate.", drivestat[num_devices].name);
+                       drivestat[num_devices].blocksize = 512;
+               }
+
                /* clean up, return success */
                CFRelease(properties);
                num_devices++;
diff --git a/kpgo.tproj/kpgo.c b/kpgo.tproj/kpgo.c
new file mode 100644 (file)
index 0000000..0b439cf
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2014 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+#include <sys/pgo.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static void usage(char **argv)
+{
+       fprintf (stderr, "usage: %s [-H] [-m] [-w] [uuid] >datafile\n", argv[0]);
+        fprintf (stderr, "    uuid : the UUID of a kext\n");
+        fprintf (stderr, "    -H   : grab data for the HIB segment\n");
+        fprintf (stderr, "    -w   : wait for the kext to be unloaded\n");
+        fprintf (stderr, "    -m   : request metadata\n");
+       exit(1);
+}
+
+int main(int argc, char **argv)
+{
+       int flags = 0;
+        int data_flags = 0;
+        uuid_t *uuidp = NULL;
+        uuid_t uuid;
+        int c;
+
+        while ((c = getopt(argc, argv, "hHwm")) != EOF) {
+            switch(c) {
+            case 'H':
+                flags |= PGO_HIB;
+                break;
+            case 'm':
+                flags |= PGO_METADATA;
+                break;
+            case 'w':
+                data_flags |= PGO_WAIT_FOR_UNLOAD;
+                break;
+            case '?':
+            case 'h':
+            default:
+                usage(argv);
+                break;
+            }
+        }
+
+        if (optind < argc)
+        {
+            if (optind == argc - 1 &&
+                0 == uuid_parse(argv[optind], uuid))
+            {
+                uuidp = &uuid;
+            } else {
+                usage(argv);
+            }
+        }
+
+       ssize_t size = grab_pgo_data(uuidp, flags, NULL, 0);
+
+       if (size < 0)
+       {
+               perror("grab_pgo_data");
+               return 1;
+       }
+
+
+       fprintf (stderr, "size = %ld\n", (long) size);
+
+       unsigned char *buffer = valloc(size);
+       if (!buffer)
+       {
+               perror("valloc");
+               return 1;
+       }
+
+       ssize_t r = grab_pgo_data(uuidp, flags | data_flags, buffer, size);
+
+
+       if (r < 0)
+       {
+               perror("grab_pgo_data");
+               return 1;
+       }
+
+        if (isatty(STDOUT_FILENO)) {
+            fprintf (stderr, "%s: refusing to write binary data to a tty!\n", argv[0]);
+            return 1;
+        }
+
+        while (size > 0) {
+            errno = 0;
+            r = write(STDOUT_FILENO, buffer, size);
+            if (r > 0) {
+                buffer += r;
+                size -= r;
+            } else {
+                perror ("write");
+                return 1;
+            }
+        }
+
+       return 0;
+
+}
diff --git a/lskq.tproj/common.h b/lskq.tproj/common.h
new file mode 100644 (file)
index 0000000..eb694f6
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2015 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _LSKQ_COMMON_H_
+#define _LSKQ_COMMON_H_
+
+/*
+ * This file must be kept in sync with xnu headers
+ */
+
+/*
+ * bsd/sys/event.h
+ */
+#define KN_ACTIVE     0x01
+#define KN_QUEUED     0x02
+#define KN_DISABLED   0x04
+#define KN_STAYQUEUED 0x40
+
+
+/*
+ * bsd/sys/eventvar.h
+ */
+#define KQ_SEL        0x01
+#define KQ_SLEEP      0x02
+#define KQ_KEV32      0x08
+#define KQ_KEV64      0x10
+#define KQ_KEV_QOS    0x20
+
+/*
+ * bsd/sys/signal.h
+ */
+static const char *
+sig_strs[] = {
+       [0]  = "<UNKN>",
+       [1]  = "SIGHUP",
+       [2]  = "SIGINT",
+       [3]  = "SIGQUIT",
+       [4]  = "SIGILL",
+       [5]  = "SIGTRAP",
+       [6]  = "SIGABRT",
+       [7]  = "SIGEMT",
+       [8]  = "SIGFPE",
+       [9]  = "SIGKILL",
+       [10] = "SIGBUS",
+       [11] = "SIGSEGV",
+       [12] = "SIGSYS",
+       [13] = "SIGPIPE",
+       [14] = "SIGALRM",
+       [15] = "SIGTERM",
+       [16] = "SIGURG",
+       [17] = "SIGSTOP",
+       [18] = "SIGTSTP",
+       [19] = "SIGCONT",
+       [20] = "SIGCHLD",
+       [21] = "SIGTTIN",
+       [22] = "SIGTTOU",
+       [23] = "SIGIO",
+       [24] = "SIGXCPU",
+       [25] = "SIGXFSZ",
+       [26] = "SIGVTALRM",
+       [27] = "SIGPROF",
+       [28] = "SIGWINCH",
+       [29] = "SIGINFO",
+       [30] = "SIGUSR1",
+       [31] = "SIGUSR2"
+};
+
+/*
+ * bsd/sys/event.h: EVFILT_*
+ */
+static const char *
+filt_strs[] = {
+       NULL,
+       "READ",
+       "WRITE",
+       "AIO",
+       "VNODE",
+       "PROC",
+       "SIGNAL",
+       "TIMER",
+       "MACHPORT",
+       "FS",
+       "USER",
+       "<inval>",
+       "VM",
+       "SOCK",
+       "MEMSTATUS",
+};
+
+/*
+ * bsd/sys/proc_info.h: PROX_FDTYPE_*
+ */
+static const char *
+fdtype_strs[] = {
+       "ATALK",
+       "VNODE",
+       "SOCKET",
+       "PSHM",
+       "PSEM",
+       "KQUEUE",
+       "PIPE",
+       "FSEVENTS",
+};
+
+#endif /* _LSKQ_COMMON_H_ */
diff --git a/lskq.tproj/lskq.1 b/lskq.tproj/lskq.1
new file mode 100644 (file)
index 0000000..3660a3a
--- /dev/null
@@ -0,0 +1,176 @@
+.\" Copyright (c) 2015, Apple Inc.  All rights reserved.
+.\"
+.Dd Apr 20, 2015
+.Dt lskq 1
+.Os "Mac OS X"
+.Sh NAME
+.Nm lskq
+.Nd display process kqueue state
+.Sh SYNOPSIS
+.Nm lskq
+.Op Fl vhe
+.Op Fl p Ar <pid> | Fl a
+.Sh DESCRIPTION
+The
+.Nm lskq
+command enumerates kqueues and registered kevents of running processes.
+.Sh OPTIONS
+.Pp
+.Bl -tag -width xxx
+.It Fl p Ar <pid>
+Show kqueues of process
+.Ar <pid> .
+.It Fl a
+Show kqueues for all running processes. Requires root.
+.It Fl v
+Verbose: show opaque user data and filter-specific extension fields.
+.It Fl e
+Ignore empty kqueues.
+.It Fl h
+Show help and exit.
+.El
+.Sh OUTPUT
+.Nm lskq
+prints one line of output for each registered kevent, consisting of process,
+kqueue, and kevent information. For kqueues with no registered kevents, a single
+line is output with an ident of `-'. See
+.Xr kevent 2
+for field semantics. The output columns are:
+.Bl -tag -width xxxxxxxxxxxx
+.It command
+shortened process name.
+.It pid
+process identifier.
+.It kq
+file descriptor corresponding to kqueue, or ``wq'' for the special workq kqueue.
+.It kqst
+kqueue status bitmask.
+.Bl -tag -width xxxxxxx -compact
+.It Sy k
+kqueue is in a
+.Fn kevent*
+wait set (KQ_SLEEP).
+.It Sy s
+kqueue is in a
+.Fn select
+wait set (KQ_SEL).
+.It Sy 3 6 q
+Type of kevents on this kqueue: KEV32, KEV64, or KEV_QOS.
+.El
+.It ident
+kevent identifier. The meaning depends on the kevent filter specified. Where
+possible,
+.Nm lskq
+prints both numeric and symbolic names.
+.It filter
+kevent filter type (EVFILT_*).
+.It fdtype
+file descriptor type, for filters operating on file descriptors.
+.It fflags
+kevent filter flags bitmask. The meaning of each field depends on the filter type.
+.Bl -tag -width xxxxxxx -compact
+.Pp
+.It EVFILT_READ:
+.It Sy l
+NOTE_LOWAT
+.Pp
+.It EVFILT_MACHPORT:
+.It Sy r
+MACH_RCV_MSG
+.Pp
+.It EVFILT_VNODE:
+.It Sy d
+NOTE_DELETE
+.It Sy w
+NOTE_WRITE
+.It Sy e
+NOTE_EXTEND
+.It Sy a
+NOTE_ATTRIB
+.It Sy l
+NOTE_LINK
+.It Sy r
+NOTE_RENAME
+.It Sy v
+NOTE_REVOKE
+.Pp
+.It EVFILT_PROC:
+.It Sy x
+NOTE_EXIT
+.It Sy t
+NOTE_EXITSTATUS
+.It Sy f
+NOTE_FORK
+.It Sy e
+NOTE_EXEC
+.It Sy s
+NOTE_SIGNAL
+.It Sy r
+NOTE_REAP
+.Pp
+.It EVFILT_TIMER:
+.It Sy s u n
+NOTE_SECONDS, NOTE_USECONDS, NOTE_NSECONDS
+.It Sy a
+NOTE_ABSOLUTE
+.It Sy c
+NOTE_CRITICAL
+.It Sy b
+NOTE_BACKGROUND
+.It Sy l
+NOTE_LEEWAY
+.El
+.It flags
+kevent generic flags bitmask.
+.Bl -tag -width xxxxxxx -compact
+.It Sy a
+EV_ADD
+.It Sy n
+EV_ENABLE
+.It Sy d
+EV_DISABLE
+.It Sy x
+EV_DELETE
+.It Sy r
+EV_RECEIPT
+.It Sy 1
+EV_ONESHOT
+.It Sy c
+EV_CLEAR
+.It Sy o
+EV_EOF
+.It Sy e
+EV_ERROR
+.El
+.It evst
+kevent status bitmask.
+.Bl -tag -width xxxxxxx -compact
+.It Sy a
+Event has triggered (KN_ACTIVE).
+.It Sy q
+Event has been added to the active list (KN_QUEUED).
+.It Sy d
+Event is disabled (KN_DISABLED).
+.It Sy s
+Event is marked as always-enqueued on the active list (KN_STAYQUEUED).
+.El
+.It data
+Filter-specific data.
+.El
+.Pp
+If the
+.Fl v
+(verbose) option is specified, the opaque user-data field and further
+filter-specific extension fields are printed in raw hexadecimal.
+.Sh NOTES
+The output of
+.Nm lskq
+is not an atomic snapshot of system state. In cases where
+.Nm lskq
+is able to detect an inconsistency, a warning will be printed.
+.Sh SEE ALSO
+.Xr kqueue 2 ,
+.Xr kevent 2 ,
+.Xr ddt 1 ,
+.Xr lsof 8 ,
+.Xr lsmp 1
diff --git a/lskq.tproj/lskq.c b/lskq.tproj/lskq.c
new file mode 100644 (file)
index 0000000..48782d8
--- /dev/null
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2015 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <strings.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <sys/proc_info.h>
+#include <mach/message.h>
+#include <libproc.h>
+
+#include "common.h"
+
+#define ARRAYLEN(x) (sizeof((x))/sizeof((x[0])))
+
+/* command line options */
+static int verbose;
+static int all_pids;
+static int ignore_empty;
+
+static char *self = "lskq";
+
+static inline const char *
+filt_name(int16_t filt)
+{
+       int idx = -filt;
+       if (idx >= 0 && idx < ARRAYLEN(filt_strs)) {
+               return filt_strs[idx];
+       } else {
+               return "<inval>";
+       }
+}
+
+static inline const char *
+fdtype_str(uint32_t type)
+{
+       if (type < ARRAYLEN(fdtype_strs)) {
+               return fdtype_strs[type];
+       } else {
+               return "<unknown>";
+       }
+}
+
+static char *
+fflags_build(struct kevent_extinfo *info, char *str, int len)
+{
+       unsigned ff = info->kqext_sfflags;
+
+       switch (info->kqext_kev.filter) {
+
+       case EVFILT_READ: {
+               snprintf(str, len, "%c      ",
+                       (ff & NOTE_LOWAT) ? 'l' : '-'
+               );
+               break;
+       }
+
+       case EVFILT_MACHPORT: {
+               snprintf(str, len, "%c      ",
+                       (ff & MACH_RCV_MSG) ? 'r' : '-'
+               );
+               break;
+       }
+
+       case EVFILT_VNODE: {
+               snprintf(str, len, "%c%c%c%c%c%c%c",
+                       (ff & NOTE_DELETE) ? 'd' : '-',
+                       (ff & NOTE_WRITE)  ? 'w' : '-',
+                       (ff & NOTE_EXTEND) ? 'e' : '-',
+                       (ff & NOTE_ATTRIB) ? 'a' : '-',
+                       (ff & NOTE_LINK)   ? 'l' : '-',
+                       (ff & NOTE_RENAME) ? 'r' : '-',
+                       (ff & NOTE_REVOKE) ? 'v' : '-'
+               );
+               break;
+       }
+
+       case EVFILT_PROC: {
+/* NOTE_REAP is deprecated, but we still want to show if it's used */
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+               snprintf(str, len, "%c%c%c%c%c%c ",
+                       (ff & NOTE_EXIT)       ? 'x' : '-',
+                       (ff & NOTE_EXITSTATUS) ? 't' : '-',
+                       (ff & NOTE_FORK)       ? 'f' : '-',
+                       (ff & NOTE_EXEC)       ? 'e' : '-',
+                       (ff & NOTE_SIGNAL)     ? 's' : '-',
+                       (ff & NOTE_REAP)       ? 'r' : '-'
+               );
+               break;
+#pragma clang diagnostic pop
+       }
+
+       case EVFILT_TIMER: {
+               snprintf(str, len, "%c%c%c%c%c  ",
+                       (ff & NOTE_SECONDS)    ? 's' :
+                       (ff & NOTE_USECONDS)   ? 'u' :
+                       (ff & NOTE_NSECONDS)   ? 'n' : '?',
+                       (ff & NOTE_ABSOLUTE)   ? 'a' : '-',
+                       (ff & NOTE_CRITICAL)   ? 'c' : '-',
+                       (ff & NOTE_BACKGROUND) ? 'b' : '-',
+                       (ff & NOTE_LEEWAY)     ? 'l' : '-'
+               );
+               break;
+       }
+
+       default:
+               snprintf(str, len, "");
+               break;
+       };
+
+       return str;
+}
+
+
+static inline int
+filter_is_fd_type(int filter)
+{
+       if (filter <= EVFILT_READ && filter >= EVFILT_VNODE) {
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
+/*
+ * find index of fd in a list of fdinfo of length nfds
+ */
+static inline int
+fd_list_getfd(struct proc_fdinfo *fds, int nfds, int fd)
+{
+       int i;
+       for (i = 0; i < nfds; i++) {
+               if (fds[i].proc_fd == fd) {
+                       return i;
+               }
+       }
+
+       return -1;
+}
+
+/*
+ * left truncate URL-form process names
+ */
+static const char *
+shorten_procname(const char *proc, int width)
+{
+       if (strcasestr(proc, "com.") == proc) {
+               long len = strlen(proc);
+               if (len > width) {
+                       return &proc[len - width];
+               } else {
+                       return proc;
+               }
+       } else {
+               return proc;
+       }
+}
+
+/*
+ * stringify knote ident where possible (signals, processes)
+ */
+static void
+print_ident(uint64_t ident, int16_t filter, int width)
+{
+       switch (filter) {
+
+       case EVFILT_SIGNAL:
+       case EVFILT_PROC: {
+               char str[128] = "";
+               char num[128];
+               char out[128];
+               int numlen = sprintf(num, "%llu", ident);
+               int strwidth = width - numlen - 3; // add room for brackets and space
+
+               if (filter == EVFILT_SIGNAL) {
+                       if (ident < ARRAYLEN(sig_strs)) {
+                               snprintf(str, strwidth + 1, "%s", sig_strs[ident]);
+                       }
+               } else {
+                       /* FIXME: this should be cached */
+                       struct proc_bsdinfo bsdinfo;
+                       int ret = proc_pidinfo((int)ident, PROC_PIDTBSDINFO, 0, &bsdinfo, sizeof(bsdinfo));
+                       if (ret == sizeof(bsdinfo)) {
+                               char *procname = bsdinfo.pbi_name;
+                               if (strlen(procname) == 0) {
+                                       procname = bsdinfo.pbi_comm;
+                               }
+                               snprintf(str, strwidth + 1, "%s",
+                                               shorten_procname(procname, strwidth));
+                       }
+               }
+
+               if (str[0] != '\0') {
+                       snprintf(out, width + 1, "(%s) %s", str, num);
+               } else {
+                       snprintf(out, width + 1, "%s", num);
+               }
+
+               printf("%*s ", width, out);
+               break;
+       }
+
+       default:
+               printf("%*llu ", width, ident);
+               break;
+       }
+
+}
+
+static void
+print_kqfd(int kqfd, int width)
+{
+       if (kqfd == -1) {
+               printf("%*s ", width, "wq");
+       } else {
+               printf("%*u ", width, kqfd);
+       }
+}
+
+static void
+print_kq_info(int pid, const char *procname, int kqfd, int state)
+{
+       char tmpstr[16];
+       strlcpy(tmpstr, shorten_procname(procname, 10), 11);
+       printf("%-10s ", tmpstr);
+       printf("%5u ", pid);
+       print_kqfd(kqfd, 5);
+       printf(" %c%c%c ",
+                       (state & KQ_SLEEP)    ? 'k' : '-',
+                       (state & KQ_SEL)      ? 's' : '-',
+                       (state & KQ_KEV32)    ? '3' :
+                       (state & KQ_KEV64)    ? '6' :
+                       (state & KQ_KEV_QOS)  ? 'q' : '-'
+                 );
+}
+
+#define MAXENTRIES 2048
+
+static int
+process_kqueue_on_fd(int pid, const char *procname, int kqfd, struct proc_fdinfo *fdlist, int nfds)
+{
+       int ret, i, nknotes;
+       char tmpstr[256];
+
+       /*
+        * get the basic kqueue info
+        */
+       struct kqueue_fdinfo kqfdinfo = {};
+       ret = proc_pidfdinfo(pid, kqfd, PROC_PIDFDKQUEUEINFO, &kqfdinfo, sizeof(kqfdinfo));
+       if (ret != sizeof(kqfdinfo) && kqfd != -1) {
+               /* every proc has an implicit workq kqueue, dont warn if its unused */
+               fprintf(stderr, "WARN: FD table changed (pid %i, kq %i)\n", pid, kqfd);
+       }
+
+       /*
+        * get extended kqueue info
+        */
+       struct kevent_extinfo kqextinfo[MAXENTRIES];
+ again:
+       errno = 0;
+       nknotes = proc_pidfdinfo(pid, kqfd, PROC_PIDFDKQUEUE_EXTINFO, kqextinfo, sizeof(kqextinfo));
+       if (nknotes <= 0) {
+               if (errno == 0) {
+                       /* proc_*() can't distinguish between error and empty list */
+               } else if (errno == EAGAIN) {
+                       goto again;
+               } else if (errno == EBADF) {
+                       fprintf(stderr, "WARN: FD table changed (pid %i, kq %i)\n", pid, kqfd);
+                       return 0;
+               } else {
+                       perror("failed to get extended kqueue info");
+                       return errno;
+               }
+       }
+
+       if (nknotes > MAXENTRIES) {
+               fprintf(stderr, "WARN: truncated knote list (pid %i, kq %i)\n", pid, kqfd);
+               nknotes = MAXENTRIES;
+       }
+
+       if (nknotes == 0) {
+               if (!ignore_empty) {
+                       /* for empty kqueues, print a single empty entry */
+                       print_kq_info(pid, procname, kqfd, kqfdinfo.kqueueinfo.kq_state);
+                       printf("%20s \n", "-");
+               }
+               return 0;
+       }
+
+       for (i = 0; i < nknotes; i++) {
+               struct kevent_extinfo *info = &kqextinfo[i];
+
+               print_kq_info(pid, procname, kqfd, kqfdinfo.kqueueinfo.kq_state);
+               print_ident(info->kqext_kev.ident, info->kqext_kev.filter, 20);
+               printf("%-9s ", filt_name(info->kqext_kev.filter));
+
+               /* for kevents attached to file descriptors, print the type of FD (file, socket, etc) */
+               const char *fdstr = "";
+               if (filter_is_fd_type(info->kqext_kev.filter)) {
+                       fdstr = "<UNKN>";
+                       int knfd = (info->kqext_kev.ident < nfds)
+                                       ? fd_list_getfd(fdlist, nfds, (int)info->kqext_kev.ident)
+                                       : -1;
+                       if (knfd >= 0) {
+                               fdstr = fdtype_str(fdlist[knfd].proc_fdtype);
+                       }
+               }
+               printf("%-8s ", fdstr);
+
+               /* print filter flags */
+               printf("%7s ", fflags_build(info, tmpstr, sizeof(tmpstr)));
+
+               /* print generic flags */
+               unsigned flg = info->kqext_kev.flags;
+               printf("%c%c%c%c%c%c%c%c%c ",
+                               (flg & EV_ADD)     ? 'a' : '-',
+                               (flg & EV_ENABLE)  ? 'n' : '-',
+                               (flg & EV_DISABLE) ? 'd' : '-',
+                               (flg & EV_DELETE)  ? 'x' : '-',
+                               (flg & EV_RECEIPT) ? 'r' : '-',
+                               (flg & EV_ONESHOT) ? '1' : '-',
+                               (flg & EV_CLEAR)   ? 'c' : '-',
+                               (flg & EV_EOF)     ? 'o' : '-',
+                               (flg & EV_ERROR)   ? 'e' : '-'
+               );
+
+               unsigned st = info->kqext_status;
+               printf("%c%c%c%c ",
+                               (st & KN_ACTIVE)     ? 'a' : '-',
+                               (st & KN_QUEUED)     ? 'q' : '-',
+                               (st & KN_DISABLED)   ? 'd' : '-',
+                               (st & KN_STAYQUEUED) ? 's' : '-'
+               );
+
+               printf("%#18llx ", (unsigned long long)info->kqext_kev.data);
+
+               if (verbose) {
+                       printf("%#18llx ", (unsigned long long)info->kqext_kev.udata);
+                       if (kqfdinfo.kqueueinfo.kq_state & (KQ_KEV64|KQ_KEV_QOS)) {
+                               printf("%#18llx ", (unsigned long long)info->kqext_kev.ext[0]);
+                               printf("%#18llx ", (unsigned long long)info->kqext_kev.ext[1]);
+                       }
+                       if (kqfdinfo.kqueueinfo.kq_state & KQ_KEV_QOS) {
+                               printf("%#18llx ", (unsigned long long)info->kqext_kev.ext[2]);
+                               printf("%#18llx ", (unsigned long long)info->kqext_kev.ext[3]);
+                               printf("%#10lx ", (unsigned long)info->kqext_kev.xflags);
+                       }
+               }
+
+               printf("\n");
+       }
+
+       return 0;
+}
+
+static int
+process_pid(pid_t pid)
+{
+       int i, ret, nfds;
+
+       /* enumerate file descriptors */
+       struct proc_fdinfo fdlist[MAXENTRIES];
+       nfds = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fdlist, sizeof(fdlist));
+       if (nfds <= 0) {
+               fprintf(stderr, "%s: failed enumerating file descriptors of process %i: %s",
+                               self, pid, strerror(errno));
+               if (errno == EPERM && geteuid() != 0) {
+                       fprintf(stderr, " (are you root?)");
+               }
+               fprintf(stderr, "\n");
+               return 1;
+       }
+
+       nfds /= sizeof(struct proc_fdinfo);
+       if (nfds > MAXENTRIES) {
+               fprintf(stderr, "WARN: truncated FD list (proc %i)\n", pid);
+               nfds = MAXENTRIES;
+       }
+
+       /* get bsdinfo for the process name */
+       struct proc_bsdinfo bsdinfo;
+       ret = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &bsdinfo, sizeof(bsdinfo));
+       if (ret != sizeof(bsdinfo)) {
+               perror("failed retrieving process info");
+               return 1;
+       }
+
+       char *procname = bsdinfo.pbi_name;
+       if (strlen(procname) == 0) {
+               procname = bsdinfo.pbi_comm;
+       }
+
+       /* handle the special workq kq */
+       ret = process_kqueue_on_fd(pid, procname, -1, fdlist, nfds);
+       if (ret) {
+               return ret;
+       }
+
+       for (i = 0; i < nfds; i++) {
+               if (fdlist[i].proc_fdtype == PROX_FDTYPE_KQUEUE) {
+                       ret = process_kqueue_on_fd(pid, procname, fdlist[i].proc_fd, fdlist, nfds);
+                       if (ret) {
+                               return ret;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+#define MAXPIDS 4096
+
+static int
+process_all_pids(void)
+{
+       int i, npids, ret;
+       int pids[MAXPIDS];
+
+       npids = proc_listpids(PROC_ALL_PIDS, 0, pids, sizeof(pids));
+       if (npids <= 0) {
+               perror("failed enumerating pids");
+               return 1;
+       }
+       npids /= sizeof(int);
+
+       for (i = 0; i < npids; i++) {
+               /* listpids gives us pid 0 for some reason */
+               if (pids[i]) {
+                       ret = process_pid(pids[i]);
+                       if (ret) {
+                               return ret;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static void
+usage(void)
+{
+       fprintf(stderr, "usage: %s [-vhe] [-a | -p <pid>]\n", self);
+}
+
+int main(int argc, char *argv[])
+{
+       pid_t pid = 0;
+       int opt;
+
+       if (argc > 0) {
+               self = argv[0];
+       }
+
+       while ((opt = getopt(argc, argv, "eahvp:")) != -1) {
+               switch (opt) {
+               case 'a':
+                       all_pids = 1;
+                       break;
+               case 'v':
+                       verbose++;
+                       break;
+               case 'p':
+                       pid = atoi(optarg);
+                       break;
+               case 'e':
+                       ignore_empty = 1;
+                       break;
+               case 'h':
+                       usage();
+                       return 0;
+               case '?':
+               default:
+                       usage();
+                       return 1;
+               }
+       }
+
+       argc -= optind;
+       argv += optind;
+
+       if (argc == 1) {
+               /* also allow lskq <pid> */
+               if (pid || all_pids) {
+                       usage();
+                       return 1;
+               }
+
+               pid = atoi(argv[0]);
+       } else if (argc > 1) {
+               usage();
+               return 1;
+       }
+
+       /* exactly one of -p or -a is required */
+       if (!pid && !all_pids) {
+               usage();
+               return 1;
+       } else if (pid && all_pids) {
+               usage();
+               return 1;
+       }
+
+       printf("command      pid    kq kqst                ident filter    fdtype   fflags    flags   evst               data");
+       if (verbose) {
+               printf("              udata               ext0               ext1               ext2               ext3     xflags");
+       }
+       printf("\n");
+       printf("---------- ----- ----- ---- -------------------- --------- -------- ------- --------- ---- ------------------");
+       if (verbose) {
+               printf(" ------------------ ------------------ ------------------ ------------------ ------------------ ----------");
+       }
+       printf("\n");
+
+       if (all_pids) {
+               return process_all_pids();
+       } else {
+               return process_pid(pid);
+       }
+
+       return 0;
+}
+
index b21dbd852d3f6b01c31c04c546591b0f018198f5..b7b4e6c614e0ae0e9e32b513409cb53b2da1ebd5 100644 (file)
@@ -4,5 +4,7 @@
 <dict>
        <key>task_for_pid-allow</key>
        <true/>
+       <key>com.apple.system-task-ports</key>
+       <true/>
 </dict>
 </plist>
index 481c96146a14b8a2795aee3c66124aec375b83e3..438e6041f9f102e7af53bab426cdd1a26f0b36d6 100644 (file)
@@ -309,7 +309,7 @@ void show_task_mach_ports(my_per_task_info_t *taskinfo, uint32_t taskCount, my_p
             
                        /* show other rights (in this and other tasks) for the port */
                        for (j = 0; j < taskCount; j++) {
-                               for (k = 0; k < allTaskInfos->tableCount; k++) {
+                               for (k = 0; k < allTaskInfos[j].tableCount; k++) {
                                        if (allTaskInfos[j].valid == FALSE ||
                                                &allTaskInfos[j].table[k] == &taskinfo->table[i] ||
                                                allTaskInfos[j].table[k].iin_object != taskinfo->table[i].iin_object)
index 2538799db168b2c305da6906525963ceba90d292..6fb8deee887e5734318e94ff30b799aeacb32b6b 100644 (file)
@@ -209,7 +209,7 @@ kern_return_t print_task_threads_special_ports(my_per_task_info_t *taskinfo)
     
     for (int i = 0; i < threadcount; i++) {
         if (header_required) {
-            printf("Threads             Thread-ID     DispatchQ     Port Description.");
+            printf("Threads             Thread-ID     Port Description.");
             header_required = FALSE;
         }
         
@@ -223,10 +223,10 @@ kern_return_t print_task_threads_special_ports(my_per_task_info_t *taskinfo)
             mach_msg_type_number_t th_info_count = THREAD_IDENTIFIER_INFO_COUNT;
             printf("0x%08x ", th_kobject);
             if (KERN_SUCCESS == thread_info(threadlist[i], THREAD_IDENTIFIER_INFO, (thread_info_t)&th_info, &th_info_count)) {
-                printf("%16llu  0x%016llx  ", th_info.thread_id, th_info.dispatch_qaddr);
+                printf("0x%llx  ", th_info.thread_id);
             }
             else
-                printf("                                     ");
+                printf("                   ");
             
         }
 
@@ -238,6 +238,7 @@ kern_return_t print_task_threads_special_ports(my_per_task_info_t *taskinfo)
         }
         mach_port_deallocate(mach_task_self(), threadlist[i]);
     }
+    printf("\n");
     return kret;
 }
 
index 0d82b45502ed396d5070f613674ad397820ae5f4..fc6a24a7e2eb564e7651bd342f9795bad507d57f 100644 (file)
@@ -26,6 +26,7 @@ cc -o nvram nvram.c -framework CoreFoundation -framework IOKit -Wall
 #include <stdio.h>
 #include <IOKit/IOKitLib.h>
 #include <IOKit/IOKitKeys.h>
+#include <IOKit/IOKitKeysPrivate.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include <err.h>
 #include <mach/mach_error.h>
@@ -52,6 +53,7 @@ static void NVRamSyncNow(char *name);
 static char                *gToolName;
 static io_registry_entry_t gOptionsRef;
 static bool                gUseXML;
+static bool                gUseForceSync;
 
 
 int main(int argc, char **argv)
@@ -112,7 +114,11 @@ int main(int argc, char **argv)
        case 'c':
          ClearOFVariables();
          break;
-         
+       case 's':
+         // -s option is unadvertised -- advises the kernel more forcibly to
+         // commit the variable to nonvolatile storage
+         gUseForceSync = true;
+         break;
        default:
          strcpy(errorMessage, "no such option as --");
          errorMessage[strlen(errorMessage)-1] = *str;
@@ -500,7 +506,11 @@ static void DeleteOFVariable(char *name)
 
 static void NVRamSyncNow(char *name)
 {
-  SetOFVariable(kIONVRAMSyncNowPropertyKey, name);
+  if (!gUseForceSync) {
+    SetOFVariable(kIONVRAMSyncNowPropertyKey, name);
+  } else {
+    SetOFVariable(kIONVRAMForceSyncNowPropertyKey, name);
+  }
 }
 
 // PrintOFVariables()
index 33f8f100b9931b8736d3014b255911ece3400aa3..f545174b15cd0173a4bf4d7264df3e58583bcbf7 100644 (file)
@@ -13,6 +13,8 @@
                        buildPhases = (
                        );
                        dependencies = (
+                               97999D351AE84D3A00E8B10F /* PBXTargetDependency */,
+                               08DC48921A12C6FA008AAF38 /* PBXTargetDependency */,
                                18597F1A18CBC3B000531A50 /* PBXTargetDependency */,
                                1865518B18CA7151003B92A7 /* PBXTargetDependency */,
                                550C19F11804D2B7001DA380 /* PBXTargetDependency */,
                        buildPhases = (
                        );
                        dependencies = (
+                               97999D371AE84D4100E8B10F /* PBXTargetDependency */,
+                               08DC48901A12C6F0008AAF38 /* PBXTargetDependency */,
                                18597F1C18CBC3B900531A50 /* PBXTargetDependency */,
                                186551D018CA8154003B92A7 /* PBXTargetDependency */,
                                550C19EF1804D2AD001DA380 /* PBXTargetDependency */,
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
+               08DC488E1A12C2D6008AAF38 /* kpgo.c in Sources */ = {isa = PBXBuildFile; fileRef = 08DC488D1A12C2C6008AAF38 /* kpgo.c */; };
                1523FE6C1595056C00661E82 /* ltop.c in Sources */ = {isa = PBXBuildFile; fileRef = 1523FE6B1595056C00661E82 /* ltop.c */; };
                1523FE6D1595058100661E82 /* ltop.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1523FE6A1595056C00661E82 /* ltop.1 */; };
                1845E41618EB95810010F451 /* TraceFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1845E41418EB95810010F451 /* TraceFile.cpp */; };
                55CCB17616B84F3600B56979 /* vm_purgeable_stat.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 55CCB16816B84ED100B56979 /* vm_purgeable_stat.1 */; };
                72D1FDD918C4140600C1E05F /* task_details.c in Sources */ = {isa = PBXBuildFile; fileRef = 72D1FDD818C4140600C1E05F /* task_details.c */; };
                72F9316D18C26A8600D804C5 /* port_details.c in Sources */ = {isa = PBXBuildFile; fileRef = 72F9316C18C26A8600D804C5 /* port_details.c */; };
+               97999D321AE84CE400E8B10F /* lskq.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 97999D301AE84C7600E8B10F /* lskq.1 */; };
+               97999D331AE84D0A00E8B10F /* lskq.c in Sources */ = {isa = PBXBuildFile; fileRef = 97999D311AE84C7600E8B10F /* lskq.c */; };
+               A624DA861AF6F3CF00F56A5C /* CoreSymbolication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A624DA851AF6F3CF00F56A5C /* CoreSymbolication.framework */; };
+               A6738D031AF6FF9F001EF064 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A6738D021AF6FF9F001EF064 /* IOKit.framework */; };
+               A6738D051AF6FFB5001EF064 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A6738D041AF6FFB5001EF064 /* CoreFoundation.framework */; };
                ADA9007B1767A02D00161ADF /* purge.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = ADA900791767A02700161ADF /* purge.8 */; };
                ADA9007C1767A03200161ADF /* purge.c in Sources */ = {isa = PBXBuildFile; fileRef = ADA9007A1767A02700161ADF /* purge.c */; };
                B158E3A3185A836700474677 /* wordexp-helper.c in Sources */ = {isa = PBXBuildFile; fileRef = B158E3A2185A836700474677 /* wordexp-helper.c */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
+               08DC488F1A12C6F0008AAF38 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = BA2DE9181372FA9100D1913C /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 08DC48841A12C21B008AAF38;
+                       remoteInfo = kpgo;
+               };
+               08DC48911A12C6FA008AAF38 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = BA2DE9181372FA9100D1913C /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 08DC48841A12C21B008AAF38;
+                       remoteInfo = kpgo;
+               };
                1523FE6E1595069900661E82 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = BA2DE9181372FA9100D1913C /* Project object */;
                        remoteGlobalIDString = 55CCB16A16B84EDA00B56979;
                        remoteInfo = vm_purgeable_stat;
                };
+               97999D341AE84D3A00E8B10F /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = BA2DE9181372FA9100D1913C /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 97999D211AE84C0E00E8B10F;
+                       remoteInfo = lskq;
+               };
+               97999D361AE84D4100E8B10F /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = BA2DE9181372FA9100D1913C /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 97999D211AE84C0E00E8B10F;
+                       remoteInfo = lskq;
+               };
                ADA9007D1767A31300161ADF /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = BA2DE9181372FA9100D1913C /* Project object */;
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXCopyFilesBuildPhase section */
+               08DC48831A12C21B008AAF38 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = /usr/share/man/man1/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
                1523FE5F1595048900661E82 /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
+               97999D281AE84C0E00E8B10F /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = /usr/share/man/man1;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               97999D321AE84CE400E8B10F /* lskq.1 in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
                ADA9007317679A8C00161ADF /* CopyFiles */ = {
                        isa = PBXCopyFilesBuildPhase;
                        buildActionMask = 2147483647;
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
+               08DC48851A12C21B008AAF38 /* kpgo */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = kpgo; sourceTree = BUILT_PRODUCTS_DIR; };
+               08DC488D1A12C2C6008AAF38 /* kpgo.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = kpgo.c; sourceTree = "<group>"; };
                1523FE631595048900661E82 /* ltop */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ltop; sourceTree = BUILT_PRODUCTS_DIR; };
                1523FE6A1595056C00661E82 /* ltop.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; path = ltop.1; sourceTree = "<group>"; };
                1523FE6B1595056C00661E82 /* ltop.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltop.c; sourceTree = "<group>"; };
                72D1FDD818C4140600C1E05F /* task_details.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = task_details.c; path = lsmp.tproj/task_details.c; sourceTree = SOURCE_ROOT; };
                72F9316B18C269E500D804C5 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = common.h; path = lsmp.tproj/common.h; sourceTree = SOURCE_ROOT; };
                72F9316C18C26A8600D804C5 /* port_details.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = port_details.c; path = lsmp.tproj/port_details.c; sourceTree = SOURCE_ROOT; };
+               97999D2D1AE84C0E00E8B10F /* lskq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = lskq; sourceTree = BUILT_PRODUCTS_DIR; };
+               97999D2F1AE84C7600E8B10F /* common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = common.h; path = lskq.tproj/common.h; sourceTree = "<group>"; };
+               97999D301AE84C7600E8B10F /* lskq.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; name = lskq.1; path = lskq.tproj/lskq.1; sourceTree = "<group>"; };
+               97999D311AE84C7600E8B10F /* lskq.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = lskq.c; path = lskq.tproj/lskq.c; sourceTree = "<group>"; };
+               A624DA851AF6F3CF00F56A5C /* CoreSymbolication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreSymbolication.framework; path = ../../../../System/Library/PrivateFrameworks/CoreSymbolication.framework; sourceTree = "<group>"; };
+               A6738D021AF6FF9F001EF064 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = ../../../../System/Library/Frameworks/IOKit.framework; sourceTree = "<group>"; };
+               A6738D041AF6FFB5001EF064 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = ../../../../System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<group>"; };
                ADA9007717679A8C00161ADF /* purge */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = purge; sourceTree = BUILT_PRODUCTS_DIR; };
                ADA900791767A02700161ADF /* purge.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = purge.8; sourceTree = "<group>"; };
                ADA9007A1767A02700161ADF /* purge.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = purge.c; sourceTree = "<group>"; };
                C96F50AC15BDCBF0008682F7 /* lsmp.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; name = lsmp.1; path = lsmp.tproj/lsmp.1; sourceTree = SOURCE_ROOT; };
                C96F50AD15BDCE8E008682F7 /* lsmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lsmp.c; path = lsmp.tproj/lsmp.c; sourceTree = SOURCE_ROOT; };
                C96F50B715BDCEC3008682F7 /* lsmp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = lsmp; sourceTree = BUILT_PRODUCTS_DIR; };
+               FEBEE5CF1B0EACEB00166A8B /* entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = entitlements.plist; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
+               08DC48821A12C21B008AAF38 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                1523FE5D1595048900661E82 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               97999D261AE84C0E00E8B10F /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                ADA9007217679A8C00161ADF /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               A6738D051AF6FFB5001EF064 /* CoreFoundation.framework in Frameworks */,
                                BA0A860B13968E8500D2272C /* libutil.dylib in Frameworks */,
+                               A624DA861AF6F3CF00F56A5C /* CoreSymbolication.framework in Frameworks */,
+                               A6738D031AF6FF9F001EF064 /* IOKit.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+               08DC488C1A12C2C5008AAF38 /* kpgo.tproj */ = {
+                       isa = PBXGroup;
+                       children = (
+                               08DC488D1A12C2C6008AAF38 /* kpgo.c */,
+                       );
+                       path = kpgo.tproj;
+                       sourceTree = "<group>";
+               };
                1523FE691595056C00661E82 /* ltop.tproj */ = {
                        isa = PBXGroup;
                        children = (
                        path = vm_purgeable_stat.tproj;
                        sourceTree = "<group>";
                };
+               97999D2E1AE84C5700E8B10F /* lskq.tproj */ = {
+                       isa = PBXGroup;
+                       children = (
+                               97999D2F1AE84C7600E8B10F /* common.h */,
+                               97999D301AE84C7600E8B10F /* lskq.1 */,
+                               97999D311AE84C7600E8B10F /* lskq.c */,
+                       );
+                       name = lskq.tproj;
+                       sourceTree = "<group>";
+               };
                ADA900781767A02700161ADF /* purge.tproj */ = {
                        isa = PBXGroup;
                        children = (
                BA2DE9161372FA9100D1913C = {
                        isa = PBXGroup;
                        children = (
+                               A6738D041AF6FFB5001EF064 /* CoreFoundation.framework */,
+                               A6738D021AF6FF9F001EF064 /* IOKit.framework */,
+                               A624DA851AF6F3CF00F56A5C /* CoreSymbolication.framework */,
+                               08DC488C1A12C2C5008AAF38 /* kpgo.tproj */,
                                186551CD18CA7A1B003B92A7 /* System.framework */,
                                550C19DF1804C55E001DA380 /* iosim.tproj */,
                                ADA900781767A02700161ADF /* purge.tproj */,
                                BA4FD24F1372FAFA0025925C /* iostat.tproj */,
                                BA4FD2551372FAFA0025925C /* latency.tproj */,
                                BA4FD2591372FAFA0025925C /* login.tproj */,
+                               97999D2E1AE84C5700E8B10F /* lskq.tproj */,
                                1523FE691595056C00661E82 /* ltop.tproj */,
                                BA4FD2651372FAFA0025925C /* makekey.tproj */,
                                BA4FD2691372FAFA0025925C /* mean.tproj */,
                BA4FD2E31372FAFA0025925C /* zprint.tproj */ = {
                        isa = PBXGroup;
                        children = (
+                               FEBEE5CF1B0EACEB00166A8B /* entitlements.plist */,
                                BA4FD2E51372FAFA0025925C /* zprint.1 */,
                                BA4FD2E61372FAFA0025925C /* zprint.c */,
                        );
                                1865517C18CA7104003B92A7 /* msa */,
                                18597EC418CBC2A300531A50 /* kdprof */,
                                18C8727F18EA114F00F86DD9 /* libKDBG.a */,
+                               08DC48851A12C21B008AAF38 /* kpgo */,
+                               97999D2D1AE84C0E00E8B10F /* lskq */,
                        );
                        name = Products;
                        sourceTree = "<group>";
 /* End PBXHeadersBuildPhase section */
 
 /* Begin PBXNativeTarget section */
+               08DC48841A12C21B008AAF38 /* kpgo */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 08DC488B1A12C21C008AAF38 /* Build configuration list for PBXNativeTarget "kpgo" */;
+                       buildPhases = (
+                               08DC48811A12C21B008AAF38 /* Sources */,
+                               08DC48821A12C21B008AAF38 /* Frameworks */,
+                               08DC48831A12C21B008AAF38 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = kpgo;
+                       productName = kpgo;
+                       productReference = 08DC48851A12C21B008AAF38 /* kpgo */;
+                       productType = "com.apple.product-type.tool";
+               };
                1523FE5A1595048900661E82 /* ltop */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = 1523FE611595048900661E82 /* Build configuration list for PBXNativeTarget "ltop" */;
                        productReference = 55CCB17316B84EDA00B56979 /* vm_purgeable_stat */;
                        productType = "com.apple.product-type.tool";
                };
+               97999D211AE84C0E00E8B10F /* lskq */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 97999D2A1AE84C0E00E8B10F /* Build configuration list for PBXNativeTarget "lskq" */;
+                       buildPhases = (
+                               97999D221AE84C0E00E8B10F /* Sources */,
+                               97999D261AE84C0E00E8B10F /* Frameworks */,
+                               97999D281AE84C0E00E8B10F /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = lskq;
+                       productName = ac;
+                       productReference = 97999D2D1AE84C0E00E8B10F /* lskq */;
+                       productType = "com.apple.product-type.tool";
+               };
                ADA9006F17679A8C00161ADF /* purge */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = ADA9007517679A8C00161ADF /* Build configuration list for PBXNativeTarget "purge" */;
                        isa = PBXProject;
                        attributes = {
                                LastUpgradeCheck = 0600;
+                               TargetAttributes = {
+                                       08DC48841A12C21B008AAF38 = {
+                                               CreatedOnToolsVersion = 6.3;
+                                       };
+                               };
                        };
                        buildConfigurationList = BA2DE91B1372FA9100D1913C /* Build configuration list for PBXProject "system_cmds" */;
                        compatibilityVersion = "Xcode 3.2";
                                BA4B7A6913765D3E00003422 /* iostat */,
                                BA4B7A7D13765F3C00003422 /* latency */,
                                BA473DA01377B2230005CC19 /* login */,
+                               97999D211AE84C0E00E8B10F /* lskq */,
                                1523FE5A1595048900661E82 /* ltop */,
                                BACC1D011377B3E6007728F4 /* makekey */,
                                BACC1D0D1377B481007728F4 /* mean */,
                                18C8727E18EA114F00F86DD9 /* KDBG */,
                                1865517B18CA7104003B92A7 /* msa */,
                                18597EC318CBC2A300531A50 /* kdprof */,
+                               08DC48841A12C21B008AAF38 /* kpgo */,
                        );
                };
 /* End PBXProject section */
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "set -x\nset -e\n\ncp \"${SCRIPT_INPUT_FILE_0}\" \"${SCRIPT_OUTPUT_FILE_0}\"\nif [[ \"${PLATFORM_NAME}\" == \"iphoneos\"* ]]; then\n    /usr/libexec/PlistBuddy -c \"Add :LaunchOnlyOnce bool true\" \"${SCRIPT_OUTPUT_FILE_0}\"\nfi\n";
+                       shellScript = ". ${SRCROOT}/dynamic_pager.tproj/generate_plist.sh";
                };
                BA4B7A221373C01600003422 /* ShellScript */ = {
                        isa = PBXShellScriptBuildPhase;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "set -x\nset -e\n\ncp \"${SCRIPT_INPUT_FILE_0}\" \"${SCRIPT_OUTPUT_FILE_0}\"\nif [[ \"${PLATFORM_NAME}\" != \"iphoneos\"* ]]; then\n    /usr/libexec/PlistBuddy -c \"Add :Disabled bool true\" \"${SCRIPT_OUTPUT_FILE_0}\"\nfi\n";
+                       shellScript = ". ${SRCROOT}/getty.tproj/generate_plist.sh";
                };
                BA4FD335137306050025925C /* ShellScript */ = {
                        isa = PBXShellScriptBuildPhase;
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
+               08DC48811A12C21B008AAF38 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               08DC488E1A12C2D6008AAF38 /* kpgo.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                1523FE5B1595048900661E82 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               97999D221AE84C0E00E8B10F /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               97999D331AE84D0A00E8B10F /* lskq.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                ADA9007017679A8C00161ADF /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
+               08DC48901A12C6F0008AAF38 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 08DC48841A12C21B008AAF38 /* kpgo */;
+                       targetProxy = 08DC488F1A12C6F0008AAF38 /* PBXContainerItemProxy */;
+               };
+               08DC48921A12C6FA008AAF38 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 08DC48841A12C21B008AAF38 /* kpgo */;
+                       targetProxy = 08DC48911A12C6FA008AAF38 /* PBXContainerItemProxy */;
+               };
                1523FE6F1595069900661E82 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 1523FE5A1595048900661E82 /* ltop */;
                        target = 55CCB16A16B84EDA00B56979 /* vm_purgeable_stat */;
                        targetProxy = 55CCB17916B851F300B56979 /* PBXContainerItemProxy */;
                };
+               97999D351AE84D3A00E8B10F /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 97999D211AE84C0E00E8B10F /* lskq */;
+                       targetProxy = 97999D341AE84D3A00E8B10F /* PBXContainerItemProxy */;
+               };
+               97999D371AE84D4100E8B10F /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 97999D211AE84C0E00E8B10F /* lskq */;
+                       targetProxy = 97999D361AE84D4100E8B10F /* PBXContainerItemProxy */;
+               };
                ADA9007E1767A31300161ADF /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = ADA9006F17679A8C00161ADF /* purge */;
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */
+               08DC48891A12C21C008AAF38 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               COPY_PHASE_STRIP = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               ENABLE_NS_ASSERTIONS = NO;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+                                       "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders",
+                               );
+                               MACOSX_DEPLOYMENT_TARGET = 10.10;
+                               MTL_ENABLE_DEBUG_INFO = NO;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SDKROOT = macosx.internal;
+                       };
+                       name = Release;
+               };
+               08DC488A1A12C21C008AAF38 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               COPY_PHASE_STRIP = NO;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+                                       "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders",
+                               );
+                               MACOSX_DEPLOYMENT_TARGET = 10.10;
+                               MTL_ENABLE_DEBUG_INFO = YES;
+                               ONLY_ACTIVE_ARCH = YES;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SDKROOT = macosx.internal;
+                       };
+                       name = Debug;
+               };
                1523FE621595048900661E82 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ALWAYS_SEARCH_USER_PATHS = NO;
                                CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
                                CLANG_CXX_LIBRARY = "libc++";
-                               CLANG_ENABLE_MODULES = YES;
                                CLANG_ENABLE_OBJC_ARC = YES;
                                CLANG_WARN_BOOL_CONVERSION = YES;
                                CLANG_WARN_CONSTANT_CONVERSION = YES;
                                ALWAYS_SEARCH_USER_PATHS = NO;
                                CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
                                CLANG_CXX_LIBRARY = "libc++";
-                               CLANG_ENABLE_MODULES = YES;
                                CLANG_ENABLE_OBJC_ARC = YES;
                                CLANG_WARN_BOOL_CONVERSION = YES;
                                CLANG_WARN_CONSTANT_CONVERSION = YES;
                                ALWAYS_SEARCH_USER_PATHS = NO;
                                CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
                                CLANG_CXX_LIBRARY = "libc++";
-                               CLANG_ENABLE_MODULES = YES;
                                CLANG_ENABLE_OBJC_ARC = YES;
                                CLANG_WARN_BOOL_CONVERSION = YES;
                                CLANG_WARN_CONSTANT_CONVERSION = YES;
                1873301718CBD4A700275344 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               CODE_SIGN_ENTITLEMENTS = zprint.tproj/entitlements.plist;
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                               );
                                HEADER_SEARCH_PATHS = (
+                                       "$(SDKROOT)/$(SYSTEM_LIBRARY_DIR)/Frameworks/Kernel.framework/PrivateHeaders/mach",
                                        "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders",
                                        "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders/bsd",
                                );
                1873301818CBD4A700275344 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = lsmp.tproj/entitlements.plist;
+                               "CODE_SIGN_ENTITLEMENTS[sdk=*]" = lsmp.tproj/entitlements.plist;
                                GCC_TREAT_WARNINGS_AS_ERRORS = YES;
                                HEADER_SEARCH_PATHS = "";
                                INSTALL_PATH = /usr/local/bin;
                                ALWAYS_SEARCH_USER_PATHS = NO;
                                CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
                                CLANG_CXX_LIBRARY = "libc++";
-                               CLANG_ENABLE_MODULES = YES;
                                CLANG_ENABLE_OBJC_ARC = YES;
                                CLANG_WARN_BOOL_CONVERSION = YES;
                                CLANG_WARN_CONSTANT_CONVERSION = YES;
                                ALWAYS_SEARCH_USER_PATHS = NO;
                                CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
                                CLANG_CXX_LIBRARY = "libc++";
-                               CLANG_ENABLE_MODULES = YES;
                                CLANG_ENABLE_OBJC_ARC = YES;
                                CLANG_WARN_BOOL_CONVERSION = YES;
                                CLANG_WARN_CONSTANT_CONVERSION = YES;
                                ALWAYS_SEARCH_USER_PATHS = NO;
                                CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
                                CLANG_CXX_LIBRARY = "libc++";
-                               CLANG_ENABLE_MODULES = YES;
                                CLANG_ENABLE_OBJC_ARC = YES;
                                CLANG_WARN_BOOL_CONVERSION = YES;
                                CLANG_WARN_CONSTANT_CONVERSION = YES;
                                AXLE_ENABLE_DEBUG_INFO = NO;
                                CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
                                CLANG_CXX_LIBRARY = "libc++";
-                               CLANG_ENABLE_MODULES = YES;
                                CLANG_ENABLE_OBJC_ARC = YES;
                                CLANG_WARN_ASSIGN_ENUM = YES;
                                CLANG_WARN_BOOL_CONVERSION = YES;
                                AXLE_ENABLE_DEBUG_INFO = YES;
                                CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
                                CLANG_CXX_LIBRARY = "libc++";
-                               CLANG_ENABLE_MODULES = YES;
                                CLANG_ENABLE_OBJC_ARC = YES;
                                CLANG_WARN_ASSIGN_ENUM = YES;
                                CLANG_WARN_BOOL_CONVERSION = YES;
                        };
                        name = Release;
                };
+               97999D2B1AE84C0E00E8B10F /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               HEADER_SEARCH_PATHS = "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders";
+                               INSTALL_PATH = /usr/bin;
+                               PRODUCT_NAME = lskq;
+                       };
+                       name = Release;
+               };
+               97999D2C1AE84C0E00E8B10F /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               HEADER_SEARCH_PATHS = "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders";
+                               INSTALL_PATH = /usr/bin;
+                               PRODUCT_NAME = lskq;
+                       };
+                       name = Debug;
+               };
                ADA9007617679A8C00161ADF /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                BA0A860F13968E8500D2272C /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
+                               CODE_SIGN_ENTITLEMENTS = zprint.tproj/entitlements.plist;
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                               );
                                HEADER_SEARCH_PATHS = (
+                                       "$(SDKROOT)/$(SYSTEM_LIBRARY_DIR)/Frameworks/Kernel.framework/PrivateHeaders/mach",
                                        "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders",
                                        "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders/bsd",
                                );
                C96F50B615BDCEC3008682F7 /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = lsmp.tproj/entitlements.plist;
+                               "CODE_SIGN_ENTITLEMENTS[sdk=*]" = lsmp.tproj/entitlements.plist;
                                GCC_TREAT_WARNINGS_AS_ERRORS = YES;
                                HEADER_SEARCH_PATHS = "";
                                INSTALL_PATH = /usr/bin;
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
+               08DC488B1A12C21C008AAF38 /* Build configuration list for PBXNativeTarget "kpgo" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               08DC48891A12C21C008AAF38 /* Release */,
+                               08DC488A1A12C21C008AAF38 /* Debug */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                1523FE611595048900661E82 /* Build configuration list for PBXNativeTarget "ltop" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               97999D2A1AE84C0E00E8B10F /* Build configuration list for PBXNativeTarget "lskq" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               97999D2B1AE84C0E00E8B10F /* Release */,
+                               97999D2C1AE84C0E00E8B10F /* Debug */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                ADA9007517679A8C00161ADF /* Build configuration list for PBXNativeTarget "purge" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
index 5c5b3fe2203151adb8cfd7d430247a38c8922b60..d860ee0ec950fb189fd0d693d86f48f531e486e4 100644 (file)
 .\" Copyright (c) 2010, Apple Inc.  All rights reserved.
 .\"
-.Dd October 28, 2010
+.Dd April 3, 2015
 .Dt TRACE 1
 .Os "Mac OS X"
 .Sh NAME
 .Nm trace
-.Nd configure and record kernel trace events
+.Nd configure, record, and display kernel trace events
 .Sh SYNOPSIS
-.Nm trace
-.Fl h
+.Bl -hang -compact -width "trace -"
+.\"
+.It Nm Fl d
+.Op Fl a Ar pid | Fl x Ar pid
+.\"
+.It Nm Fl e
+.Op Fl c Ar class Oo Fl p Ar end-class Oc Oo Fl s Ar subclass Oc
+.Op Fl a Ar pid | Fl x Ar pid
+.Op Fl k Ar code
+.Op Fl P
+.Op Fl T Ar filter-file
+.\"
+.It Nm Fl E
+.Op Fl c Ar class Oo Fl p Ar end-class Oc Oo Fl s Ar subclass Oc
+.Op Fl a Ar pid | Fl x Ar pid
+.Op Fl k Ar code
+.Op Fl P
+.Op Fl T Ar tracefilter
+.Ar command
+.Op Ar argument ...
+.\"
+.It Nm Fl h
+.\"
+.It Nm Fl i
+.Op Fl b Ar num-events
+.\"
+.It Nm Fl g
+.\"
+.It Nm Fl l Ar rawfile
+.\"
+.It Nm Fl L Ar rawfile
+.Op Fl S Ar secs
+.\"
+.It Nm Fl n
+.\"
+.It Nm Fl r
+.\"
+.It Nm Fl R Ar rawfile
+.Op Fl X
+.Op Fl F Ar frequency
+.Op Fl o Ar outfile
+.Op Fl N
+.Op Ar codesfile ...
+.\"
+.It Nm Fl t
+.Op Fl o Ar outfile
+.Op Fl N
+.Op Ar codesfile ...
+.El
+.Sh DESCRIPTION
+.Nm
+initializes and configures the kernel trace subsystem.  Trace events can
+be recorded to an in-memory buffer or logged directly to a file, and
+optionally converted to a human-readable, plain-text format.
 .Pp
-.Nm trace
-.Fl i
-.Op Fl b Ar numbufs
+.Nm
+operates according to the command flag specified.
+.Sh COMMANDS
+.Bl -tag -width Ds
+.It Fl h
+Print a succinct help message to
+.Xr stdout 4 .
+.\"
+.\"     ## trace -i ##
+.It Fl i Op Fl b Ar num-events
 .Pp
-.Nm trace
-.Fl g
+Initialize the kernel trace buffer.  This command is required before
+tracing.
+.Bl -tag -width Ds
+.It Fl b Ar num-events
+Set the number of events that can be stored in the kernel trace buffer.
+.Ar num-events
+is a decimal number of events.  The default (and minimum) value is 8192
+event records per logical CPU.  No more than half of available
+memory may be used by trace buffers, though running with a buffer this
+large is not recommended.
+.El
+.\"
+.\"     ## trace -g ##
+.It Fl g
+Print the current kernel trace buffer settings to
+.Xr stdout 4 .
+.\"
+.\"     ## trace -d ##
+.It Fl d Op Fl a Ar pid | Fl x Ar pid
 .Pp
-.Nm trace
-.Fl d
+By default, disable collection of events.  This command does not remove
+the kernel trace buffer.
+.Bl -tag -width Ds
+.It Fl a Ar pid
+Disable event collection for the process identified by
+.Ar pid .
+.It Fl x Ar pid
+Stop excluding
+.Ar pid
+from the trace.
+This reenables event collection of events for.
+.Ar pid .
+.El
+.\"
+.\"     ## trace -r ##
+.It Fl r
+Remove the kernel trace buffer.
+.\"
+.\"     ## trace -n ##
+.It Fl n
+Disable ring buffer mode.  When set, the trace buffer will fill to capacity
+and then stop collecting events.  Ring buffer mode is sometimes called
+"head," "stop," or "no-wrap" mode.  By default, the trace buffer will
+wrap around, overwriting previous events.  The default behavior is
+sometimes called windowed or wrap-around mode.
+.\"
+.\"     ## trace -e ##
+.Bk -words
+.It Xo Fl e
+.Op Fl c Ar class Oo Fl p Ar end-class Oc Oo Fl s Ar subclass Oc
 .Op Fl a Ar pid | Fl x Ar pid
+.Op Fl k Ar code ...
+.Op Fl P
+.Op Fl T Ar filter-file
+.Ek
+.Xc
 .Pp
-.Nm trace
-.Fl r
+Enable collection of events.  By default, all events are collected.
 .Pp
-.Nm trace
-.Fl n
+Options can be used to restrict collection to specific classes, class
+ranges, subclasses, and codes.  Classes and subclasses can be specified
+any number of times, but only 4 codes can be filtered at once.  Values
+can be specified in hex (0x...), decimal, or octal (0...).
+.Bl -tag -width " "
+.It Fl c Ar class
+Restrict collection to the events with the specified
+.Ar class .
+This option can be specified any number of times to collect events from
+more classes.
+.Bl -tag -width " "
+.It Fl p Ar end-class
+Provide an ending class to restrict collection to events in an inclusive
+range of classes between
+.Ar class
+and
+.Ar end-class .
+.It Fl s Ar subclass
+Restrict collection to the events with the specified
+.Ar subclass .
+.El
+.It Fl a Ar pid
+Restrict collection to to those events emitted by the process identified
+by
+.Ar pid .
+.It Fl x Ar pid
+Exclude events emitted by the process identified by
+.Ar pid .
+.It Fl k Ar code
+Restrict collection to events with the specified
+.Ar code .
+This option can be specified up to 4 times, and applies to all classes
+being collected.
+.It Fl T Ar filter-file
+Restrict collection to events specified in the provided
+.Ar filter-file .
+See
+.Sx TRACEFILTER FORMAT
+for details.
+.It Xo Fl P
+Restrict collection to PPT events.  This special collection of trace
+events provides insight into system performance.
+.Xc
+.El
+.\"
+.\"     ## trace -E ##
+.Bk -words
+.It Xo Fl E
+.Op Fl c Ar class Oo Fl p Ar end-class Oc Oo Fl s Ar subclass Oc
+.Op Fl a Ar pid | Fl x Ar pid
+.Op Fl k Ar code ...
+.Op Fl P
+.Op Fl T Ar filter-file
+.Ar command Op args ...
+.Ek
+.Xc
 .Pp
-.Nm trace
+Execute
+.Ar command
+with trace collection enabled for events emitted by the process.  See
 .Fl e
-.Op Fl c Ar class Oo Fl p Ar class Oc Oo Fl s Ar subclass Oc
-.Op Fl a Ar pid | Fl x Ar pid
-.Op Fl k Ar code | Fl k Ar code | Fl k Ar code | Fl k Ar code
+for more information.
+.\"
+.\"     ## trace -t ##
+.It Fl t Oo Fl o Ar outfile Oc Oo Fl N Oc Oo Ar codesfile ... Oc
 .Pp
-.Nm trace
-.Fl E
-.Op Fl c Ar class Oo Fl p Ar class Oc Oo Fl s Ar subclass Oc
-.Op Fl a Ar pid | Fl x Ar pid
-.Op Fl k Ar code | Fl k Ar code | Fl k Ar code | Fl k Ar code
-.Ar executable_path
-.Op Ar optional args to executable
+Extract events from the kernel trace buffer and print them in a formatted,
+plain-text representation.  Additional code files can be specified to
+help
+.Nm
+find the names of unknown events.  For more information on the formatting
+process, see
+.Sx TRACE CODES FORMAT .
+.Bl -tag -width Ds
+.It Fl o Ar outfile
+Output the plain-text events to
+.Ar outfile .
+.It Fl N
+Ignore the system-wide trace codes file when getting names of events.
+Additional trace codes files specified will still be used.
+.El
+.\"
+.\"     ## trace -l ##
+.It Fl l Ar rawfile
 .Pp
-.Nm trace
+Empty the current kernel trace buffer into
+.Ar rawfile
+in a binary format.
+.\"
+.\"     ## trace -L ##
+.It Fl L Ar rawfile Fl S Ar seconds
+.Pp
+Copy the current trace buffer to
+.Ar rawfile
+and send all future trace events to 
+.Ar rawfile .
+.Bl -tag -width Ds
+.It Fl S Ar seconds
+After 
+.Ar seconds
+have elapsed, stop recording and exit.
+.El
+.\"
+.\"     ## trace -R ##
+.It Fl R Ar rawfile Oo Fl o Ar outfile Oc Oo Fl N Oc Oo Fl F Ar frequency Oc Oo Fl X Oc Op Ar codesfile ...
+.Pp
+Read events from
+.Ar rawfile
+and print them in a human-readable format.  
+.Bl -tag -width " "
+.It Fl F Ar frequency
+If
+.Ar rawfile
+does not contain clock frequency information, it can be specified with
+.Fl F .
+.It Fl X
+Force the binary format to be interpreted as 32-bit, as opposed to
+matching the width of the system running
+.Nm .
+.El
+.Pp
+See
 .Fl t
-.Op Fl R Ar rawfile
-.Op Fl o Ar OutputFilename
-.Op Fl N
-.Op Ar ExtraCodeFilename1 ExtraCodeFilename2 ...
-.Sh DESCRIPTION
-The
-.Nm trace
-command allows developers to initialize and configure
-the kernel trace subsystem. Trace events can be recorded
-to an in-memory buffer, or logged directly to a file. Raw
-data files can later be decoded to a plaintext format.
+for additional options.
+.El
+.Sh TRACE CODES FORMAT
+Event classes, subclasses, and codes are matched to names using a trace
+codes file.  Any events that cannot be matched will be referred to by
+their debugid in hex.
+.Pp
+The system-wide trace codes file is located at
+.Pa /usr/share/misc/trace.codes .
+Additional files are typically stored in
+.Pa /usr/local/share/misc .
+.Pp
+A code file consists of a list of tracepoints, one per line, with the
+tracepoint's debugid (component, subclass, and code) in hex, followed by
+a tab, followed by the tracepoint's name.
+.Pp
+For instance, the MSC_mach_msg_trap tracepoint is defined by
+.Pp
+.Dl 0x010c007c MSC_mach_msg_trap
+.Pp
+This describes the tracepoint with the following info:
+.Pp
+.Bl -column -offset indent "Subclass" "MSC_mach_msg_trap"
+.\" is this right?  We should refer to the shifting and kdebug.h
+.It Sy Name Ta MSC_mach_msg_trap
+.It Sy Class Ta 0x01 Ta (Mach events)
+.It Sy Subclass Ta 0x0c Ta (Mach system calls)
+.It Sy Code Ta 0x007c Ta (msg_trap)
+.El
+.Pp
+See
+.\" this absolute path no longer exists thanks to SDKs. :P
+.Pa /usr/include/sys/kdebug.h
+for class and subclass values.
+.Sh TRACEFILTER FORMAT
+A tracefilter description file consists of a list of class and subclass
+filters in hex, one per line, which are applied as if they were passed
+with
+.Fl c
+and
+.Fl s .
+Pass
+.Fl v
+to see what classes and subclasses are being set.
+.Pp
+Comment lines start with
+.Ql # ,
+class filter lines start with
+.Ql C ,
+and subclass filter lines start with
+.Ql S
+and include the class they apply to.
+.Pp
+For example, to trace Mach events (class 1):
+.Pp
+.Dl C 0x01
+.Pp
+And to trace Mach system calls (class 1, subclass 13):
+.Pp
+.Dl S 0x010C
+.Pp
+.Sh EXAMPLES
+.Nm
+usually requires multiple invocations in order to set up the trace
+buffers, enable the correct events, and collect the events.  A typical
+session with trace is:
+.Pp
+.Dl trace -i
+.Dl trace -e -c 1 -s 31
+.Dl sleep 1
+.Dl trace -d
+.Dl trace -t
+.Pp
+This initializes the trace buffers to their default values, enables the
+mach_msg_trap subclass of the MACH_SysCall class, waits for one second,
+then disables tracing and prints it to
+.Xr stdout 4 .
+This is useful for investigating isolated issues or gaining some
+understanding about a kernel subsystem.  If a specific execuable should
+be traced, with the events saved for later analysis, the sequence of
+commands would be:
+.Pp
+.Dl trace -i
+.Dl trace -E -c 0x4 ./my_prog
+.Dl trace -d
+.Dl trace -l tracefile
+.Dl trace -R tracefile
+.Pp
+This initializes the trace buffers, enables all events in the BSC_SysCall class and runs
+.Li my_prog ,
+disables tracing, collects events into
+.Li tracefile ,
+and finally prints those events out in a human-readable form.
+.Sh CAVEATS
+Almost all
+.Nm
+command flags require superuser (root) privileges.
+.Pp
+After failures, the trace buffers usually need to be re-initialized.
+.Pp
+.Sh DIAGNOSTICS
+.Ex -std
 .Sh SEE ALSO
+.Xr trace 4 ,
 .Xr fs_usage 1 ,
 .Xr sc_usage 1 ,
 .Xr latency 1 ,
index 59d657f56ca94d819e74efca58135eedbeffc443..d6648901312c292f77536fbee28116278ea6901b 100644 (file)
 #include <err.h>
 #include <stdarg.h>
 #include <inttypes.h>
+#include <spawn.h>
+#include <assert.h>
+#include <signal.h>
+#include <sysexits.h>
 
 #include <libutil.h>
 
@@ -93,6 +97,7 @@ extern char **environ;
 
 uint8_t* type_filter_bitmap;
 
+#define SIZE_4KB (4 * (1 << 10))
 
 #define DBG_FUNC_ALL           (DBG_FUNC_START | DBG_FUNC_END)
 #define DBG_FUNC_MASK  0xfffffffc
@@ -183,7 +188,6 @@ struct threadmap {
        char            tm_command[MAXCOMLEN + 1];
 };
        
-
 #define HASH_SIZE      1024
 #define HASH_MASK      1023
 
@@ -242,6 +246,7 @@ static void delete_thread_entry(uintptr_t);
 static void find_and_insert_tmp_map_entry(uintptr_t, char *);
 static void create_tmp_map_entry(uintptr_t, uintptr_t);
 static void find_thread_name(uintptr_t, char **, boolean_t);
+static void execute_process(char * const argv[]);
 
 static int  writetrace(int);
 static int  write_command_map(int);
@@ -315,8 +320,12 @@ void set_enable(int val)
 #endif
        mib[4] = 0;
        mib[5] = 0;
-       if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
+       if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0) {
+               if (errno == EINVAL) {
+                       quit_args("trace facility failure, KERN_KDENABLE: trace buffer is uninitialized\n");
+               }
                quit_args("trace facility failure, KERN_KDENABLE: %s\n", strerror(errno));
+       }
 }
 
 void set_remove()
@@ -390,11 +399,20 @@ void set_pidcheck(int pid, int on_off_flag)
        mib[5] = 0;
        if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0)
        {
-               if (on_off_flag == 1)
+               if (errno == EACCES)
+               {
+                       quit_args("trace facility failure, setting pid filter: %s\n",
+                                 strerror(errno));
+               }
+               else if (on_off_flag == 1 && errno == ESRCH)
                {
-                       printf("trace facility failure, KERN_KDPIDTR,\n\tpid %d does not exist\n", pid);
                        set_remove();
-                       exit(2);
+                       quit_args("trace facility failure, setting pid filter: "
+                                 "pid %d does not exist\n", pid);
+               }
+               else
+               {
+                       quit_args("trace facility failure, KERN_KDPIDTR: %s\n", strerror(errno));
                }
        }
 }
@@ -703,15 +721,13 @@ uint64_t consume_start_event(uintptr_t thread, int debugid, uint64_t now)
 void
 log_trace()
 {
-        char           *buffer;
-       uint32_t        buffer_size;
-       int             fd;
-       int             size;
-       int             pad_size;
-       char            pad_buf[4096];
+       int fd = -1;
+       int ret = 0;
+       char *buffer;
+       uint32_t buffer_size = 1000000 * sizeof(kd_buf);
 
-
-       if ((fd = open(logfile, O_TRUNC|O_WRONLY|O_CREAT, 0777)) == -1) {
+       fd = open(logfile, O_TRUNC | O_WRONLY | O_CREAT, 0777);
+       if (fd == -1) {
                perror("Can't open logfile");
                exit(1);
        }
@@ -729,47 +745,33 @@ log_trace()
                else
                        printf("Buffer has not wrapped\n");
        }
-       buffer_size = 1000000 * sizeof(kd_buf);
-       buffer = malloc(buffer_size);
-
-       if (buffer == (char *) 0)
-               quit("can't allocate memory for tracing info\n");
-
-       read_command_map(0, 0);
-       read_cpu_map(0);
-
-       raw_header.version_no = RAW_VERSION1;
-       raw_header.thread_count = total_threads;
-       raw_header.TOD_secs = time((long *)0);
-       raw_header.TOD_usecs = 0;
-
-       write(fd, &raw_header, sizeof(RAW_header));
-
-       size = total_threads * sizeof(kd_threadmap);
-       write(fd, (char *)mapptr, size);
 
-       pad_size = 4096 - ((sizeof(RAW_header) + size) & 4095);
-
-       if (cpumap_header) {
-               size_t cpumap_size = sizeof(kd_cpumap_header) + cpumap_header->cpu_count * sizeof(kd_cpumap);
-               if (pad_size >= cpumap_size) {
-                       write(fd, (char *)cpumap_header, cpumap_size);
-                       pad_size -= cpumap_size;
-               }
+       ret = write_command_map(fd);
+       if (ret) {
+               close(fd);
+               perror("failed to write logfile");
+               exit(1);
        }
 
-       memset(pad_buf, 0, pad_size);
-       write(fd, pad_buf, pad_size);
+       buffer = malloc(buffer_size);
+       if (buffer == NULL) {
+               quit("can't allocate memory for events\n");
+       }
 
        for (;;) {
                needed = buffer_size;
 
                readtrace(buffer);
 
-               if (needed == 0)
+               if (needed == 0) {
                        break;
+               }
+
                write(fd, buffer, needed * sizeof(kd_buf));
        }
+
+       free(buffer);
+
        close(fd);
 }
 
@@ -836,35 +838,9 @@ Log_trace()
                set_enable(1);
 
        if (write_command_map(fd)) {
-               int  pad_size;
-               char pad_buf[4096];
-
-               read_command_map(0, 0);
-               read_cpu_map(0);
-
-               raw_header.version_no = RAW_VERSION1;
-               raw_header.thread_count = total_threads;
-               raw_header.TOD_secs = time((long *)0);
-               raw_header.TOD_usecs = 0;
-
-               write(fd, &raw_header, sizeof(RAW_header));
-
-               size = total_threads * sizeof(kd_threadmap);
-               write(fd, (char *)mapptr, size);
-
-               pad_size = 4096 - ((sizeof(RAW_header) + size) & 4095);
-
-               if (cpumap_header) {
-                       size_t cpumap_size = sizeof(kd_cpumap_header) + cpumap_header->cpu_count * sizeof(kd_cpumap);
-                       if (pad_size >= cpumap_size) {
-                               write(fd, (char *)cpumap_header, cpumap_size);
-                               pad_size -= cpumap_size;
-                       }
-               }
-
-               memset(pad_buf, 0, pad_size);                   
-               write(fd, pad_buf, pad_size);
+               quit("can't write tracefile header\n");
        }
+
        sample_window_abs = (uint64_t)((double)US_TO_SLEEP * divisor);
 
        next_window_begins = mach_absolute_time() + sample_window_abs;
@@ -1301,7 +1277,6 @@ char **env;
 {
        extern char *optarg;
        extern int optind;
-       int status;
        int ch;
        int i;
        char *output_filename = NULL;
@@ -1520,21 +1495,21 @@ char **env;
                if (pid_flag)
                {
                        set_pidcheck(pid, 0);   /* disable pid check for given pid */
-                       exit(1);
+                       exit(0);
                }
                else if (pid_exflag)
                {
                        set_pidexclude(pid, 0);  /* disable pid exclusion for given pid */
-                       exit(1);
+                       exit(0);
                }
                set_enable(0);
-               exit(1);
+               exit(0);
        }
 
        if (remove_flag)
        {
                set_remove();
-               exit(1);
+               exit(0);
        }
     
        if (bufset_flag )
@@ -1634,26 +1609,8 @@ char **env;
                fflush(stdout);
                fflush(stderr);
 
-               switch ((pid = vfork()))
-               {
-               case -1:
-                       perror("vfork: ");
-                       exit(1);
-               case 0: /* child */
-                       setsid();
-                       ptrace(PT_TRACE_ME, 0, (caddr_t)0, 0);
-                       execve(argv[optind], &argv[optind], environ);
-                       perror("execve:");
-                       exit(1);
-               }
-               sleep(1);
+               execute_process(&(argv[optind]));
 
-               signal(SIGINT, signal_handler);
-               set_pidcheck(pid, 1);
-               set_enable(1);
-               ptrace(PT_CONTINUE, pid, (caddr_t)1, 0);
-               waitpid(pid, &status, 0);
-               /* child is gone; no need to disable the pid */
                exit(0);
        }
        else if (enable_flag)
@@ -1695,6 +1652,49 @@ char **env;
 
 } /* end main */
 
+static void
+execute_process(char * const argv[])
+{
+       int status = 0;
+       int rc = 0;
+       posix_spawnattr_t spawn_attrs;
+
+       assert(argv);
+
+       /* ensure that the process being spawned starts suspended */
+       rc = posix_spawnattr_init(&spawn_attrs);
+       if (rc != 0) {
+               quit_args("Failed to initialize spawn attrs: %s\n", strerror(rc));
+       }
+       rc = posix_spawnattr_setflags(&spawn_attrs,
+                                     POSIX_SPAWN_START_SUSPENDED);
+       if (rc != 0) {
+               quit_args("Unable to start process suspended: %s\n", strerror(rc));
+       }
+
+       /* spawn the process with the rest of the arguments */
+       rc = posix_spawnp(&pid, argv[0], NULL, &spawn_attrs, argv, environ);
+       if (rc != 0) {
+               quit_args("Unabled to start process: %s\n", strerror(rc));
+       }
+
+       signal(SIGINT, signal_handler);
+       set_pidcheck(pid, 1);
+       set_enable(1);
+
+       /* start the child process */
+       rc = kill(pid, SIGCONT);
+       if (rc != 0) {
+               perror("Failed to continue child process:");
+               exit(EX_OSERR);
+       }
+
+       rc = waitpid(pid, &status, 0);
+       if (rc == -1) {
+               perror("Failed to wait for process: ");
+       }
+}
+
 static void
 quit_args(const char *fmt, ...) 
 {
@@ -2512,11 +2512,10 @@ read_cpu_map(int fd)
                 * cpu maps exist in a RAW_VERSION1+ header only
                 */
                if (raw_header.version_no == RAW_VERSION1) {
-                       off_t base_offset = lseek(fd, (off_t)0, SEEK_CUR);
-                       off_t aligned_offset = (base_offset + (4095)) & ~4095; /* <rdar://problem/13500105> */
-                       
-                       size_t padding_bytes = (size_t)(aligned_offset - base_offset);
-                       
+                       off_t cpumap_position = lseek(fd, 0, SEEK_CUR);
+            /* cpumap is part of the last 4KB of padding in the preamble */
+                       size_t padding_bytes = SIZE_4KB - (cpumap_position & (SIZE_4KB - 1));
+
                        if (read(fd, cpumap_header, padding_bytes) == padding_bytes) {
                                if (cpumap_header->version_no == RAW_VERSION1) {
                                        cpumap = (kd_cpumap*)&cpumap_header[1];
@@ -2630,6 +2629,7 @@ read_command_map(int fd, uint32_t count)
                                mapptr[i].command);
                }
        }
+
        return (int)size;
 }
 
index e0a0176b08a55b44b652ddf7dbfabe00eb6c706a..6b921d15997716c04423653288ce20a6a6cd4b69 100755 (executable)
@@ -67,16 +67,23 @@ if [ $? -ne 0 ]; then
     exit 1
 fi
 
-if [[ "${PLATFORM_NAME}" == "iphoneos"* ]]; then
+case "$PLATFORM_NAME" in
+iphone*|appletv*|watch*)
     mkdir -p "${PRIVATEDIR}/var/db"
     mkdir -p -m a+rx "${PRIVATEDIR}/var/db/timezone"
 
     # This link must precisely start with TZDIR followed by a slash. radar:13532660
     ln -hfs "/var/db/timezone/zoneinfo/${LOCALTIME}" "${PRIVATEDIR}/var/db/timezone/localtime"
-else
+    ;;
+macosx)
     mkdir -p "${PRIVATEDIR}/etc"
     ln -hfs "/usr/share/zoneinfo/${LOCALTIME}" "${PRIVATEDIR}/etc/localtime"
-fi
+    ;;
+*)
+    echo "Unsupported platform: $PLATFORM_NAME"
+    exit 1
+    ;;
+esac
 
 rm -f "${VERSIONFILE}"
 echo ${DATVERS} > "${VERSIONFILE}"
index ed372b4331e8b54ab542ac874a64c6f5a97010e8..94846aad3e1de887409f1fa07cc5ebd687c7b1c2 100755 (executable)
@@ -1,8 +1,17 @@
 #!/bin/sh
+set -e
+set -x
 
-if [[ "${PLATFORM_NAME}" == "iphoneos"* ]]; then
-ditto "${BUILT_PRODUCTS_DIR}/zoneinfo" "${DSTROOT}/usr/share/zoneinfo.default"
-ln -hfs "/var/db/timezone/zoneinfo" "${DSTROOT}/usr/share/zoneinfo"
-else
-ditto "${BUILT_PRODUCTS_DIR}/zoneinfo" "${DSTROOT}/usr/share/zoneinfo"
-fi
+case "$PLATFORM_NAME" in
+iphone*|appletv*|watch*)
+    ditto "${BUILT_PRODUCTS_DIR}/zoneinfo" "${DSTROOT}/usr/share/zoneinfo.default"
+    ln -hfs "/var/db/timezone/zoneinfo" "${DSTROOT}/usr/share/zoneinfo"
+    ;;
+macosx)
+    ditto "${BUILT_PRODUCTS_DIR}/zoneinfo" "${DSTROOT}/usr/share/zoneinfo"
+    ;;
+*)
+    echo "Unsupported platform: $PLATFORM_NAME"
+    exit 1
+    ;;
+esac
diff --git a/zprint.tproj/entitlements.plist b/zprint.tproj/entitlements.plist
new file mode 100644 (file)
index 0000000..50ad69c
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>com.apple.system-task-ports</key>
+       <true/>
+       <key>task_for_pid-allow</key>
+       <true/>
+    <key>com.apple.private.kernel.get-kext-info</key>
+    <true/>
+</dict>
+</plist>
index 74a7d5830a620eaa48f808e7baf7955facc7d56a..fed4172a3b6f94c66ab9fd34e98233f0d8bb71dd 100644 (file)
@@ -65,6 +65,9 @@
  *     to zones but not currently in use.
  */
 
+
+
+#include <vm_statistics.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <mach/mach_error.h>
 #include <libutil.h>
 #include <errno.h>
+#include <sysexits.h>
+#include <getopt.h>
+#include <malloc/malloc.h>
+#include <Kernel/IOKit/IOKitDebug.h>
+#include <Kernel/libkern/OSKextLibPrivate.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOKitKeys.h>
+#include <IOKit/kext/OSKext.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreSymbolication/CoreSymbolication.h>
+
+
+
 
 #define streql(a, b)           (strcmp((a), (b)) == 0)
 #define strneql(a, b, n)       (strncmp((a), (b), (n)) == 0)
+#define        PRINTK(fmt, value)      \
+       printf(fmt "K", (value) / 1024 )        /* ick */
 
 static void usage(void);
 static void printzone(mach_zone_name_t *, task_zone_info_t *);
 static void colprintzone(mach_zone_name_t *, task_zone_info_t *);
 static int  find_deltas(mach_zone_name_t *, task_zone_info_t *, task_zone_info_t *, char *, int, int);
 static void colprintzoneheader(void);
-static boolean_t substr(const char *a, int alen, const char *b, int blen);
+static boolean_t substr(const char *a, size_t alen, const char *b, size_t blen);
+
+static int  SortName(const void * left, const void * right);
+static int  SortSize(const void * left, const void * right);
+static void PrintLarge(mach_memory_info_t *wiredInfo, unsigned int wiredInfoCnt, int (*func)(const void *, const void *), boolean_t column);
 
 static char *program;
 
@@ -93,6 +115,7 @@ static boolean_t ShowPid = FALSE;
 static boolean_t ShowDeltas = FALSE;
 static boolean_t ShowWasted = FALSE;
 static boolean_t ShowTotal = FALSE;
+static boolean_t ShowLarge = TRUE;
 static boolean_t SortZones = FALSE;
 static boolean_t ColFormat = TRUE;
 static boolean_t PrintHeader = TRUE;
@@ -105,7 +128,7 @@ static unsigned long long pidsum = 0;
 static int last_time = 0;
 
 static char    *zname = NULL;
-static int     znamelen = 0;
+static size_t  znamelen = 0;
 
 static void
 sigintr(__unused int signum)
@@ -127,7 +150,8 @@ main(int argc, char **argv)
        unsigned int nameCnt = 0;
        task_zone_info_t *info = NULL;
        unsigned int infoCnt = 0;
-
+       mach_memory_info_t *wiredInfo = NULL;
+       unsigned int wiredInfoCnt = 0;
        task_zone_info_t *max_info = NULL;
        char            *deltas = NULL;
 
@@ -156,6 +180,10 @@ main(int argc, char **argv)
                        ShowWasted = TRUE;
                else if (streql(argv[i], "-W"))
                        ShowWasted = FALSE;
+               else if (streql(argv[i], "-l"))
+                       ShowLarge = TRUE;
+               else if (streql(argv[i], "-L"))
+                       ShowLarge = FALSE;
                else if (streql(argv[i], "-s"))
                        SortZones = TRUE;
                else if (streql(argv[i], "-S"))
@@ -223,13 +251,15 @@ main(int argc, char **argv)
        } else {
            mach_zone_info_t *zinfo = NULL;
 
-           kr = mach_zone_info(mach_host_self(),
-                               &name, &nameCnt, &zinfo, &infoCnt);
+           kr = mach_memory_info(mach_host_self(),
+                               &name, &nameCnt, &zinfo, &infoCnt,
+                               &wiredInfo, &wiredInfoCnt);
            if (kr != KERN_SUCCESS) {
                fprintf(stderr, "%s: mach_zone_info: %s\n",
                        program, mach_error_string(kr));
                exit(1);
            }
+
            kr = vm_allocate(mach_task_self(), (vm_address_t *)&info,
                             infoCnt * sizeof *info, VM_FLAGS_ANYWHERE);
            if (kr != KERN_SUCCESS) {
@@ -266,7 +296,7 @@ main(int argc, char **argv)
        if (SortZones) {
                for (i = 0; i < nameCnt-1; i++)
                        for (j = i+1; j < nameCnt; j++) {
-                               int wastei, wastej;
+                               unsigned long long wastei, wastej;
 
                                wastei = (info[i].tzi_cur_size -
                                          (info[i].tzi_elem_size *
@@ -305,6 +335,11 @@ main(int argc, char **argv)
                                        printzone(&name[i], &info[i]);
                        }
                }
+
+               if (ShowLarge && first_time) {
+                       PrintLarge(wiredInfo, wiredInfoCnt, 
+                                  SortZones ? &SortSize : &SortName, ColFormat);
+               }
        }
 
        first_time = 0;
@@ -329,6 +364,16 @@ main(int argc, char **argv)
                }
        }
 
+       if ((wiredInfo != NULL) && (wiredInfoCnt != 0)) {
+               kr = vm_deallocate(mach_task_self(), (vm_address_t) wiredInfo,
+                                  (vm_size_t) (wiredInfoCnt * sizeof *wiredInfo));
+               if (kr != KERN_SUCCESS) {
+                       fprintf(stderr, "%s: vm_deallocate: %s\n",
+                            program, mach_error_string(kr));
+                       exit(1);
+               }
+       }
+
        if ((ShowWasted||ShowTotal) && PrintHeader && !ShowDeltas) {
                printf("TOTAL SIZE   = %llu\n", totalsize);
                printf("TOTAL USED   = %llu\n", totalused);
@@ -347,7 +392,7 @@ main(int argc, char **argv)
 }
 
 static boolean_t
-substr(const char *a, int alen, const char *b, int blen)
+substr(const char *a, size_t alen, const char *b, size_t blen)
 {
        int i;
 
@@ -406,9 +451,6 @@ printzone(mach_zone_name_t *name, task_zone_info_t *info)
        }
 }
 
-#define        PRINTK(fmt, value)      \
-       printf(fmt "K", (value) / 1024 )        /* ick */
-
 static void
 colprintzone(mach_zone_name_t *zone_name, task_zone_info_t *info)
 {
@@ -533,3 +575,289 @@ find_deltas(mach_zone_name_t *name, task_zone_info_t *info, task_zone_info_t *ma
        }
        return(found_one);
 }
+
+/*********************************************************************
+*********************************************************************/
+
+static char *
+kern_vm_tag_name(uint64_t tag)
+{
+    char * result;
+    const char * name;
+    switch (tag)
+    {
+       case (VM_KERN_MEMORY_NONE):             name = "VM_KERN_MEMORY_NONE"; break;
+       case (VM_KERN_MEMORY_OSFMK):            name = "VM_KERN_MEMORY_OSFMK"; break;
+       case (VM_KERN_MEMORY_BSD):              name = "VM_KERN_MEMORY_BSD"; break;
+       case (VM_KERN_MEMORY_IOKIT):            name = "VM_KERN_MEMORY_IOKIT"; break;
+       case (VM_KERN_MEMORY_LIBKERN):          name = "VM_KERN_MEMORY_LIBKERN"; break;
+       case (VM_KERN_MEMORY_OSKEXT):           name = "VM_KERN_MEMORY_OSKEXT"; break;
+       case (VM_KERN_MEMORY_KEXT):             name = "VM_KERN_MEMORY_KEXT"; break;
+       case (VM_KERN_MEMORY_IPC):              name = "VM_KERN_MEMORY_IPC"; break;
+       case (VM_KERN_MEMORY_STACK):            name = "VM_KERN_MEMORY_STACK"; break;
+       case (VM_KERN_MEMORY_CPU):              name = "VM_KERN_MEMORY_CPU"; break;
+       case (VM_KERN_MEMORY_PMAP):             name = "VM_KERN_MEMORY_PMAP"; break;
+       case (VM_KERN_MEMORY_PTE):              name = "VM_KERN_MEMORY_PTE"; break;
+       case (VM_KERN_MEMORY_ZONE):             name = "VM_KERN_MEMORY_ZONE"; break;
+       case (VM_KERN_MEMORY_KALLOC):           name = "VM_KERN_MEMORY_KALLOC"; break;
+       case (VM_KERN_MEMORY_COMPRESSOR):       name = "VM_KERN_MEMORY_COMPRESSOR";      break;
+       case (VM_KERN_MEMORY_COMPRESSED_DATA):  name = "VM_KERN_MEMORY_COMPRESSED_DATA"; break;
+       case (VM_KERN_MEMORY_PHANTOM_CACHE):    name = "VM_KERN_MEMORY_PHANTOM_CACHE";   break;
+       case (VM_KERN_MEMORY_WAITQ):            name = "VM_KERN_MEMORY_WAITQ"; break;
+       case (VM_KERN_MEMORY_DIAG):             name = "VM_KERN_MEMORY_DIAG"; break;
+       case (VM_KERN_MEMORY_LOG):              name = "VM_KERN_MEMORY_LOG"; break;
+       case (VM_KERN_MEMORY_FILE):             name = "VM_KERN_MEMORY_FILE"; break;
+       case (VM_KERN_MEMORY_MBUF):             name = "VM_KERN_MEMORY_MBUF"; break;
+       case (VM_KERN_MEMORY_UBC):              name = "VM_KERN_MEMORY_UBC"; break;
+       case (VM_KERN_MEMORY_SECURITY):         name = "VM_KERN_MEMORY_SECURITY"; break;
+       case (VM_KERN_MEMORY_MLOCK):            name = "VM_KERN_MEMORY_MLOCK"; break;
+       case (VM_KERN_MEMORY_ANY):              name = "VM_KERN_MEMORY_ANY"; break;
+       default:                                name = NULL; break;
+    }
+    if (name) asprintf(&result, "%s", name);
+    else      asprintf(&result, "VM_KERN_MEMORY_%lld", tag);
+    return (result);
+ }
+
+static char * 
+kern_vm_counter_name(uint64_t tag)
+{
+    char * result;
+    const char * name;
+    switch (tag)
+    {
+       case (VM_KERN_COUNT_MANAGED):           name = "VM_KERN_COUNT_MANAGED"; break;
+       case (VM_KERN_COUNT_RESERVED):          name = "VM_KERN_COUNT_RESERVED"; break;
+       case (VM_KERN_COUNT_WIRED):             name = "VM_KERN_COUNT_WIRED"; break;
+       case (VM_KERN_COUNT_WIRED_MANAGED):     name = "VM_KERN_COUNT_WIRED_MANAGED"; break;
+       case (VM_KERN_COUNT_STOLEN):            name = "VM_KERN_COUNT_STOLEN"; break;
+       case (VM_KERN_COUNT_LOPAGE):            name = "VM_KERN_COUNT_LOPAGE"; break;
+       case (VM_KERN_COUNT_MAP_KERNEL):        name = "VM_KERN_COUNT_MAP_KERNEL"; break;
+       case (VM_KERN_COUNT_MAP_ZONE):          name = "VM_KERN_COUNT_MAP_ZONE"; break;
+       case (VM_KERN_COUNT_MAP_KALLOC):        name = "VM_KERN_COUNT_MAP_KALLOC"; break;
+       default:                                name = NULL; break;
+    }
+    if (name) asprintf(&result, "%s", name);
+    else      asprintf(&result, "VM_KERN_COUNT_%lld", tag);
+    return (result);
+}
+
+static void
+MakeLoadTagKeys(const void * key, const void * value, void * context)
+{
+    CFMutableDictionaryRef newDict  = context;
+    CFDictionaryRef        kextInfo = value;
+    CFNumberRef            loadTag;
+    uint32_t               loadTagValue;
+
+    loadTag = (CFNumberRef)CFDictionaryGetValue(kextInfo, CFSTR(kOSBundleLoadTagKey));
+    CFNumberGetValue(loadTag, kCFNumberSInt32Type, &loadTagValue);
+    key = (const void *)(uintptr_t) loadTagValue;
+    CFDictionarySetValue(newDict, key, value);
+}
+
+static CSSymbolicatorRef        gSym;
+static CFMutableDictionaryRef    gTagDict;
+static mach_memory_info_t *  gSites;
+
+static char * 
+GetSiteName(int siteIdx)
+{
+    const char      * name;
+    char            * result;
+    mach_vm_address_t addr;
+    CFDictionaryRef   kextInfo;
+    CFStringRef       bundleID;
+    uint32_t          type;
+
+    const mach_memory_info_t * site;
+    const char                   * fileName;
+    CSSymbolRef                    symbol;
+    const char                   * symbolName;
+    CSSourceInfoRef                sourceInfo;
+
+    name = NULL;
+    result = NULL;
+    site = &gSites[siteIdx];
+    addr = site->site;
+    type = (VM_KERN_SITE_TYPE & site->flags);
+    switch (type)
+    {
+       case VM_KERN_SITE_TAG:
+           result = kern_vm_tag_name(addr);
+           break;
+
+       case VM_KERN_SITE_COUNTER:
+           result = kern_vm_counter_name(addr);
+           break;
+
+       case VM_KERN_SITE_KMOD:
+           kextInfo = CFDictionaryGetValue(gTagDict, (const void *)(uintptr_t) addr);
+           if (kextInfo) 
+           {
+               bundleID = (CFStringRef)CFDictionaryGetValue(kextInfo,  kCFBundleIdentifierKey);
+               name = CFStringGetCStringPtr(bundleID, kCFStringEncodingUTF8);
+           //    wiredSize = (CFNumberRef)CFDictionaryGetValue(kextInfo, CFSTR(kOSBundleWiredSizeKey));
+           }
+           asprintf(&result,  "%-64s%3lld", name ?  name : "(unknown kmod)", addr);
+           break;
+
+       case VM_KERN_SITE_KERNEL:
+           symbolName = NULL;
+           if (addr)
+           {
+               symbol = CSSymbolicatorGetSymbolWithAddressAtTime(gSym, addr, kCSNow);
+               symbolName = CSSymbolGetName(symbol);
+           }
+           if (symbolName)
+           {
+               asprintf(&result, "%s", symbolName);
+               sourceInfo = CSSymbolicatorGetSourceInfoWithAddressAtTime(gSym, addr, kCSNow);
+               fileName = CSSourceInfoGetPath(sourceInfo);
+               if (fileName) printf(" (%s:%d)", fileName, CSSourceInfoGetLineNumber(sourceInfo));
+           }
+           else
+           {
+               asprintf(&result, "site 0x%qx", addr);
+           }
+           break;
+       default:
+           asprintf(&result, "");
+           break;
+    }
+
+     return (result);
+}
+
+static int 
+SortName(const void * left, const void * right)
+{
+    const int * idxL;
+    const int * idxR;
+    char * l;
+    char * r;
+    int result;
+
+    idxL = (typeof(idxL)) left;
+    idxR = (typeof(idxR)) right;
+    l = GetSiteName(*idxL);
+    r = GetSiteName(*idxR);
+
+    result = strcmp(l, r);
+    free(l);
+    free(r);
+
+    return (result);
+}
+
+static int 
+SortSize(const void * left, const void * right)
+{
+    const mach_memory_info_t * siteL;
+    const mach_memory_info_t * siteR;
+    const int * idxL;
+    const int * idxR;
+
+    idxL = (typeof(idxL)) left;
+    idxR = (typeof(idxR)) right;
+    siteL = &gSites[*idxL];
+    siteR = &gSites[*idxR];
+
+    if (siteL->size > siteR->size) return (-1);
+    else if (siteL->size < siteR->size) return (1);
+    return (0);
+}
+
+
+static void
+PrintLarge(mach_memory_info_t *wiredInfo, unsigned int wiredInfoCnt,
+               int (*func)(const void *, const void *), boolean_t column)
+{
+    uint64_t zonetotal;
+    uint64_t top_wired;
+
+    CFDictionaryRef allKexts;
+    unsigned int idx, site, first;
+    int sorted[wiredInfoCnt];
+    char totalstr[40];
+    char * name;
+
+    zonetotal = totalsize;
+
+    gSites = wiredInfo;
+
+    gSym = CSSymbolicatorCreateWithMachKernel();
+   
+    allKexts = OSKextCopyLoadedKextInfo(NULL, NULL);
+    gTagDict = CFDictionaryCreateMutable( 
+                           kCFAllocatorDefault, (CFIndex) 0,
+                           (CFDictionaryKeyCallBacks *) 0,
+                           &kCFTypeDictionaryValueCallBacks);
+
+    CFDictionaryApplyFunction(allKexts, &MakeLoadTagKeys, gTagDict);
+    CFRelease(allKexts);
+
+    top_wired = 0;
+
+    for (idx = 0; idx < wiredInfoCnt; idx++) sorted[idx] = idx;
+    first = 0; // VM_KERN_MEMORY_FIRST_DYNAMIC
+    qsort(&sorted[first],
+           wiredInfoCnt - first, 
+           sizeof(sorted[0]), 
+           func);
+
+    printf("-------------------------------------------------------------------------------------------------------------\n");
+    printf("                                                               kmod          vm                       cur\n");
+    printf("wired memory                                                     id         tag                      size\n");
+    printf("-------------------------------------------------------------------------------------------------------------\n");
+
+    for (idx = 0; idx < wiredInfoCnt; idx++) 
+    {
+        site = sorted[idx];
+       if (!gSites[site].size) continue;
+       if (VM_KERN_COUNT_WIRED == gSites[site].site) top_wired = gSites[site].size;
+       if (VM_KERN_SITE_HIDE & gSites[site].flags) continue;
+       if (!(VM_KERN_SITE_WIRED & gSites[site].flags)) continue;
+
+       name = GetSiteName(site);
+       printf("%-67s", name);
+       free(name);
+       printf("%12d", site);
+
+       printf(" %11s", "");
+       PRINTK(" %12llu", gSites[site].size);
+       totalsize += gSites[site].size;
+
+       printf("\n");
+    }
+
+    printf("%-67s", "zones");
+    printf("%12s", "");
+    printf(" %11s", "");
+    PRINTK(" %12llu", zonetotal);
+    snprintf(totalstr, sizeof(totalstr), "%6.2fM of %6.2fM", totalsize / 1024.0 / 1024.0, top_wired / 1024.0 / 1024.0);
+    printf("\ntotal%100s\n", totalstr);
+
+    printf("-------------------------------------------------------------------------------------------------------------\n");
+    printf("                                                                                    largest\n");
+    printf("maps                                                                       free        free          size\n");
+    printf("-------------------------------------------------------------------------------------------------------------\n");
+
+    for (idx = 0; idx < wiredInfoCnt; idx++) 
+    {
+        site = sorted[idx];
+       if (!gSites[site].size) continue;
+       if (VM_KERN_SITE_HIDE & gSites[site].flags) continue;
+       if (VM_KERN_SITE_WIRED & gSites[site].flags) continue;
+
+       name = GetSiteName(site);
+       printf("%-67s", name);
+       free(name);
+
+       PRINTK(" %10llu", gSites[site].free);
+       PRINTK(" %10llu", gSites[site].largest);
+       PRINTK(" %12llu", gSites[site].size);
+
+       printf("\n");
+    }
+}