--- /dev/null
+#!/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
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
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 */
#define FMT_CHMODAT 44
#define FMT_OPENAT 45
#define FMT_RENAMEAT 46
+#define FMT_IOCTL_SYNCCACHE 47
#define MAX_BSD_SYSCALL 526
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;
columns = MAX_WIDE_MODE_COLS;
break;
+ case 'W':
+ include_waited_flag = 1;
+ break;
+
case 'f':
if (!strcmp(optarg, "network"))
filter_mode |= NETWORK_FILTER;
/* set up signal handlers */
signal(SIGINT, leave);
signal(SIGQUIT, leave);
+ signal(SIGPIPE, leave);
sigaction(SIGHUP, (struct sigaction *)NULL, &osa);
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();
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
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);
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);
}
case FMT_IOCTL_SYNC:
+ {
+ /*
+ * ioctl
+ */
+ clen += printf(" <DKIOCSYNCHRONIZE> B=%d /dev/%s", arg3, find_disk_name(arg1));
+
+ break;
+ }
+
+ case FMT_IOCTL_SYNCCACHE:
{
/*
* ioctl
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;
<!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>
--- /dev/null
+#!/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
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++;
--- /dev/null
+/*
+ * 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;
+
+}
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+.\" 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
--- /dev/null
+/*
+ * 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;
+}
+
<dict>
<key>task_for_pid-allow</key>
<true/>
+ <key>com.apple.system-task-ports</key>
+ <true/>
</dict>
</plist>
/* 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)
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;
}
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(" ");
}
}
mach_port_deallocate(mach_task_self(), threadlist[i]);
}
+ printf("\n");
return kret;
}
#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>
static char *gToolName;
static io_registry_entry_t gOptionsRef;
static bool gUseXML;
+static bool gUseForceSync;
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;
static void NVRamSyncNow(char *name)
{
- SetOFVariable(kIONVRAMSyncNowPropertyKey, name);
+ if (!gUseForceSync) {
+ SetOFVariable(kIONVRAMSyncNowPropertyKey, name);
+ } else {
+ SetOFVariable(kIONVRAMForceSyncNowPropertyKey, name);
+ }
}
// PrintOFVariables()
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 = (
.\" 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 ,
#include <err.h>
#include <stdarg.h>
#include <inttypes.h>
+#include <spawn.h>
+#include <assert.h>
+#include <signal.h>
+#include <sysexits.h>
#include <libutil.h>
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
char tm_command[MAXCOMLEN + 1];
};
-
#define HASH_SIZE 1024
#define HASH_MASK 1023
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);
#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()
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));
}
}
}
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);
}
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);
}
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;
{
extern char *optarg;
extern int optind;
- int status;
int ch;
int i;
char *output_filename = NULL;
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 )
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)
} /* 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, ...)
{
* 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];
mapptr[i].command);
}
}
+
return (int)size;
}
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}"
#!/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
--- /dev/null
+<?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>
* 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;
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;
static int last_time = 0;
static char *zname = NULL;
-static int znamelen = 0;
+static size_t znamelen = 0;
static void
sigintr(__unused int signum)
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;
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"))
} 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) {
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 *
printzone(&name[i], &info[i]);
}
}
+
+ if (ShowLarge && first_time) {
+ PrintLarge(wiredInfo, wiredInfoCnt,
+ SortZones ? &SortSize : &SortName, ColFormat);
+ }
}
first_time = 0;
}
}
+ 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);
}
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;
}
}
-#define PRINTK(fmt, value) \
- printf(fmt "K", (value) / 1024 ) /* ick */
-
static void
colprintzone(mach_zone_name_t *zone_name, task_zone_info_t *info)
{
}
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");
+ }
+}