/*
- * Copyright (c) 1999-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 1999-2020 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <errno.h>
#include <err.h>
#include <libutil.h>
+#include <TargetConditionals.h>
#include <ktrace/session.h>
#include <System/sys/kdebug.h>
-#include <assert.h>
+#include <os/assumes.h>
#include <sys/disk.h>
#include <sys/fcntl.h>
#define BSC_msync_extended 0x040e0104
#define BSC_pread_extended 0x040e0264
#define BSC_pwrite_extended 0x040e0268
+#define BSC_guarded_pwrite_extended 0x040e0798
#define BSC_mmap_extended 0x040e0314
#define BSC_mmap_extended2 0x040f0314
SYSCALL_WITH_NOCANCEL(read, FMT_FD_IO),
SYSCALL_WITH_NOCANCEL(write, FMT_FD_IO),
SYSCALL(guarded_write_np, FMT_FD_IO),
- SYSCALL(guarded_pwrite_np, FMT_FD_IO),
+ SYSCALL(guarded_pwrite_np, FMT_PREAD),
SYSCALL(guarded_writev_np, FMT_FD_IO),
SYSCALL(fgetxattr, FMT_FD),
SYSCALL(fsetxattr, FMT_FD),
mach_to_nano(uint64_t mach)
{
uint64_t nanoseconds = 0;
- assert(ktrace_convert_timestamp_to_nanoseconds(s, mach, &nanoseconds) == 0);
+ os_assert(ktrace_convert_timestamp_to_nanoseconds(s, mach, &nanoseconds) == 0);
return nanoseconds;
}
exit(1);
}
+static void fs_usage_cleanup(const char *message)
+{
+ if (s){
+ ktrace_session_destroy(s);
+ }
+
+ fprintf(stderr, "Cleaning up tracing state because of %s\n", message);
+}
+
int
main(int argc, char *argv[])
{
bool exclude_pids = false;
uint64_t time_limit_ns = 0;
+ os_set_crash_callback(&fs_usage_cleanup);
+
get_screenwidth();
s = ktrace_session_create();
- assert(s != NULL);
+ os_assert(s != NULL);
(void)ktrace_ignore_process_filter_for_event(s, P_WrData);
(void)ktrace_ignore_process_filter_for_event(s, P_RdData);
(void)ktrace_ignore_process_filter_for_event(s, P_WrMeta);
ktrace_exclude_process(s, "csh");
ktrace_exclude_process(s, "sh");
ktrace_exclude_process(s, "zsh");
-#if TARGET_OS_EMBEDDED
+#if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
ktrace_exclude_process(s, "dropbear");
-#endif /* TARGET_OS_EMBEDDED */
+#endif /* (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) */
}
}
fprintf(stderr, "ERROR: cannot both include and exclude simultaneously\n");
exit(1);
} else {
- assert(!rv);
+ os_assert(!rv);
}
argc--;
});
}
+static void
+extend_syscall_rw(th_info_t ti, ktrace_event_t event)
+{
+ ti->arg1 = event->arg1; /* the fd */
+ ti->arg2 = event->arg2; /* nbytes */
+ ti->arg3 = event->arg3; /* top half offset */
+ ti->arg4 = event->arg4; /* bottom half offset */
+}
+
/*
* Handle system call extended trace data.
* pread and pwrite:
switch (type) {
case BSC_mmap_extended:
- if ((ti = event_find(thread, BSC_mmap)) == NULL)
+ if ((ti = event_find(thread, BSC_mmap)) == NULL) {
return;
+ }
ti->arg8 = ti->arg3; /* save protection */
ti->arg1 = event->arg1; /* the fd */
case BSC_msync_extended:
if ((ti = event_find(thread, BSC_msync)) == NULL) {
- if ((ti = event_find(thread, BSC_msync_nocancel)) == NULL)
+ if ((ti = event_find(thread, BSC_msync_nocancel)) == NULL) {
return;
+ }
}
ti->arg4 = event->arg1; /* top half address */
case BSC_pread_extended:
if ((ti = event_find(thread, BSC_pread)) == NULL) {
- if ((ti = event_find(thread, BSC_pread_nocancel)) == NULL)
+ if ((ti = event_find(thread, BSC_pread_nocancel)) == NULL) {
return;
+ }
}
- ti->arg1 = event->arg1; /* the fd */
- ti->arg2 = event->arg2; /* nbytes */
- ti->arg3 = event->arg3; /* top half offset */
- ti->arg4 = event->arg4; /* bottom half offset */
+ extend_syscall_rw(ti, event);
break;
case BSC_pwrite_extended:
if ((ti = event_find(thread, BSC_pwrite)) == NULL) {
- if ((ti = event_find(thread, BSC_pwrite_nocancel)) == NULL)
+ if ((ti = event_find(thread, BSC_pwrite_nocancel)) == NULL) {
return;
+ }
}
- ti->arg1 = event->arg1; /* the fd */
- ti->arg2 = event->arg2; /* nbytes */
- ti->arg3 = event->arg3; /* top half offset */
- ti->arg4 = event->arg4; /* bottom half offset */
+ extend_syscall_rw(ti, event);
+ break;
+
+ case BSC_guarded_pwrite_extended:
+ if ((ti = event_find(thread, BSC_guarded_pwrite_np)) == NULL) {
+ return;
+ }
+
+ extend_syscall_rw(ti, event);
break;
}
}
int
print_open(ktrace_event_t event, uint64_t flags)
{
- char mode[] = "______";
+ char mode[] = {
+ '_',
+ '_',
+ (flags & O_CREAT) ? 'C' : '_',
+ (flags & O_APPEND) ? 'A' : '_',
+ (flags & O_TRUNC) ? 'T' : '_',
+ (flags & O_EXCL) ? 'E' : '_',
+ (flags & O_NONBLOCK) ? 'N' : '_',
+ (flags & O_SHLOCK) ? 'l' : (flags & O_EXLOCK) ? 'L' : '_',
+ (flags & O_NOFOLLOW) ? 'F' : '_',
+ (flags & O_SYMLINK) ? 'S' : '_',
+ (flags & O_EVTONLY) ? 'V' : '_',
+ (flags & O_CLOEXEC) ? 'X' : '_',
+ '\0',
+ };
if (flags & O_RDWR) {
mode[0] = 'R';
mode[0] = 'R';
}
- if (flags & O_CREAT) {
- mode[2] = 'C';
- }
- if (flags & O_APPEND) {
- mode[3] = 'A';
- }
- if (flags & O_TRUNC) {
- mode[4] = 'T';
- }
- if (flags & O_EXCL) {
- mode[5] = 'E';
- }
-
if (event->arg1) {
return printf(" [%3d] (%s) ", (int)event->arg1, mode);
} else {
mach_time_of_first_event = now;
if (format == FMT_DISKIO || format == FMT_DISKIO_CS) {
- assert(dio);
+ os_assert(dio);
} else {
- assert(event);
+ os_assert(event);
if (format != FMT_UNMAP_INFO)
- assert(ti);
+ os_assert(ti);
}
/* <rdar://problem/19852325> Filter out WindowServer/xcpm ioctls in fs_usage */
if (!command_name)
command_name = "";
- assert(now_walltime.tv_sec || now_walltime.tv_usec);
+ os_assert(now_walltime.tv_sec || now_walltime.tv_usec);
/* try and reuse the timestamp string */
if (last_walltime_secs != now_walltime.tv_sec) {
p = "SETLKW";
break;
+ case F_SETLKWTIMEOUT:
+ p = "SETLKWTIMEOUT";
+ break;
+
+ case F_GETLKPID:
+ p = "GETLKPID";
+ break;
+
+ case F_OFD_GETLK:
+ p = "OFD_GETLK";
+ break;
+
+ case F_OFD_SETLK:
+ p = "OFD_SETLK";
+ break;
+
+ case F_OFD_SETLKW:
+ p = "OFD_SETLKW";
+ break;
+
+ case F_OFD_SETLKWTIMEOUT:
+ p = "OFD_SETLKWTIMEOUT";
+ break;
+
+ case F_OFD_GETLKPID:
+ p = "OFD_GETLKPID";
+ break;
+
case F_PREALLOCATE:
p = "PREALLOCATE";
break;
p = "CACHING ON (GLOBAL)";
break;
+ case F_FLUSH_DATA:
+ p = "FLUSH_DATA";
+ break;
+
+ case F_CHKCLEAN:
+ p = "CHKCLEAN";
+ break;
+
+ case F_RDAHEAD:
+ if (ti->arg3) {
+ p = "RDAHEAD ON";
+ } else {
+ p = "RDAHEAD OFF";
+ }
+ break;
+
+ case F_LOG2PHYS:
+ p = "LOG2PHYS";
+ break;
+
+ case F_FREEZE_FS:
+ p = "FREEZE_FS";
+ break;
+
+ case F_THAW_FS:
+ p = "THAW_FS";
+ break;
+
+ case F_ADDSIGS:
+ p = "ADDSIGS";
+ break;
+
+ case F_MARKDEPENDENCY:
+ p = "MARKDEPENDENCY";
+ break;
+
+ case F_ADDFILESIGS:
+ p = "ADDFILESIGS";
+ break;
+
+ case F_NODIRECT:
+ p = "NODIRECT";
+ break;
+
+ case F_GETPROTECTIONCLASS:
+ p = "GETPROTECTIONCLASS";
+ break;
+
+ case F_SETPROTECTIONCLASS:
+ p = "SETPROTECTIONCLASS";
+ break;
+
+ case F_LOG2PHYS_EXT:
+ p = "LOG2PHYS_EXT";
+ break;
+
+ case F_SETSTATICCONTENT:
+ if (ti->arg3) {
+ p = "STATICCONTENT ON";
+ } else {
+ p = "STATICCONTENT OFF";
+ }
+ break;
+
+ case F_MOVEDATAEXTENTS:
+ p = "MOVEDATAEXTENTS";
+ break;
+
+ case F_DUPFD_CLOEXEC:
+ p = "DUPFD_CLOEXEC";
+ break;
+
+ case F_SETBACKINGSTORE:
+ p = "SETBACKINGSTORE";
+ break;
+
+ case F_GETPATH_MTMINFO:
+ p = "GETPATH_MTMINFO";
+ break;
+
+ case F_GETCODEDIR:
+ p = "GETCODEDIR";
+ break;
+
+ case F_SETNOSIGPIPE:
+ p = "SETNOSIGPIPE";
+ break;
+
+ case F_GETNOSIGPIPE:
+ p = "GETNOSIGPIPE";
+ break;
+
+ case F_TRANSCODEKEY:
+ p = "TRANSCODEKEY";
+ break;
+
+ case F_SINGLE_WRITER:
+ p = "SINGLE_WRITER";
+ break;
+
+ case F_GETPROTECTIONLEVEL:
+ p = "GETPROTECTIONLEVEL";
+ break;
+
+ case F_FINDSIGS:
+ p = "FINDSIGS";
+ break;
+
+ case F_GETDEFAULTPROTLEVEL:
+ p = "GETDEFAULTPROTLEVEL";
+ break;
+
+ case F_MAKECOMPRESSED:
+ p = "MAKECOMPRESSED";
+ break;
+
+ case F_SET_GREEDY_MODE:
+ if (ti->arg3) {
+ p = "GREEDY_MODE ON";
+ } else {
+ p = "GREEDY_MODE OFF";
+ }
+ break;
+
+ case F_SETIOTYPE:
+ p = "SETIOTYPE";
+ break;
+
+ case F_ADDFILESIGS_FOR_DYLD_SIM:
+ p = "ADDFILESIGS_FOR_DYLD_SIM";
+ break;
+
+ case F_RECYCLE:
+ p = "RECYCLE";
+ break;
+
+ case F_BARRIERFSYNC:
+ p = "BARRIERFSYNC";
+ break;
+
+ case F_SETCONFINED:
+ p = "SETCONFINED";
+ break;
+
+ case F_GETCONFINED:
+ p = "GETCONFINED";
+ break;
+
+ case F_ADDFILESIGS_RETURN:
+ p = "ADDFILESIGS_RETURN";
+ break;
+
+ case F_CHECK_LV:
+ p = "CHECK_LV";
+ break;
+
+ case F_PUNCHHOLE:
+ p = "PUNCHHOLE";
+ break;
+
+ case F_TRIM_ACTIVE_FILE:
+ p = "TRIM_ACTIVE_FILE";
+ break;
+
+ case F_SPECULATIVE_READ:
+ p = "SPECULATIVE_READ";
+ break;
+
+ case F_GETPATH_NOFIRMLINK:
+ p = "GETPATH_NOFIRMLINK";
+ break;
+
+ case F_ADDFILESIGS_INFO:
+ p = "ADDFILESIGS_INFO";
+ break;
+
+ case F_ADDFILESUPPL:
+ p = "ADDFILESUPPL";
+ break;
+
+#ifdef F_GETSIGSINFO
+ case F_GETSIGSINFO:
+ p = "GETSIGSINFO";
+ break;
+#endif // F_GETSIGSINFO
}
if (p) {
found = true;
}
- assert(found);
+ os_assert(found);
#endif /* DEBUG */
if ((ti = add_event(event, type)) == NULL)
struct pid_fd_set *pfs;
int hashid;
- assert(pid >= 0);
+ os_assert(pid >= 0);
hashid = pid & HASH_MASK;
newsize = MAX(((size_t)fd + CHAR_BIT) / CHAR_BIT, 2 * pfs->setsize);
pfs->set = reallocf(pfs->set, newsize);
- assert(pfs->set != NULL);
+ os_assert(pfs->set != NULL);
bzero(pfs->set + pfs->setsize, newsize - pfs->setsize);
pfs->setsize = newsize;
char *name;
};
-struct library_range framework32 = {0, 0};
+struct library_range frameworkArm64e = {0, 0};
struct library_range framework64 = {0, 0};
struct library_range framework64h = {0, 0};
return 1;
}
+#define DYLD_SHARED_CACHE_LOCATION "/System/Library/dyld/"
+
void
init_shared_cache_mapping(void)
{
- read_shared_cache_map("/var/db/dyld/dyld_shared_cache_i386.map", &framework32, "/var/db/dyld/dyld_shared_cache_i386");
-
- if (0 == read_shared_cache_map("/var/db/dyld/dyld_shared_cache_x86_64h.map", &framework64h, "/var/db/dyld/dyld_shared_cache_x86_64h")) {
- read_shared_cache_map("/var/db/dyld/dyld_shared_cache_x86_64.map", &framework64, "/var/db/dyld/dyld_shared_cache_x86_64");
+#if TARGET_OS_OSX
+#if TARGET_CPU_ARM64
+ read_shared_cache_map(DYLD_SHARED_CACHE_LOCATION"dyld_shared_cache_arm64e.map", &frameworkArm64e, DYLD_SHARED_CACHE_LOCATION"dyld_shared_cache_arm64e");
+#else //!TARGET_CPU_ARM64
+ if (0 == read_shared_cache_map(DYLD_SHARED_CACHE_LOCATION"dyld_shared_cache_x86_64h.map", &framework64h, DYLD_SHARED_CACHE_LOCATION"dyld_shared_cache_x86_64h")) {
+ read_shared_cache_map(DYLD_SHARED_CACHE_LOCATION"dyld_shared_cache_x86_64.map", &framework64, DYLD_SHARED_CACHE_LOCATION"dyld_shared_cache_x86_64");
}
-
+#endif //TARGET_CPU_ARM64
sort_library_addresses();
+#endif //TARGET_OS_OSX
}
void
*type = NULL;
if (num_libraries) {
- if ((user_addr >= framework32.b_address && user_addr < framework32.e_address) ||
+ if ((user_addr >= frameworkArm64e.b_address && user_addr < frameworkArm64e.e_address) ||
(user_addr >= framework64.b_address && user_addr < framework64.e_address) ||
(user_addr >= framework64h.b_address && user_addr < framework64h.e_address)) {