X-Git-Url: https://git.saurik.com/apple/system_cmds.git/blobdiff_plain/887d5eedc67e1d6b5933393070e765bc7739453c..HEAD:/fs_usage.tproj/fs_usage.c?ds=inline diff --git a/fs_usage.tproj/fs_usage.c b/fs_usage.tproj/fs_usage.c index f7f9bfc..ef81b48 100644 --- a/fs_usage.tproj/fs_usage.c +++ b/fs_usage.tproj/fs_usage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2016 Apple Inc. All rights reserved. + * Copyright (c) 1999-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -39,10 +39,11 @@ #include #include #include +#include #include #include -#include +#include #include #include @@ -68,7 +69,7 @@ typedef struct th_info { struct th_info *next; - uintptr_t thread; + uint64_t thread; /* this is needed for execve()/posix_spawn(), because the command name at the end probe is the new name, which we don't want */ char command[MAXCOMLEN + 1]; @@ -78,21 +79,21 @@ typedef struct th_info { * (e.g., one absolute, one relative). traditional fs_usage behavior was to display the * *first* lookup, so we need to save it off once we see it. */ - unsigned long vnodeid; /* the vp of the VFS_LOOKUP we're currently in, 0 if we are not in one */ + uint64_t vnodeid; /* the vp of the VFS_LOOKUP we're currently in, 0 if we are not in one */ char pathname[MAXPATHLEN]; char pathname2[MAXPATHLEN]; char *newest_pathname; /* points to pathname2 if it's filled, otherwise pathname if it's filled, otherwise NULL */ int pid; int type; - unsigned long arg1; - unsigned long arg2; - unsigned long arg3; - unsigned long arg4; - unsigned long arg5; - unsigned long arg6; - unsigned long arg7; - unsigned long arg8; + uint64_t arg1; + uint64_t arg2; + uint64_t arg3; + uint64_t arg4; + uint64_t arg5; + uint64_t arg6; + uint64_t arg7; + uint64_t arg8; int waited; uint64_t stime; } *th_info_t; @@ -100,17 +101,17 @@ typedef struct th_info { struct diskio { struct diskio *next; struct diskio *prev; - unsigned long type; - unsigned long bp; - unsigned long dev; - unsigned long blkno; - unsigned long iosize; - unsigned long io_errno; - unsigned long is_meta; + uint64_t type; + uint64_t bp; + uint64_t dev; + uint64_t blkno; + uint64_t iosize; + uint64_t io_errno; + uint64_t is_meta; uint64_t vnodeid; - uintptr_t issuing_thread; + uint64_t issuing_thread; pid_t issuing_pid; - uintptr_t completion_thread; + uint64_t completion_thread; char issuing_command[MAXCOMLEN + 1]; uint64_t issued_time; uint64_t completed_time; @@ -122,12 +123,12 @@ struct diskio { #define HASH_MASK (HASH_SIZE - 1) void setup_ktrace_callbacks(void); -void extend_syscall(uintptr_t thread, int type, ktrace_event_t event); +void extend_syscall(uint64_t thread, int type, ktrace_event_t event); /* printing routines */ -bool check_filter_mode(pid_t pid, th_info_t ti, unsigned long type, int error, int retval, char *sc_name); -void format_print(th_info_t ti, char *sc_name, ktrace_event_t event, unsigned long type, int format, uint64_t now, uint64_t stime, int waited, const char *pathname, struct diskio *dio); -int print_open(ktrace_event_t event, uintptr_t flags); +bool check_filter_mode(pid_t pid, th_info_t ti, uint64_t type, int error, int retval, char *sc_name); +void format_print(th_info_t ti, char *sc_name, ktrace_event_t event, uint64_t type, int format, uint64_t now, uint64_t stime, int waited, const char *pathname, struct diskio *dio); +int print_open(ktrace_event_t event, uint64_t flags); /* metadata info hash routines */ void meta_add_name(uint64_t blockno, const char *pathname); @@ -137,14 +138,14 @@ void meta_delete_all(void); /* event ("thread info") routines */ void event_enter(int type, ktrace_event_t event); void event_exit(char *sc_name, int type, ktrace_event_t event, int format); -th_info_t event_find(uintptr_t thread, int type); +th_info_t event_find(uint64_t thread, int type); void event_delete(th_info_t ti_to_delete); void event_delete_all(void); -void event_mark_thread_waited(uintptr_t); +void event_mark_thread_waited(uint64_t); /* network fd set routines */ -void fd_set_is_network(pid_t pid, unsigned long fd, bool set); -bool fd_is_network(pid_t pid, unsigned long fd); +void fd_set_is_network(pid_t pid, uint64_t fd, bool set); +bool fd_is_network(pid_t pid, uint64_t fd); void fd_clear_pid(pid_t pid); void fd_clear_all(void); @@ -153,17 +154,17 @@ void init_shared_cache_mapping(void); void lookup_name(uint64_t user_addr, char **type, char **name); /* disk I/O tracking routines */ -struct diskio *diskio_start(unsigned long type, unsigned long bp, unsigned long dev, unsigned long blkno, unsigned long iosize, ktrace_event_t event); -struct diskio *diskio_find(unsigned long bp); -struct diskio *diskio_complete(unsigned long bp, unsigned long io_errno, unsigned long resid, uintptr_t thread, uint64_t curtime, struct timeval curtime_wall); +struct diskio *diskio_start(uint64_t type, uint64_t bp, uint64_t dev, uint64_t blkno, uint64_t iosize, ktrace_event_t event); +struct diskio *diskio_find(uint64_t bp); +struct diskio *diskio_complete(uint64_t bp, uint64_t io_errno, uint64_t resid, uint64_t thread, uint64_t curtime, struct timeval curtime_wall); void diskio_print(struct diskio *dio); void diskio_free(struct diskio *dio); /* disk name routines */ #define NFS_DEV -1 #define CS_DEV -2 -char *generate_cs_disk_name(unsigned long dev, char *s); -char *find_disk_name(unsigned long dev); +char *generate_cs_disk_name(uint64_t dev, char *s); +char *find_disk_name(uint64_t dev); void cache_disk_names(void); #define CLASS_MASK 0xff000000 @@ -386,7 +387,11 @@ void cache_disk_names(void); #define BSC_pwrite_nocancel 0x040c067c #define BSC_aio_suspend_nocancel 0x40c0694 #define BSC_guarded_open_np 0x040c06e4 +#define BSC_guarded_open_dprotected_np 0x040c0790 #define BSC_guarded_close_np 0x040c06e8 +#define BSC_guarded_write_np 0x040c0794 +#define BSC_guarded_pwrite_np 0x040c0798 +#define BSC_guarded_writev_np 0x040c079c #define BSC_fsgetpath 0x040c06ac @@ -409,6 +414,7 @@ void cache_disk_names(void); #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 @@ -461,6 +467,7 @@ void cache_disk_names(void); #define FMT_OPENAT 45 #define FMT_RENAMEAT 46 #define FMT_IOCTL_SYNCCACHE 47 +#define FMT_GUARDED_OPEN 48 #define DBG_FUNC_ALL (DBG_FUNC_START | DBG_FUNC_END) @@ -543,14 +550,18 @@ const struct bsd_syscall bsd_syscalls[MAX_BSD_SYSCALL] = { NORMAL_SYSCALL(posix_spawn), SYSCALL_WITH_NOCANCEL(open, FMT_OPEN), SYSCALL(open_extended, FMT_OPEN), - SYSCALL(guarded_open_np, FMT_OPEN), + SYSCALL(guarded_open_np, FMT_GUARDED_OPEN), SYSCALL_NAMED(open_dprotected_np, open_dprotected, FMT_OPEN), + SYSCALL(guarded_open_dprotected_np, FMT_GUARDED_OPEN), SYSCALL(dup, FMT_FD_2), SYSCALL(dup2, FMT_FD_2), SYSCALL_WITH_NOCANCEL(close, FMT_FD), SYSCALL(guarded_close_np, FMT_FD), 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_PREAD), + SYSCALL(guarded_writev_np, FMT_FD_IO), SYSCALL(fgetxattr, FMT_FD), SYSCALL(fsetxattr, FMT_FD), SYSCALL(fremovexattr, FMT_FD), @@ -677,7 +688,7 @@ static uint64_t 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; } @@ -713,6 +724,15 @@ exit_usage(void) 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[]) { @@ -721,10 +741,18 @@ 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); + 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); + (void)ktrace_ignore_process_filter_for_event(s, P_RdMeta); + (void)ktrace_ignore_process_filter_for_event(s, P_PgOut); + (void)ktrace_ignore_process_filter_for_event(s, P_PgIn); while ((ch = getopt(argc, argv, "bewf:R:S:E:t:W")) != -1) { switch (ch) { @@ -795,16 +823,9 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - if (time_limit_ns > 0) { - if (RAW_flag) { - fprintf(stderr, "NOTE: time limit ignored when a raw file is specified\n"); - } else { - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, time_limit_ns), - dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), - ^{ - ktrace_end(s, 0); - }); - } + if (time_limit_ns > 0 && RAW_flag) { + fprintf(stderr, "NOTE: time limit ignored when a raw file is specified\n"); + time_limit_ns = 0; } if (!RAW_flag) { @@ -832,9 +853,9 @@ main(int argc, char *argv[]) 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) */ } } @@ -887,7 +908,7 @@ main(int argc, char *argv[]) fprintf(stderr, "ERROR: cannot both include and exclude simultaneously\n"); exit(1); } else { - assert(!rv); + os_assert(!rv); } argc--; @@ -938,6 +959,14 @@ main(int argc, char *argv[]) exit(1); } + if (time_limit_ns > 0) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, time_limit_ns), + dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), + ^{ + ktrace_end(s, 0); + }); + } + dispatch_main(); return 0; @@ -1265,6 +1294,15 @@ setup_ktrace_callbacks(void) }); } +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: @@ -1273,14 +1311,15 @@ setup_ktrace_callbacks(void) * is all we really need. */ void -extend_syscall(uintptr_t thread, int type, ktrace_event_t event) +extend_syscall(uint64_t thread, int type, ktrace_event_t event) { th_info_t ti; 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 */ @@ -1300,8 +1339,9 @@ extend_syscall(uintptr_t thread, int type, ktrace_event_t event) 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 */ @@ -1310,26 +1350,30 @@ extend_syscall(uintptr_t thread, int type, ktrace_event_t event) 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; } } @@ -1337,7 +1381,7 @@ extend_syscall(uintptr_t thread, int type, ktrace_event_t event) #pragma mark printing routines static void -get_mode_nibble(char *buf, unsigned long smode, unsigned long special, char x_on, char x_off) +get_mode_nibble(char *buf, uint64_t smode, uint64_t special, char x_on, char x_off) { if (smode & 04) buf[0] = 'r'; @@ -1357,7 +1401,7 @@ get_mode_nibble(char *buf, unsigned long smode, unsigned long special, char x_on } static void -get_mode_string(unsigned long mode, char *buf) +get_mode_string(uint64_t mode, char *buf) { memset(buf, '-', 9); buf[9] = '\0'; @@ -1404,11 +1448,11 @@ clip_64bit(char *s, uint64_t value) * filters may be combined; default is all filters on (except cachehit) */ bool -check_filter_mode(pid_t pid, th_info_t ti, unsigned long type, int error, int retval, char *sc_name) +check_filter_mode(pid_t pid, th_info_t ti, uint64_t type, int error, int retval, char *sc_name) { bool ret = false; int network_fd_isset = 0; - unsigned long fd; + uint64_t fd; /* cachehit is special -- it's not on by default */ if (sc_name[0] == 'C' && !strcmp(sc_name, "CACHE_HIT")) { @@ -1559,9 +1603,23 @@ check_filter_mode(pid_t pid, th_info_t ti, unsigned long type, int error, int re } int -print_open(ktrace_event_t event, uintptr_t flags) +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'; @@ -1572,19 +1630,6 @@ print_open(ktrace_event_t event, uintptr_t flags) 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 { @@ -1601,7 +1646,7 @@ print_open(ktrace_event_t event, uintptr_t flags) */ void format_print(th_info_t ti, char *sc_name, ktrace_event_t event, - unsigned long type, int format, uint64_t now, uint64_t stime, + uint64_t type, int format, uint64_t now, uint64_t stime, int waited, const char *pathname, struct diskio *dio) { uint64_t secs, usecs; @@ -1612,16 +1657,16 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, int len = 0; int clen = 0; size_t tlen = 0; - unsigned long class; + uint64_t class; uint64_t user_addr; uint64_t user_size; char *framework_name; char *framework_type; char *p1; char *p2; - char buf[MAXWIDTH]; + char buf[2 * PATH_MAX + 64]; char cs_diskname[32]; - unsigned long threadid; + uint64_t threadid; struct timeval now_walltime; static char timestamp[32]; @@ -1631,12 +1676,12 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, 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); } /* Filter out WindowServer/xcpm ioctls in fs_usage */ @@ -1680,7 +1725,7 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, 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) { @@ -1755,7 +1800,7 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, if (event->arg1) clen += printf(" F=%-3d[%3d]", (int)ti->arg1, (int)event->arg1); else - clen += printf(" F=%-3d B=0x%-6lx", (int)ti->arg1, event->arg2); + clen += printf(" F=%-3d B=0x%-6" PRIx64, (int)ti->arg1, (uint64_t)event->arg2); break; @@ -1783,7 +1828,7 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, /* * pageout */ - clen += printf(" B=0x%-8lx", event->arg1); + clen += printf(" B=0x%-8" PRIx64, (uint64_t)event->arg1); break; case FMT_HFS_update: @@ -1838,12 +1883,12 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, * physical disk I/O */ if (dio->io_errno) { - clen += printf(" D=0x%8.8lx [%3d]", dio->blkno, (int)dio->io_errno); + clen += printf(" D=0x%8.8" PRIx64 " [%3d]", dio->blkno, (int)dio->io_errno); } else { if (BC_flag) - clen += printf(" D=0x%8.8lx B=0x%-6lx BC:%s /dev/%s ", dio->blkno, dio->iosize, BC_STR(dio->bc_info), find_disk_name(dio->dev)); + clen += printf(" D=0x%8.8" PRIx64 " B=0x%-6" PRIx64 " BC:%s /dev/%s ", dio->blkno, dio->iosize, BC_STR(dio->bc_info), find_disk_name(dio->dev)); else - clen += printf(" D=0x%8.8lx B=0x%-6lx /dev/%s ", dio->blkno, dio->iosize, find_disk_name(dio->dev)); + clen += printf(" D=0x%8.8" PRIx64 " B=0x%-6" PRIx64 " /dev/%s ", dio->blkno, dio->iosize, find_disk_name(dio->dev)); if (dio->is_meta) { if (!(type & P_DISKIO_READ)) { @@ -1866,9 +1911,9 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, * physical disk I/O */ if (dio->io_errno) - clen += printf(" D=0x%8.8lx [%3lu]", dio->blkno, dio->io_errno); + clen += printf(" D=0x%8.8" PRIx64 " [%3" PRIu64 "]", dio->blkno, dio->io_errno); else - clen += printf(" D=0x%8.8lx B=0x%-6lx /dev/%s", dio->blkno, dio->iosize, generate_cs_disk_name(dio->dev, cs_diskname)); + clen += printf(" D=0x%8.8" PRIx64 " B=0x%-6" PRIx64 " /dev/%s", dio->blkno, dio->iosize, generate_cs_disk_name(dio->dev, cs_diskname)); break; @@ -2006,6 +2051,34 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, 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; @@ -2059,6 +2132,191 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, 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) { @@ -2093,7 +2351,7 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, /* * ioctl */ - clen += printf(" B=%lu /dev/%s", event->arg3, find_disk_name(event->arg1)); + clen += printf(" B=%" PRIu64 " /dev/%s", (uint64_t)event->arg3, find_disk_name(event->arg1)); break; } @@ -2120,7 +2378,7 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, case FMT_UNMAP_INFO: { - clen += printf(" D=0x%8.8lx B=0x%-6lx /dev/%s", event->arg2, event->arg3, find_disk_name(event->arg1)); + clen += printf(" D=0x%8.8" PRIx64 " B=0x%-6" PRIx64 " /dev/%s", (uint64_t)event->arg2, (uint64_t)event->arg3, find_disk_name(event->arg1)); break; } @@ -2147,7 +2405,7 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, clen += printf("[%3d] ", (int)event->arg1); } else { if (format == FMT_PREAD) - clen += printf(" B=0x%-8lx ", event->arg2); + clen += printf(" B=0x%-8" PRIx64 " ", (uint64_t)event->arg2); else clen += printf(" "); } @@ -2309,7 +2567,7 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, /* * fchmod, fchmod_extended, chmod, chmod_extended */ - unsigned long mode; + uint64_t mode; if (format == FMT_FCHMOD || format == FMT_FCHMOD_EXT) { if (event->arg1) @@ -2370,9 +2628,9 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, case FMT_MOUNT: { if (event->arg1) - clen += printf(" [%3d] ", (int)event->arg1, ti->arg3); + clen += printf(" [%3d] ", (int)event->arg1, ti->arg3); else - clen += printf(" ", ti->arg3); + clen += printf(" ", ti->arg3); nopadding = 1; break; @@ -2406,6 +2664,11 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, nopadding = 1; break; + case FMT_GUARDED_OPEN: + clen += print_open(event, ti->arg4); + nopadding = 1; + break; + case FMT_SOCKET: { /* @@ -2457,9 +2720,9 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, } if (event->arg1) - clen += printf(" [%3d] <%s, %s, 0x%lx>", (int)event->arg1, domain, type, ti->arg3); + clen += printf(" [%3d] <%s, %s, 0x%" PRIx64 ">", (int)event->arg1, domain, type, ti->arg3); else - clen += printf(" F=%-3d <%s, %s, 0x%lx>", (int)event->arg2, domain, type, ti->arg3); + clen += printf(" F=%-3d <%s, %s, 0x%" PRIx64 ">", (int)event->arg2, domain, type, ti->arg3); break; } @@ -2481,9 +2744,9 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, op = "UNKNOWN"; if (event->arg1) - clen += printf(" [%3d] P=0x%8.8lx <%s>", (int)event->arg1, ti->arg2, op); + clen += printf(" [%3d] P=0x%8.8" PRIx64 " <%s>", (int)event->arg1, ti->arg2, op); else - clen += printf(" P=0x%8.8lx <%s>", ti->arg2, op); + clen += printf(" P=0x%8.8" PRIx64 " <%s>", ti->arg2, op); break; } @@ -2493,9 +2756,9 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, * aio_return [errno] AIOCBP IOSIZE */ if (event->arg1) - clen += printf(" [%3d] P=0x%8.8lx", (int)event->arg1, ti->arg1); + clen += printf(" [%3d] P=0x%8.8" PRIx64, (int)event->arg1, ti->arg1); else - clen += printf(" P=0x%8.8lx B=0x%-8lx", ti->arg1, event->arg2); + clen += printf(" P=0x%8.8" PRIx64 " B=0x%-8" PRIx64, ti->arg1, (uint64_t)event->arg2); break; @@ -2516,9 +2779,9 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, */ if (ti->arg2) { if (event->arg1) - clen += printf(" [%3d] P=0x%8.8lx", (int)event->arg1, ti->arg2); + clen += printf(" [%3d] P=0x%8." PRIx64, (int)event->arg1, ti->arg2); else - clen += printf(" P=0x%8.8lx", ti->arg2); + clen += printf(" P=0x%8.8" PRIx64, ti->arg2); } else { if (event->arg1) clen += printf(" F=%-3d[%3d]", (int)ti->arg1, (int)event->arg1); @@ -2533,9 +2796,9 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, * aio_error, aio_read, aio_write [errno] AIOCBP */ if (event->arg1) - clen += printf(" [%3d] P=0x%8.8lx", (int)event->arg1, ti->arg1); + clen += printf(" [%3d] P=0x%8.8" PRIx64, (int)event->arg1, ti->arg1); else - clen += printf(" P=0x%8.8lx", ti->arg1); + clen += printf(" P=0x%8.8" PRIx64, ti->arg1); break; @@ -2644,7 +2907,7 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, p2 = " "; if (columns > MAXCOLS || wideflag) - printf("%s%s %3llu.%06llu%s %s.%lu\n", p1, pathname, secs, usecs, p2, command_name, threadid); + printf("%s%s %3llu.%06llu%s %s.%" PRIu64 "\n", p1, pathname, secs, usecs, p2, command_name, threadid); else printf("%s%s %3llu.%06llu%s %-12.12s\n", p1, pathname, secs, usecs, p2, command_name); @@ -2732,7 +2995,7 @@ add_event(ktrace_event_t event, int type) { th_info_t ti; int hashid; - unsigned long eventid; + uint64_t eventid; if ((ti = th_info_freelist)) th_info_freelist = ti->next; @@ -2767,7 +3030,7 @@ add_event(ktrace_event_t event, int type) } th_info_t -event_find(uintptr_t thread, int type) +event_find(uint64_t thread, int type) { th_info_t ti; int hashid; @@ -2862,7 +3125,7 @@ event_enter(int type, ktrace_event_t event) found = true; } - assert(found); + os_assert(found); #endif /* DEBUG */ if ((ti = add_event(event, type)) == NULL) @@ -2905,7 +3168,7 @@ event_exit(char *sc_name, int type, ktrace_event_t event, int format) } void -event_mark_thread_waited(uintptr_t thread) +event_mark_thread_waited(uint64_t thread) { th_info_t ti; int hashid; @@ -2935,7 +3198,7 @@ pfs_get(pid_t pid) struct pid_fd_set *pfs; int hashid; - assert(pid >= 0); + os_assert(pid >= 0); hashid = pid & HASH_MASK; @@ -3008,7 +3271,7 @@ fd_clear_all(void) } void -fd_set_is_network(pid_t pid, unsigned long fd, bool set) +fd_set_is_network(pid_t pid, uint64_t fd, bool set) { struct pid_fd_set *pfs; @@ -3024,9 +3287,9 @@ fd_set_is_network(pid_t pid, unsigned long fd, bool set) if (!set) return; - newsize = MAX((fd + CHAR_BIT) / CHAR_BIT, 2 * pfs->setsize); + 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; @@ -3039,7 +3302,7 @@ fd_set_is_network(pid_t pid, unsigned long fd, bool set) } bool -fd_is_network(pid_t pid, unsigned long fd) +fd_is_network(pid_t pid, uint64_t fd) { struct pid_fd_set *pfs; @@ -3071,7 +3334,7 @@ struct library_info { 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}; @@ -3273,16 +3536,21 @@ read_shared_cache_map(const char *path, struct library_range *lr, char *linkedit 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 @@ -3305,7 +3573,7 @@ lookup_name(uint64_t user_addr, char **type, char **name) *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)) { @@ -3334,8 +3602,8 @@ struct diskio *free_diskios = NULL; struct diskio *busy_diskios = NULL; struct diskio * -diskio_start(unsigned long type, unsigned long bp, unsigned long dev, - unsigned long blkno, unsigned long iosize, ktrace_event_t event) +diskio_start(uint64_t type, uint64_t bp, uint64_t dev, + uint64_t blkno, uint64_t iosize, ktrace_event_t event) { const char *command; struct diskio *dio; @@ -3378,7 +3646,7 @@ diskio_start(unsigned long type, unsigned long bp, unsigned long dev, } struct diskio * -diskio_find(unsigned long bp) +diskio_find(uint64_t bp) { struct diskio *dio; @@ -3391,8 +3659,8 @@ diskio_find(unsigned long bp) } struct diskio * -diskio_complete(unsigned long bp, unsigned long io_errno, unsigned long resid, - uintptr_t thread, uint64_t curtime, struct timeval curtime_wall) +diskio_complete(uint64_t bp, uint64_t io_errno, uint64_t resid, + uint64_t thread, uint64_t curtime, struct timeval curtime_wall) { struct diskio *dio; @@ -3428,7 +3696,7 @@ diskio_print(struct diskio *dio) { char *p = NULL; int len = 0; - unsigned long type; + uint64_t type; int format = FMT_DISKIO; char buf[64]; @@ -3546,8 +3814,11 @@ diskio_print(struct diskio *dio) buf[len] = 0; - if (check_filter_mode(-1, NULL, type, 0, 0, buf)) - format_print(NULL, buf, NULL, type, format, dio->completed_time, dio->issued_time, 1, "", dio); + if (check_filter_mode(-1, NULL, type, 0, 0, buf)) { + const char *pathname = ktrace_get_path_for_vp(s, dio->vnodeid); + format_print(NULL, buf, NULL, type, format, dio->completed_time, + dio->issued_time, 1, pathname ? pathname : "", dio); + } } #pragma mark disk name routines @@ -3617,7 +3888,7 @@ recache_disk_names(void) } char * -find_disk_name(unsigned long dev) +find_disk_name(uint64_t dev) { struct diskrec *dnp; int i; @@ -3640,12 +3911,12 @@ find_disk_name(unsigned long dev) } char * -generate_cs_disk_name(unsigned long dev, char *s) +generate_cs_disk_name(uint64_t dev, char *s) { if (dev == -1) return "UNKNOWN"; - sprintf(s, "disk%lus%lu", (dev >> 16) & 0xffff, dev & 0xffff); + sprintf(s, "disk%" PRIu64 "s%" PRIu64, (dev >> 16) & 0xffff, dev & 0xffff); return (s); }