2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
26 cc -I/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders -DPRIVATE -D__APPLE_PRIVATE -arch x86_64 -arch i386 -O -lutil -o fs_usage fs_usage.c
44 #include <sys/types.h>
45 #include <sys/param.h>
47 #include <sys/ioctl.h>
48 #include <sys/socket.h>
50 #include <sys/sysctl.h>
53 #ifndef KERNEL_PRIVATE
54 #define KERNEL_PRIVATE
55 #include <sys/kdebug.h>
58 #include <sys/kdebug.h>
59 #endif /*KERNEL_PRIVATE*/
61 #import <mach/clock_types.h>
62 #import <mach/mach_time.h>
66 #define F_OPENFROM 56 /* SPI: open a file relative to fd (must be a dir) */
67 #define F_UNLINKFROM 57 /* SPI: open a file relative to fd (must be a dir) */
68 #define F_CHECK_OPENEVT 58 /* SPI: if a process is marked OPENEVT, or in O_EVTONLY on opens of this vnode */
79 #define RAW_VERSION0 0x55aa0000
80 #define RAW_VERSION1 0x55aa0101
86 typedef struct LibraryRange
{
91 LibraryRange framework32
;
92 LibraryRange framework64
;
104 char *frameworkType
[] = {
115 typedef struct LibraryInfo
{
122 LibraryInfo frameworkInfo
[MAXINDEX
];
123 int numFrameworks
= 0;
127 * MAXCOLS controls when extra data kicks in.
128 * MAX_WIDE_MODE_COLS controls -w mode to get even wider data in path.
129 * If NUMPARMS changes to match the kernel, it will automatically
130 * get reflected in the -w mode output.
133 #define PATHLENGTH (NUMPARMS*sizeof(uintptr_t))
136 #define MAX_WIDE_MODE_COLS (PATHLENGTH + 80)
137 #define MAXWIDTH MAX_WIDE_MODE_COLS + 64
140 typedef struct th_info
*th_info_t
;
145 uintptr_t child_thread
;
161 uintptr_t pathname
[NUMPARMS
+ 1]; /* add room for null terminator */
162 uintptr_t pathname2
[NUMPARMS
+ 1]; /* add room for null terminator */
166 typedef struct threadmap
* threadmap_t
;
172 unsigned int tm_setsize
; /* this is a bit count */
173 unsigned long *tm_setptr
; /* file descripter bitmap */
174 char tm_command
[MAXCOMLEN
+ 1];
178 #define HASH_SIZE 1024
179 #define HASH_MASK 1023
181 th_info_t th_info_hash
[HASH_SIZE
];
182 th_info_t th_info_freelist
;
184 threadmap_t threadmap_hash
[HASH_SIZE
];
185 threadmap_t threadmap_freelist
;
188 int filemgr_in_progress
= 0;
189 int need_new_map
= 1;
195 int one_good_pid
= 0; /* Used to fail gracefully when bad pids given */
196 int select_pid_mode
= 0; /* Flag set indicates that output is restricted
197 to selected pids or commands */
204 #define USLEEP_BEHIND 2
205 #define USLEEP_MAX 32
206 int usleep_ms
= USLEEP_MIN
;
209 * Network only or filesystem only output filter
210 * Default of zero means report all activity - no filtering
212 #define FILESYS_FILTER 0x01
213 #define NETWORK_FILTER 0x02
214 #define CACHEHIT_FILTER 0x04
215 #define EXEC_FILTER 0x08
216 #define PATHNAME_FILTER 0x10
217 #define DEFAULT_DO_NOT_FILTER 0x00
219 int filter_mode
= CACHEHIT_FILTER
;
225 struct diskrec
*next
;
239 uintptr_t issuing_thread
;
240 uintptr_t completion_thread
;
241 char issuing_command
[MAXCOMLEN
];
243 double completed_time
;
246 struct diskrec
*disk_list
= NULL
;
247 struct diskio
*free_diskios
= NULL
;
248 struct diskio
*busy_diskios
= NULL
;
251 struct diskio
*insert_diskio();
252 struct diskio
*complete_diskio();
256 int check_filter_mode(struct th_info
*, int, int, int, char *);
257 void format_print(struct th_info
*, char *, uintptr_t, int, int, int, int, int, int, double, double, int, char *, struct diskio
*);
258 void enter_event_now(uintptr_t, int, kd_buf
*, char *, double);
259 void enter_event(uintptr_t, int, kd_buf
*, char *, double);
260 void exit_event(char *, uintptr_t, int, int, int, int, int, int, double);
261 void extend_syscall(uintptr_t, int, kd_buf
*);
263 char *generate_cs_disk_name(int, char *s
);
264 char *find_disk_name(int);
265 void cache_disk_names();
266 void recache_disk_names();
268 void lookup_name(uint64_t user_addr
, char **type
, char **name
);
269 int ReadSharedCacheMap(const char *, LibraryRange
*, char *);
270 void SortFrameworkAddresses();
272 void fs_usage_fd_set(uintptr_t, unsigned int);
273 int fs_usage_fd_isset(uintptr_t, unsigned int);
274 void fs_usage_fd_clear(uintptr_t, unsigned int);
276 void init_arguments_buffer();
277 int get_real_command_name(int, char *, int);
279 void delete_all_events();
280 void delete_event(th_info_t
);
281 th_info_t
add_event(uintptr_t, int);
282 th_info_t
find_event(uintptr_t, int);
283 void mark_thread_waited(uintptr_t);
285 void read_command_map();
286 void delete_all_map_entries();
287 void create_map_entry(uintptr_t, int, char *);
288 void delete_map_entry(uintptr_t);
289 threadmap_t
find_map_entry(uintptr_t);
295 void set_pidexclude();
299 #define CLASS_MASK 0xff000000
300 #define CSC_MASK 0xffff0000
301 #define BSC_INDEX(type) ((type >> 2) & 0x3fff)
304 #define TRACE_DATA_NEWTHREAD 0x07000004
305 #define TRACE_DATA_EXEC 0x07000008
306 #define TRACE_STRING_NEWTHREAD 0x07010004
307 #define TRACE_STRING_EXEC 0x07010008
309 #define MACH_vmfault 0x01300008
310 #define MACH_pageout 0x01300004
311 #define MACH_sched 0x01400000
312 #define MACH_stkhandoff 0x01400008
313 #define MACH_idle 0x01400024
314 #define VFS_LOOKUP 0x03010090
316 #define BSC_thread_terminate 0x040c05a4
318 #define Throttled 0x3010184
319 #define SPEC_ioctl 0x3060000
320 #define SPEC_unmap_info 0x3060004
321 #define proc_exit 0x4010004
324 #define DKIO_NOCACHE 0x80
327 #define P_DISKIO_READ (DKIO_READ << 2)
328 #define P_DISKIO_ASYNC (DKIO_ASYNC << 2)
329 #define P_DISKIO_META (DKIO_META << 2)
330 #define P_DISKIO_PAGING (DKIO_PAGING << 2)
331 #define P_DISKIO_THROTTLE (DKIO_THROTTLE << 2)
332 #define P_DISKIO_PASSIVE (DKIO_PASSIVE << 2)
333 #define P_DISKIO_NOCACHE (DKIO_NOCACHE << 2)
335 #define P_DISKIO (FSDBG_CODE(DBG_DKRW, 0))
336 #define P_DISKIO_DONE (P_DISKIO | (DKIO_DONE << 2))
337 #define P_DISKIO_TYPE (P_DISKIO | P_DISKIO_READ | P_DISKIO_META | P_DISKIO_PAGING)
338 #define P_DISKIO_MASK (CSC_MASK | 0x4)
340 #define P_WrData (P_DISKIO)
341 #define P_RdData (P_DISKIO | P_DISKIO_READ)
342 #define P_WrMeta (P_DISKIO | P_DISKIO_META)
343 #define P_RdMeta (P_DISKIO | P_DISKIO_META | P_DISKIO_READ)
344 #define P_PgOut (P_DISKIO | P_DISKIO_PAGING)
345 #define P_PgIn (P_DISKIO | P_DISKIO_PAGING | P_DISKIO_READ)
347 #define P_CS_Class 0x0a000000 // DBG_CORESTORAGE
348 #define P_CS_Type_Mask 0xfffffff0
349 #define P_CS_IO_Done 0x00000004
351 #define P_CS_ReadChunk 0x0a000200 // chopped up request
352 #define P_CS_WriteChunk 0x0a000210
353 #define P_CS_MetaRead 0x0a000300 // meta data
354 #define P_CS_MetaWrite 0x0a000310
355 #define P_CS_TransformRead 0x0a000500 // background transform
356 #define P_CS_TransformWrite 0x0a000510
357 #define P_CS_MigrationRead 0x0a000600 // composite disk block migration
358 #define P_CS_MigrationWrite 0x0a000610
359 #define P_CS_SYNC_DISK 0x0a010000
361 #define MSC_map_fd 0x010c00ac
363 #define BSC_BASE 0x040C0000
364 #define MSC_BASE 0x010C0000
366 // Network related codes
367 #define BSC_recvmsg 0x040C006C
368 #define BSC_sendmsg 0x040C0070
369 #define BSC_recvfrom 0x040C0074
370 #define BSC_accept 0x040C0078
371 #define BSC_select 0x040C0174
372 #define BSC_socket 0x040C0184
373 #define BSC_connect 0x040C0188
374 #define BSC_bind 0x040C01A0
375 #define BSC_listen 0x040C01A8
376 #define BSC_sendto 0x040C0214
377 #define BSC_socketpair 0x040C021C
379 #define BSC_exit 0x040C0004
380 #define BSC_read 0x040C000C
381 #define BSC_write 0x040C0010
382 #define BSC_open 0x040C0014
383 #define BSC_close 0x040C0018
384 #define BSC_link 0x040C0024
385 #define BSC_unlink 0x040C0028
386 #define BSC_chdir 0x040c0030
387 #define BSC_fchdir 0x040c0034
388 #define BSC_mknod 0x040C0038
389 #define BSC_chmod 0x040C003C
390 #define BSC_chown 0x040C0040
391 #define BSC_getfsstat 0x040C0048
392 #define BSC_access 0x040C0084
393 #define BSC_chflags 0x040C0088
394 #define BSC_fchflags 0x040C008C
395 #define BSC_sync 0x040C0090
396 #define BSC_dup 0x040C00A4
397 #define BSC_ioctl 0x040C00D8
398 #define BSC_revoke 0x040C00E0
399 #define BSC_symlink 0x040C00E4
400 #define BSC_readlink 0x040C00E8
401 #define BSC_execve 0x040C00EC
402 #define BSC_umask 0x040C00F0
403 #define BSC_chroot 0x040C00F4
404 #define BSC_msync 0x040C0104
405 #define BSC_dup2 0x040C0168
406 #define BSC_fcntl 0x040C0170
407 #define BSC_fsync 0x040C017C
408 #define BSC_readv 0x040C01E0
409 #define BSC_writev 0x040C01E4
410 #define BSC_fchown 0x040C01EC
411 #define BSC_fchmod 0x040C01F0
412 #define BSC_rename 0x040C0200
413 #define BSC_mkfifo 0x040c0210
414 #define BSC_mkdir 0x040C0220
415 #define BSC_rmdir 0x040C0224
416 #define BSC_utimes 0x040C0228
417 #define BSC_futimes 0x040C022C
418 #define BSC_pread 0x040C0264
419 #define BSC_pwrite 0x040C0268
420 #define BSC_statfs 0x040C0274
421 #define BSC_fstatfs 0x040C0278
422 #define BSC_unmount 0x040C027C
423 #define BSC_mount 0x040C029C
424 #define BSC_stat 0x040C02F0
425 #define BSC_fstat 0x040C02F4
426 #define BSC_lstat 0x040C02F8
427 #define BSC_pathconf 0x040C02FC
428 #define BSC_fpathconf 0x040C0300
429 #define BSC_getdirentries 0x040C0310
430 #define BSC_mmap 0x040c0314
431 #define BSC_lseek 0x040c031c
432 #define BSC_truncate 0x040C0320
433 #define BSC_ftruncate 0x040C0324
434 #define BSC_undelete 0x040C0334
435 #define BSC_statv 0x040C0364
436 #define BSC_lstatv 0x040C0368
437 #define BSC_fstatv 0x040C036C
438 #define BSC_mkcomplex 0x040C0360
439 #define BSC_getattrlist 0x040C0370
440 #define BSC_setattrlist 0x040C0374
441 #define BSC_getdirentriesattr 0x040C0378
442 #define BSC_exchangedata 0x040C037C
443 #define BSC_checkuseraccess 0x040C0380
444 #define BSC_searchfs 0x040C0384
445 #define BSC_delete 0x040C0388
446 #define BSC_copyfile 0x040C038C
447 #define BSC_getxattr 0x040C03A8
448 #define BSC_fgetxattr 0x040C03AC
449 #define BSC_setxattr 0x040C03B0
450 #define BSC_fsetxattr 0x040C03B4
451 #define BSC_removexattr 0x040C03B8
452 #define BSC_fremovexattr 0x040C03BC
453 #define BSC_listxattr 0x040C03C0
454 #define BSC_flistxattr 0x040C03C4
455 #define BSC_fsctl 0x040C03C8
456 #define BSC_posix_spawn 0x040C03D0
457 #define BSC_open_extended 0x040C0454
458 #define BSC_stat_extended 0x040C045C
459 #define BSC_lstat_extended 0x040C0460
460 #define BSC_fstat_extended 0x040C0464
461 #define BSC_chmod_extended 0x040C0468
462 #define BSC_fchmod_extended 0x040C046C
463 #define BSC_access_extended 0x040C0470
464 #define BSC_mkfifo_extended 0x040C048C
465 #define BSC_mkdir_extended 0x040C0490
466 #define BSC_load_shared_file 0x040C04A0
467 #define BSC_aio_fsync 0x040C04E4
468 #define BSC_aio_return 0x040C04E8
469 #define BSC_aio_suspend 0x040C04EC
470 #define BSC_aio_cancel 0x040C04F0
471 #define BSC_aio_error 0x040C04F4
472 #define BSC_aio_read 0x040C04F8
473 #define BSC_aio_write 0x040C04FC
474 #define BSC_lio_listio 0x040C0500
475 #define BSC_sendfile 0x040C0544
476 #define BSC_stat64 0x040C0548
477 #define BSC_fstat64 0x040C054C
478 #define BSC_lstat64 0x040C0550
479 #define BSC_stat64_extended 0x040C0554
480 #define BSC_lstat64_extended 0x040C0558
481 #define BSC_fstat64_extended 0x040C055C
482 #define BSC_getdirentries64 0x040C0560
483 #define BSC_statfs64 0x040C0564
484 #define BSC_fstatfs64 0x040C0568
485 #define BSC_getfsstat64 0x040C056C
486 #define BSC_pthread_chdir 0x040C0570
487 #define BSC_pthread_fchdir 0x040C0574
488 #define BSC_lchown 0x040C05B0
490 #define BSC_read_nocancel 0x040c0630
491 #define BSC_write_nocancel 0x040c0634
492 #define BSC_open_nocancel 0x040c0638
493 #define BSC_close_nocancel 0x040c063c
494 #define BSC_recvmsg_nocancel 0x040c0644
495 #define BSC_sendmsg_nocancel 0x040c0648
496 #define BSC_recvfrom_nocancel 0x040c064c
497 #define BSC_accept_nocancel 0x040c0650
498 #define BSC_msync_nocancel 0x040c0654
499 #define BSC_fcntl_nocancel 0x040c0658
500 #define BSC_select_nocancel 0x040c065c
501 #define BSC_fsync_nocancel 0x040c0660
502 #define BSC_connect_nocancel 0x040c0664
503 #define BSC_readv_nocancel 0x040c066c
504 #define BSC_writev_nocancel 0x040c0670
505 #define BSC_sendto_nocancel 0x040c0674
506 #define BSC_pread_nocancel 0x040c0678
507 #define BSC_pwrite_nocancel 0x040c067c
508 #define BSC_aio_suspend_nocancel 0x40c0694
510 #define BSC_msync_extended 0x040e0104
511 #define BSC_pread_extended 0x040e0264
512 #define BSC_pwrite_extended 0x040e0268
513 #define BSC_mmap_extended 0x040e0314
514 #define BSC_mmap_extended2 0x040f0314
516 // Carbon File Manager support
517 #define FILEMGR_PBGETCATALOGINFO 0x1e000020
518 #define FILEMGR_PBGETCATALOGINFOBULK 0x1e000024
519 #define FILEMGR_PBCREATEFILEUNICODE 0x1e000028
520 #define FILEMGR_PBCREATEDIRECTORYUNICODE 0x1e00002c
521 #define FILEMGR_PBCREATEFORK 0x1e000030
522 #define FILEMGR_PBDELETEFORK 0x1e000034
523 #define FILEMGR_PBITERATEFORK 0x1e000038
524 #define FILEMGR_PBOPENFORK 0x1e00003c
525 #define FILEMGR_PBREADFORK 0x1e000040
526 #define FILEMGR_PBWRITEFORK 0x1e000044
527 #define FILEMGR_PBALLOCATEFORK 0x1e000048
528 #define FILEMGR_PBDELETEOBJECT 0x1e00004c
529 #define FILEMGR_PBEXCHANGEOBJECT 0x1e000050
530 #define FILEMGR_PBGETFORKCBINFO 0x1e000054
531 #define FILEMGR_PBGETVOLUMEINFO 0x1e000058
532 #define FILEMGR_PBMAKEFSREF 0x1e00005c
533 #define FILEMGR_PBMAKEFSREFUNICODE 0x1e000060
534 #define FILEMGR_PBMOVEOBJECT 0x1e000064
535 #define FILEMGR_PBOPENITERATOR 0x1e000068
536 #define FILEMGR_PBRENAMEUNICODE 0x1e00006c
537 #define FILEMGR_PBSETCATALOGINFO 0x1e000070
538 #define FILEMGR_PBSETVOLUMEINFO 0x1e000074
539 #define FILEMGR_FSREFMAKEPATH 0x1e000078
540 #define FILEMGR_FSPATHMAKEREF 0x1e00007c
542 #define FILEMGR_PBGETCATINFO 0x1e010000
543 #define FILEMGR_PBGETCATINFOLITE 0x1e010004
544 #define FILEMGR_PBHGETFINFO 0x1e010008
545 #define FILEMGR_PBXGETVOLINFO 0x1e01000c
546 #define FILEMGR_PBHCREATE 0x1e010010
547 #define FILEMGR_PBHOPENDF 0x1e010014
548 #define FILEMGR_PBHOPENRF 0x1e010018
549 #define FILEMGR_PBHGETDIRACCESS 0x1e01001c
550 #define FILEMGR_PBHSETDIRACCESS 0x1e010020
551 #define FILEMGR_PBHMAPID 0x1e010024
552 #define FILEMGR_PBHMAPNAME 0x1e010028
553 #define FILEMGR_PBCLOSE 0x1e01002c
554 #define FILEMGR_PBFLUSHFILE 0x1e010030
555 #define FILEMGR_PBGETEOF 0x1e010034
556 #define FILEMGR_PBSETEOF 0x1e010038
557 #define FILEMGR_PBGETFPOS 0x1e01003c
558 #define FILEMGR_PBREAD 0x1e010040
559 #define FILEMGR_PBWRITE 0x1e010044
560 #define FILEMGR_PBGETFCBINFO 0x1e010048
561 #define FILEMGR_PBSETFINFO 0x1e01004c
562 #define FILEMGR_PBALLOCATE 0x1e010050
563 #define FILEMGR_PBALLOCCONTIG 0x1e010054
564 #define FILEMGR_PBSETFPOS 0x1e010058
565 #define FILEMGR_PBSETCATINFO 0x1e01005c
566 #define FILEMGR_PBGETVOLPARMS 0x1e010060
567 #define FILEMGR_PBSETVINFO 0x1e010064
568 #define FILEMGR_PBMAKEFSSPEC 0x1e010068
569 #define FILEMGR_PBHGETVINFO 0x1e01006c
570 #define FILEMGR_PBCREATEFILEIDREF 0x1e010070
571 #define FILEMGR_PBDELETEFILEIDREF 0x1e010074
572 #define FILEMGR_PBRESOLVEFILEIDREF 0x1e010078
573 #define FILEMGR_PBFLUSHVOL 0x1e01007c
574 #define FILEMGR_PBHRENAME 0x1e010080
575 #define FILEMGR_PBCATMOVE 0x1e010084
576 #define FILEMGR_PBEXCHANGEFILES 0x1e010088
577 #define FILEMGR_PBHDELETE 0x1e01008c
578 #define FILEMGR_PBDIRCREATE 0x1e010090
579 #define FILEMGR_PBCATSEARCH 0x1e010094
580 #define FILEMGR_PBHSETFLOCK 0x1e010098
581 #define FILEMGR_PBHRSTFLOCK 0x1e01009c
582 #define FILEMGR_PBLOCKRANGE 0x1e0100a0
583 #define FILEMGR_PBUNLOCKRANGE 0x1e0100a4
586 #define FILEMGR_CLASS 0x1e
587 #define FILEMGR_BASE 0x1e000000
589 #define FMT_DEFAULT 0
596 #define FMT_CACHEHIT 7
600 #define FMT_FTRUNC 11
602 #define FMT_SELECT 13
604 #define FMT_AIO_FSYNC 15
605 #define FMT_AIO_RETURN 16
606 #define FMT_AIO_SUSPEND 17
607 #define FMT_AIO_CANCEL 18
609 #define FMT_LIO_LISTIO 20
612 #define FMT_ACCESS 23
614 #define FMT_FCHMOD 25
615 #define FMT_CHMOD_EXT 26
616 #define FMT_FCHMOD_EXT 27
617 #define FMT_CHFLAGS 28
618 #define FMT_FCHFLAGS 29
622 #define FMT_SENDFILE 33
623 #define FMT_IOCTL_SYNC 34
625 #define FMT_UNMOUNT 36
626 #define FMT_DISKIO_CS 37
627 #define FMT_SYNC_DISK_CS 38
628 #define FMT_IOCTL_UNMAP 39
629 #define FMT_UNMAP_INFO 40
631 #define MAX_BSD_SYSCALL 512
636 } bsd_syscalls
[MAX_BSD_SYSCALL
];
639 int bsd_syscall_types
[] = {
641 BSC_recvmsg_nocancel
,
643 BSC_sendmsg_nocancel
,
645 BSC_recvfrom_nocancel
,
652 BSC_connect_nocancel
,
726 BSC_getdirentriesattr
,
750 BSC_load_shared_file
,
754 BSC_aio_suspend_nocancel
,
771 BSC_lstat64_extended
,
772 BSC_fstat64_extended
,
784 #define MAX_FILEMGR 512
786 struct filemgr_call
{
788 } filemgr_calls
[MAX_FILEMGR
];
791 int filemgr_call_types
[] = {
792 FILEMGR_PBGETCATALOGINFO
,
793 FILEMGR_PBGETCATALOGINFOBULK
,
794 FILEMGR_PBCREATEFILEUNICODE
,
795 FILEMGR_PBCREATEDIRECTORYUNICODE
,
796 FILEMGR_PBCREATEFORK
,
797 FILEMGR_PBDELETEFORK
,
798 FILEMGR_PBITERATEFORK
,
802 FILEMGR_PBALLOCATEFORK
,
803 FILEMGR_PBDELETEOBJECT
,
804 FILEMGR_PBEXCHANGEOBJECT
,
805 FILEMGR_PBGETFORKCBINFO
,
806 FILEMGR_PBGETVOLUMEINFO
,
808 FILEMGR_PBMAKEFSREFUNICODE
,
809 FILEMGR_PBMOVEOBJECT
,
810 FILEMGR_PBOPENITERATOR
,
811 FILEMGR_PBRENAMEUNICODE
,
812 FILEMGR_PBSETCATALOGINFO
,
813 FILEMGR_PBSETVOLUMEINFO
,
814 FILEMGR_FSREFMAKEPATH
,
815 FILEMGR_FSPATHMAKEREF
,
817 FILEMGR_PBGETCATINFO
,
818 FILEMGR_PBGETCATINFOLITE
,
820 FILEMGR_PBXGETVOLINFO
,
824 FILEMGR_PBHGETDIRACCESS
,
825 FILEMGR_PBHSETDIRACCESS
,
835 FILEMGR_PBGETFCBINFO
,
838 FILEMGR_PBALLOCCONTIG
,
840 FILEMGR_PBSETCATINFO
,
841 FILEMGR_PBGETVOLPARMS
,
843 FILEMGR_PBMAKEFSSPEC
,
845 FILEMGR_PBCREATEFILEIDREF
,
846 FILEMGR_PBDELETEFILEIDREF
,
847 FILEMGR_PBRESOLVEFILEIDREF
,
851 FILEMGR_PBEXCHANGEFILES
,
858 FILEMGR_PBUNLOCKRANGE
,
868 int exclude_pids
= 0;
869 int exclude_default_pids
= 1;
872 struct kinfo_proc
*kp_buffer
= 0;
875 #define EVENT_BASE 60000
877 int num_events
= EVENT_BASE
;
880 #define DBG_FUNC_ALL (DBG_FUNC_START | DBG_FUNC_END)
881 #define DBG_FUNC_MASK 0xfffffffc
883 double divisor
= 0.0; /* Trace divisor converts to microseconds */
889 kbufinfo_t bufinfo
= {0, 0, 0, 0, 0};
892 /* defines for tracking file descriptor state */
893 #define FS_USAGE_FD_SETSIZE 256 /* Initial number of file descriptors per
894 thread that we will track */
896 #define FS_USAGE_NFDBITS (sizeof (unsigned long) * 8)
897 #define FS_USAGE_NFDBYTES(n) (((n) / FS_USAGE_NFDBITS) * sizeof (unsigned long))
899 int trace_enabled
= 0;
900 int set_remove_flag
= 1;
902 char *RAW_file
= (char *)0;
906 uint64_t sample_TOD_secs
;
907 uint32_t sample_TOD_usecs
;
909 double bias_now
= 0.0;
910 double start_time
= 0.0;
911 double end_time
= 999999999999.9;
924 void leave() /* exit under normal conditions -- INT handler */
929 void set_pidexclude();
936 if (exclude_pids
== 0) {
937 for (i
= 0; i
< num_of_pids
; i
++)
938 set_pidcheck(pids
[i
], 0);
941 for (i
= 0; i
< num_of_pids
; i
++)
942 set_pidexclude(pids
[i
], 0);
957 * This flag is turned off when calling
958 * quit() due to a set_remove() failure.
963 fprintf(stderr
, "fs_usage: ");
965 fprintf(stderr
, "%s", s
);
971 void get_screenwidth()
978 if (ioctl(1, TIOCGWINSZ
, &size
) != -1) {
979 columns
= size
.ws_col
;
981 if (columns
> MAXWIDTH
)
997 struct mach_timebase_info mti
;
999 mach_timebase_info(&mti
);
1001 divisor
= ((double)mti
.denom
/ (double)mti
.numer
) * 1000;
1006 exit_usage(char *myname
) {
1008 fprintf(stderr
, "Usage: %s [-e] [-w] [-f mode] [-R rawfile [-S start_time] [-E end_time]] [pid | cmd [pid | cmd]....]\n", myname
);
1009 fprintf(stderr
, " -e exclude the specified list of pids from the sample\n");
1010 fprintf(stderr
, " and exclude fs_usage by default\n");
1011 fprintf(stderr
, " -w force wider, detailed, output\n");
1012 fprintf(stderr
, " -f Output is based on the mode provided\n");
1013 fprintf(stderr
, " mode = \"network\" Show only network related output\n");
1014 fprintf(stderr
, " mode = \"filesys\" Show only file system related output\n");
1015 fprintf(stderr
, " mode = \"pathname\" Show only pathname related output\n");
1016 fprintf(stderr
, " mode = \"exec\" Show only execs\n");
1017 fprintf(stderr
, " mode = \"cachehit\" In addition, show cachehits\n");
1018 fprintf(stderr
, " -R specifies a raw trace file to process\n");
1019 fprintf(stderr
, " -S if -R is specified, selects a start point in microseconds\n");
1020 fprintf(stderr
, " -E if -R is specified, selects an end point in microseconds\n");
1021 fprintf(stderr
, " pid selects process(s) to sample\n");
1022 fprintf(stderr
, " cmd selects process(s) matching command string to sample\n");
1023 fprintf(stderr
, "\n%s will handle a maximum list of %d pids.\n\n", myname
, MAX_PIDS
);
1024 fprintf(stderr
, "By default (no options) the following processes are excluded from the output:\n");
1025 fprintf(stderr
, "fs_usage, Terminal, telnetd, sshd, rlogind, tcsh, csh, sh\n\n");
1031 int filemgr_index(type
) {
1034 return (((type
>> 2) & 0x3fff) + 256);
1036 return (((type
>> 2) & 0x3fff));
1040 void init_tables(void)
1046 for (i
= 0; i
< MAX_BSD_SYSCALL
; i
++) {
1047 bsd_syscalls
[i
].sc_name
= NULL
;
1048 bsd_syscalls
[i
].sc_format
= FMT_DEFAULT
;
1051 for (i
= 0; i
< MAX_FILEMGR
; i
++) {
1052 filemgr_calls
[i
].fm_name
= NULL
;
1055 for (i
= 0; (type
= bsd_syscall_types
[i
]); i
++) {
1057 code
= BSC_INDEX(type
);
1059 if (code
>= MAX_BSD_SYSCALL
) {
1060 printf("BSD syscall init (%x): type exceeds table size\n", type
);
1066 bsd_syscalls
[code
].sc_name
= "sendfile";
1067 bsd_syscalls
[code
].sc_format
= FMT_FD
; /* this should be changed to FMT_SENDFILE */
1068 break; /* once we add an extended info trace event */
1071 case BSC_recvmsg_nocancel
:
1072 bsd_syscalls
[code
].sc_name
= "recvmsg";
1073 bsd_syscalls
[code
].sc_format
= FMT_FD_IO
;
1077 case BSC_sendmsg_nocancel
:
1078 bsd_syscalls
[code
].sc_name
= "sendmsg";
1079 bsd_syscalls
[code
].sc_format
= FMT_FD_IO
;
1083 case BSC_recvfrom_nocancel
:
1084 bsd_syscalls
[code
].sc_name
= "recvfrom";
1085 bsd_syscalls
[code
].sc_format
= FMT_FD_IO
;
1089 case BSC_sendto_nocancel
:
1090 bsd_syscalls
[code
].sc_name
= "sendto";
1091 bsd_syscalls
[code
].sc_format
= FMT_FD_IO
;
1095 case BSC_select_nocancel
:
1096 bsd_syscalls
[code
].sc_name
= "select";
1097 bsd_syscalls
[code
].sc_format
= FMT_SELECT
;
1101 case BSC_accept_nocancel
:
1102 bsd_syscalls
[code
].sc_name
= "accept";
1103 bsd_syscalls
[code
].sc_format
= FMT_FD_2
;
1107 bsd_syscalls
[code
].sc_name
= "socket";
1108 bsd_syscalls
[code
].sc_format
= FMT_SOCKET
;
1112 case BSC_connect_nocancel
:
1113 bsd_syscalls
[code
].sc_name
= "connect";
1114 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1118 bsd_syscalls
[code
].sc_name
= "bind";
1119 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1123 bsd_syscalls
[code
].sc_name
= "listen";
1124 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1128 bsd_syscalls
[code
].sc_name
= "mmap";
1129 bsd_syscalls
[code
].sc_format
= FMT_MMAP
;
1132 case BSC_socketpair
:
1133 bsd_syscalls
[code
].sc_name
= "socketpair";
1137 bsd_syscalls
[code
].sc_name
= "getxattr";
1141 bsd_syscalls
[code
].sc_name
= "setxattr";
1144 case BSC_removexattr
:
1145 bsd_syscalls
[code
].sc_name
= "removexattr";
1149 bsd_syscalls
[code
].sc_name
= "listxattr";
1153 bsd_syscalls
[code
].sc_name
= "stat";
1157 bsd_syscalls
[code
].sc_name
= "stat64";
1160 case BSC_stat_extended
:
1161 bsd_syscalls
[code
].sc_name
= "stat_extended";
1164 case BSC_stat64_extended
:
1165 bsd_syscalls
[code
].sc_name
= "stat_extended64";
1169 bsd_syscalls
[code
].sc_name
= "mount";
1170 bsd_syscalls
[code
].sc_format
= FMT_MOUNT
;
1174 bsd_syscalls
[code
].sc_name
= "unmount";
1175 bsd_syscalls
[code
].sc_format
= FMT_UNMOUNT
;
1179 bsd_syscalls
[code
].sc_name
= "exit";
1183 bsd_syscalls
[code
].sc_name
= "execve";
1186 case BSC_posix_spawn
:
1187 bsd_syscalls
[code
].sc_name
= "posix_spawn";
1190 case BSC_load_shared_file
:
1191 bsd_syscalls
[code
].sc_name
= "load_sf";
1195 case BSC_open_nocancel
:
1196 bsd_syscalls
[code
].sc_name
= "open";
1197 bsd_syscalls
[code
].sc_format
= FMT_OPEN
;
1200 case BSC_open_extended
:
1201 bsd_syscalls
[code
].sc_name
= "open_extended";
1202 bsd_syscalls
[code
].sc_format
= FMT_OPEN
;
1206 bsd_syscalls
[code
].sc_name
= "dup";
1207 bsd_syscalls
[code
].sc_format
= FMT_FD_2
;
1211 bsd_syscalls
[code
].sc_name
= "dup2";
1212 bsd_syscalls
[code
].sc_format
= FMT_FD_2
;
1216 case BSC_close_nocancel
:
1217 bsd_syscalls
[code
].sc_name
= "close";
1218 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1222 case BSC_read_nocancel
:
1223 bsd_syscalls
[code
].sc_name
= "read";
1224 bsd_syscalls
[code
].sc_format
= FMT_FD_IO
;
1228 case BSC_write_nocancel
:
1229 bsd_syscalls
[code
].sc_name
= "write";
1230 bsd_syscalls
[code
].sc_format
= FMT_FD_IO
;
1234 bsd_syscalls
[code
].sc_name
= "fgetxattr";
1235 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1239 bsd_syscalls
[code
].sc_name
= "fsetxattr";
1240 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1243 case BSC_fremovexattr
:
1244 bsd_syscalls
[code
].sc_name
= "fremovexattr";
1245 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1248 case BSC_flistxattr
:
1249 bsd_syscalls
[code
].sc_name
= "flistxattr";
1250 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1254 bsd_syscalls
[code
].sc_name
= "fstat";
1255 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1259 bsd_syscalls
[code
].sc_name
= "fstat64";
1260 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1263 case BSC_fstat_extended
:
1264 bsd_syscalls
[code
].sc_name
= "fstat_extended";
1265 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1268 case BSC_fstat64_extended
:
1269 bsd_syscalls
[code
].sc_name
= "fstat64_extended";
1270 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1274 bsd_syscalls
[code
].sc_name
= "lstat";
1278 bsd_syscalls
[code
].sc_name
= "lstat64";
1281 case BSC_lstat_extended
:
1282 bsd_syscalls
[code
].sc_name
= "lstat_extended";
1285 case BSC_lstat64_extended
:
1286 bsd_syscalls
[code
].sc_name
= "lstat_extended64";
1290 bsd_syscalls
[code
].sc_name
= "lstatv";
1294 bsd_syscalls
[code
].sc_name
= "link";
1298 bsd_syscalls
[code
].sc_name
= "unlink";
1302 bsd_syscalls
[code
].sc_name
= "mknod";
1306 bsd_syscalls
[code
].sc_name
= "umask";
1307 bsd_syscalls
[code
].sc_format
= FMT_UMASK
;
1311 bsd_syscalls
[code
].sc_name
= "chmod";
1312 bsd_syscalls
[code
].sc_format
= FMT_CHMOD
;
1315 case BSC_chmod_extended
:
1316 bsd_syscalls
[code
].sc_name
= "chmod_extended";
1317 bsd_syscalls
[code
].sc_format
= FMT_CHMOD_EXT
;
1321 bsd_syscalls
[code
].sc_name
= "fchmod";
1322 bsd_syscalls
[code
].sc_format
= FMT_FCHMOD
;
1325 case BSC_fchmod_extended
:
1326 bsd_syscalls
[code
].sc_name
= "fchmod_extended";
1327 bsd_syscalls
[code
].sc_format
= FMT_FCHMOD_EXT
;
1331 bsd_syscalls
[code
].sc_name
= "chown";
1335 bsd_syscalls
[code
].sc_name
= "lchown";
1339 bsd_syscalls
[code
].sc_name
= "fchown";
1340 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1344 bsd_syscalls
[code
].sc_name
= "access";
1345 bsd_syscalls
[code
].sc_format
= FMT_ACCESS
;
1348 case BSC_access_extended
:
1349 bsd_syscalls
[code
].sc_name
= "access_extended";
1353 bsd_syscalls
[code
].sc_name
= "chdir";
1356 case BSC_pthread_chdir
:
1357 bsd_syscalls
[code
].sc_name
= "pthread_chdir";
1361 bsd_syscalls
[code
].sc_name
= "chroot";
1365 bsd_syscalls
[code
].sc_name
= "utimes";
1369 bsd_syscalls
[code
].sc_name
= "delete-Carbon";
1373 bsd_syscalls
[code
].sc_name
= "undelete";
1377 bsd_syscalls
[code
].sc_name
= "revoke";
1381 bsd_syscalls
[code
].sc_name
= "fsctl";
1385 bsd_syscalls
[code
].sc_name
= "chflags";
1386 bsd_syscalls
[code
].sc_format
= FMT_CHFLAGS
;
1390 bsd_syscalls
[code
].sc_name
= "fchflags";
1391 bsd_syscalls
[code
].sc_format
= FMT_FCHFLAGS
;
1395 bsd_syscalls
[code
].sc_name
= "fchdir";
1396 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1399 case BSC_pthread_fchdir
:
1400 bsd_syscalls
[code
].sc_name
= "pthread_fchdir";
1401 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1405 bsd_syscalls
[code
].sc_name
= "futimes";
1406 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1410 bsd_syscalls
[code
].sc_name
= "sync";
1414 bsd_syscalls
[code
].sc_name
= "symlink";
1418 bsd_syscalls
[code
].sc_name
= "readlink";
1422 case BSC_fsync_nocancel
:
1423 bsd_syscalls
[code
].sc_name
= "fsync";
1424 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1428 case BSC_readv_nocancel
:
1429 bsd_syscalls
[code
].sc_name
= "readv";
1430 bsd_syscalls
[code
].sc_format
= FMT_FD_IO
;
1434 case BSC_writev_nocancel
:
1435 bsd_syscalls
[code
].sc_name
= "writev";
1436 bsd_syscalls
[code
].sc_format
= FMT_FD_IO
;
1440 case BSC_pread_nocancel
:
1441 bsd_syscalls
[code
].sc_name
= "pread";
1442 bsd_syscalls
[code
].sc_format
= FMT_PREAD
;
1446 case BSC_pwrite_nocancel
:
1447 bsd_syscalls
[code
].sc_name
= "pwrite";
1448 bsd_syscalls
[code
].sc_format
= FMT_PREAD
;
1452 bsd_syscalls
[code
].sc_name
= "mkdir";
1455 case BSC_mkdir_extended
:
1456 bsd_syscalls
[code
].sc_name
= "mkdir_extended";
1460 bsd_syscalls
[code
].sc_name
= "mkfifo";
1463 case BSC_mkfifo_extended
:
1464 bsd_syscalls
[code
].sc_name
= "mkfifo_extended";
1468 bsd_syscalls
[code
].sc_name
= "rmdir";
1472 bsd_syscalls
[code
].sc_name
= "statfs";
1476 bsd_syscalls
[code
].sc_name
= "statfs64";
1480 bsd_syscalls
[code
].sc_name
= "getfsstat";
1483 case BSC_getfsstat64
:
1484 bsd_syscalls
[code
].sc_name
= "getfsstat64";
1488 bsd_syscalls
[code
].sc_name
= "fstatfs";
1489 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1493 bsd_syscalls
[code
].sc_name
= "fstatfs64";
1494 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1498 bsd_syscalls
[code
].sc_name
= "pathconf";
1502 bsd_syscalls
[code
].sc_name
= "fpathconf";
1503 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1506 case BSC_getdirentries
:
1507 bsd_syscalls
[code
].sc_name
= "getdirentries";
1508 bsd_syscalls
[code
].sc_format
= FMT_FD_IO
;
1511 case BSC_getdirentries64
:
1512 bsd_syscalls
[code
].sc_name
= "getdirentries64";
1513 bsd_syscalls
[code
].sc_format
= FMT_FD_IO
;
1517 bsd_syscalls
[code
].sc_name
= "lseek";
1518 bsd_syscalls
[code
].sc_format
= FMT_LSEEK
;
1522 bsd_syscalls
[code
].sc_name
= "truncate";
1523 bsd_syscalls
[code
].sc_format
= FMT_TRUNC
;
1527 bsd_syscalls
[code
].sc_name
= "ftruncate";
1528 bsd_syscalls
[code
].sc_format
= FMT_FTRUNC
;
1532 bsd_syscalls
[code
].sc_name
= "statv";
1536 bsd_syscalls
[code
].sc_name
= "fstatv";
1537 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1541 bsd_syscalls
[code
].sc_name
= "mkcomplex";
1544 case BSC_getattrlist
:
1545 bsd_syscalls
[code
].sc_name
= "getattrlist";
1548 case BSC_setattrlist
:
1549 bsd_syscalls
[code
].sc_name
= "setattrlist";
1552 case BSC_getdirentriesattr
:
1553 bsd_syscalls
[code
].sc_name
= "getdirentriesattr";
1554 bsd_syscalls
[code
].sc_format
= FMT_FD
;
1557 case BSC_exchangedata
:
1558 bsd_syscalls
[code
].sc_name
= "exchangedata";
1562 bsd_syscalls
[code
].sc_name
= "rename";
1566 bsd_syscalls
[code
].sc_name
= "copyfile";
1569 case BSC_checkuseraccess
:
1570 bsd_syscalls
[code
].sc_name
= "checkuseraccess";
1574 bsd_syscalls
[code
].sc_name
= "searchfs";
1578 bsd_syscalls
[code
].sc_name
= "aio_fsync";
1579 bsd_syscalls
[code
].sc_format
= FMT_AIO_FSYNC
;
1582 case BSC_aio_return
:
1583 bsd_syscalls
[code
].sc_name
= "aio_return";
1584 bsd_syscalls
[code
].sc_format
= FMT_AIO_RETURN
;
1587 case BSC_aio_suspend
:
1588 case BSC_aio_suspend_nocancel
:
1589 bsd_syscalls
[code
].sc_name
= "aio_suspend";
1590 bsd_syscalls
[code
].sc_format
= FMT_AIO_SUSPEND
;
1593 case BSC_aio_cancel
:
1594 bsd_syscalls
[code
].sc_name
= "aio_cancel";
1595 bsd_syscalls
[code
].sc_format
= FMT_AIO_CANCEL
;
1599 bsd_syscalls
[code
].sc_name
= "aio_error";
1600 bsd_syscalls
[code
].sc_format
= FMT_AIO
;
1604 bsd_syscalls
[code
].sc_name
= "aio_read";
1605 bsd_syscalls
[code
].sc_format
= FMT_AIO
;
1609 bsd_syscalls
[code
].sc_name
= "aio_write";
1610 bsd_syscalls
[code
].sc_format
= FMT_AIO
;
1613 case BSC_lio_listio
:
1614 bsd_syscalls
[code
].sc_name
= "lio_listio";
1615 bsd_syscalls
[code
].sc_format
= FMT_LIO_LISTIO
;
1619 case BSC_msync_nocancel
:
1620 bsd_syscalls
[code
].sc_name
= "msync";
1621 bsd_syscalls
[code
].sc_format
= FMT_MSYNC
;
1625 case BSC_fcntl_nocancel
:
1626 bsd_syscalls
[code
].sc_name
= "fcntl";
1627 bsd_syscalls
[code
].sc_format
= FMT_FCNTL
;
1631 bsd_syscalls
[code
].sc_name
= "ioctl";
1632 bsd_syscalls
[code
].sc_format
= FMT_IOCTL
;
1637 for (i
= 0; (type
= filemgr_call_types
[i
]); i
++) {
1640 code
= filemgr_index(type
);
1642 if (code
>= MAX_FILEMGR
) {
1643 printf("FILEMGR call init (%x): type exceeds table size\n", type
);
1648 case FILEMGR_PBGETCATALOGINFO
:
1649 p
= "GetCatalogInfo";
1652 case FILEMGR_PBGETCATALOGINFOBULK
:
1653 p
= "GetCatalogInfoBulk";
1656 case FILEMGR_PBCREATEFILEUNICODE
:
1657 p
= "CreateFileUnicode";
1660 case FILEMGR_PBCREATEDIRECTORYUNICODE
:
1661 p
= "CreateDirectoryUnicode";
1664 case FILEMGR_PBCREATEFORK
:
1668 case FILEMGR_PBDELETEFORK
:
1672 case FILEMGR_PBITERATEFORK
:
1673 p
= "PBIterateFork";
1676 case FILEMGR_PBOPENFORK
:
1680 case FILEMGR_PBREADFORK
:
1684 case FILEMGR_PBWRITEFORK
:
1688 case FILEMGR_PBALLOCATEFORK
:
1689 p
= "PBAllocateFork";
1692 case FILEMGR_PBDELETEOBJECT
:
1693 p
= "PBDeleteObject";
1696 case FILEMGR_PBEXCHANGEOBJECT
:
1697 p
= "PBExchangeObject";
1700 case FILEMGR_PBGETFORKCBINFO
:
1701 p
= "PBGetForkCBInfo";
1704 case FILEMGR_PBGETVOLUMEINFO
:
1705 p
= "PBGetVolumeInfo";
1708 case FILEMGR_PBMAKEFSREF
:
1712 case FILEMGR_PBMAKEFSREFUNICODE
:
1713 p
= "PBMakeFSRefUnicode";
1716 case FILEMGR_PBMOVEOBJECT
:
1720 case FILEMGR_PBOPENITERATOR
:
1721 p
= "PBOpenIterator";
1724 case FILEMGR_PBRENAMEUNICODE
:
1725 p
= "PBRenameUnicode";
1728 case FILEMGR_PBSETCATALOGINFO
:
1729 p
= "SetCatalogInfo";
1732 case FILEMGR_PBSETVOLUMEINFO
:
1733 p
= "SetVolumeInfo";
1736 case FILEMGR_FSREFMAKEPATH
:
1737 p
= "FSRefMakePath";
1740 case FILEMGR_FSPATHMAKEREF
:
1741 p
= "FSPathMakeRef";
1744 case FILEMGR_PBGETCATINFO
:
1748 case FILEMGR_PBGETCATINFOLITE
:
1749 p
= "GetCatInfoLite";
1752 case FILEMGR_PBHGETFINFO
:
1756 case FILEMGR_PBXGETVOLINFO
:
1757 p
= "PBXGetVolInfo";
1760 case FILEMGR_PBHCREATE
:
1764 case FILEMGR_PBHOPENDF
:
1768 case FILEMGR_PBHOPENRF
:
1772 case FILEMGR_PBHGETDIRACCESS
:
1773 p
= "PBHGetDirAccess";
1776 case FILEMGR_PBHSETDIRACCESS
:
1777 p
= "PBHSetDirAccess";
1780 case FILEMGR_PBHMAPID
:
1784 case FILEMGR_PBHMAPNAME
:
1788 case FILEMGR_PBCLOSE
:
1792 case FILEMGR_PBFLUSHFILE
:
1796 case FILEMGR_PBGETEOF
:
1800 case FILEMGR_PBSETEOF
:
1804 case FILEMGR_PBGETFPOS
:
1808 case FILEMGR_PBREAD
:
1812 case FILEMGR_PBWRITE
:
1816 case FILEMGR_PBGETFCBINFO
:
1820 case FILEMGR_PBSETFINFO
:
1824 case FILEMGR_PBALLOCATE
:
1828 case FILEMGR_PBALLOCCONTIG
:
1829 p
= "PBAllocContig";
1832 case FILEMGR_PBSETFPOS
:
1836 case FILEMGR_PBSETCATINFO
:
1840 case FILEMGR_PBGETVOLPARMS
:
1841 p
= "PBGetVolParms";
1844 case FILEMGR_PBSETVINFO
:
1848 case FILEMGR_PBMAKEFSSPEC
:
1852 case FILEMGR_PBHGETVINFO
:
1856 case FILEMGR_PBCREATEFILEIDREF
:
1857 p
= "PBCreateFileIDRef";
1860 case FILEMGR_PBDELETEFILEIDREF
:
1861 p
= "PBDeleteFileIDRef";
1864 case FILEMGR_PBRESOLVEFILEIDREF
:
1865 p
= "PBResolveFileIDRef";
1868 case FILEMGR_PBFLUSHVOL
:
1872 case FILEMGR_PBHRENAME
:
1876 case FILEMGR_PBCATMOVE
:
1880 case FILEMGR_PBEXCHANGEFILES
:
1881 p
= "PBExchangeFiles";
1884 case FILEMGR_PBHDELETE
:
1888 case FILEMGR_PBDIRCREATE
:
1892 case FILEMGR_PBCATSEARCH
:
1896 case FILEMGR_PBHSETFLOCK
:
1900 case FILEMGR_PBHRSTFLOCK
:
1904 case FILEMGR_PBLOCKRANGE
:
1908 case FILEMGR_PBUNLOCKRANGE
:
1909 p
= "PBUnlockRange";
1916 filemgr_calls
[code
].fm_name
= p
;
1927 char *myname
= "fs_usage";
1931 if (0 != reexec_to_match_kernel()) {
1932 fprintf(stderr
, "Could not re-execute: %d\n", errno
);
1941 if ((myname
= rindex(argv
[0], '/')) == 0)
1947 while ((ch
= getopt(argc
, argv
, "ewf:R:S:E:")) != EOF
) {
1953 exclude_default_pids
= 0;
1958 if ((uint
)columns
< MAX_WIDE_MODE_COLS
)
1959 columns
= MAX_WIDE_MODE_COLS
;
1963 if (!strcmp(optarg
, "network"))
1964 filter_mode
|= NETWORK_FILTER
;
1965 else if (!strcmp(optarg
, "filesys"))
1966 filter_mode
|= FILESYS_FILTER
;
1967 else if (!strcmp(optarg
, "cachehit"))
1968 filter_mode
&= ~CACHEHIT_FILTER
; /* turns on CACHE_HIT */
1969 else if (!strcmp(optarg
, "exec"))
1970 filter_mode
|= EXEC_FILTER
;
1971 else if (!strcmp(optarg
, "pathname"))
1972 filter_mode
|= PATHNAME_FILTER
;
1981 start_time
= atof(optarg
);
1985 end_time
= atof(optarg
);
1993 if ( geteuid() != 0 ) {
1994 fprintf(stderr
, "'fs_usage' must be run as root...\n");
2002 * when excluding, fs_usage should be the first in line for pids[]
2004 * the !exclude_pids && argc == 0 catches the exclude_default_pids
2005 * case below where exclude_pids is later set and the fs_usage PID
2006 * needs to make it into pids[]
2008 if (exclude_pids
|| (!exclude_pids
&& argc
== 0)) {
2009 if (num_of_pids
< (MAX_PIDS
- 1))
2010 pids
[num_of_pids
++] = getpid();
2014 * If we process any list of pids/cmds, then turn off the defaults
2017 exclude_default_pids
= 0;
2019 while (argc
> 0 && num_of_pids
< (MAX_PIDS
- 1)) {
2026 * Exclude a set of default pids
2028 if (exclude_default_pids
) {
2029 argtopid("Terminal");
2030 argtopid("telnetd");
2033 argtopid("rlogind");
2040 for (i
= 0; i
< num_of_pids
; i
++) {
2042 fprintf(stderr
, "exclude pid %d\n", pids
[i
]);
2044 fprintf(stderr
, "pid %d\n", pids
[i
]);
2048 struct sigaction osa
;
2052 /* set up signal handlers */
2053 signal(SIGINT
, leave
);
2054 signal(SIGQUIT
, leave
);
2056 sigaction(SIGHUP
, (struct sigaction
*)NULL
, &osa
);
2058 if (osa
.sa_handler
== SIG_DFL
)
2059 signal(SIGHUP
, leave
);
2060 signal(SIGTERM
, leave
);
2062 * grab the number of cpus
2067 len
= sizeof(num_cpus
);
2069 sysctl(mib
, 2, &num_cpus
, &len
, NULL
, 0);
2070 num_events
= EVENT_BASE
* num_cpus
;
2072 signal(SIGWINCH
, sigwinch
);
2074 if ((my_buffer
= malloc(num_events
* sizeof(kd_buf
))) == (char *)0)
2075 quit("can't allocate memory for tracing info\n");
2077 if (ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_i386.map", &framework32
, "/var/db/dyld/dyld_shared_cache_i386")) {
2078 ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_x86_64.map", &framework64
, "/var/db/dyld/dyld_shared_cache_x86_64");
2080 ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_ppc.map", &framework32
, "/var/db/dyld/dyld_shared_cache_ppc");
2081 ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_ppc64.map", &framework64
, "/var/db/dyld/dyld_shared_cache_ppc64");
2083 SortFrameworkAddresses();
2090 set_numbufs(num_events
);
2093 if (exclude_pids
== 0) {
2094 for (i
= 0; i
< num_of_pids
; i
++)
2095 set_pidcheck(pids
[i
], 1);
2097 for (i
= 0; i
< num_of_pids
; i
++)
2098 set_pidexclude(pids
[i
], 1);
2100 if (select_pid_mode
&& !one_good_pid
) {
2102 * An attempt to restrict output to a given
2103 * pid or command has failed. Exit gracefully
2110 init_arguments_buffer();
2121 usleep(1000 * usleep_ms
);
2125 last_time
= time((long *)0);
2134 struct kinfo_proc
*kp
;
2138 mib
[2] = KERN_PROC_ALL
;
2141 if (sysctl(mib
, 4, NULL
, &bufSize
, NULL
, 0) < 0)
2142 quit("trace facility failure, KERN_PROC_ALL\n");
2144 if ((kp
= (struct kinfo_proc
*)malloc(bufSize
)) == (struct kinfo_proc
*)0)
2145 quit("can't allocate memory for proc buffer\n");
2147 if (sysctl(mib
, 4, kp
, &bufSize
, NULL
, 0) < 0)
2148 quit("trace facility failure, KERN_PROC_ALL\n");
2150 kp_nentries
= bufSize
/ sizeof(struct kinfo_proc
);
2159 mib
[1] = KERN_KDEBUG
;
2160 mib
[2] = KERN_KDENABLE
; /* protocol */
2163 mib
[5] = 0; /* no flags */
2165 if (sysctl(mib
, 4, NULL
, &needed
, NULL
, 0) < 0)
2166 quit("trace facility failure, KERN_KDENABLE\n");
2175 set_numbufs(int nbufs
)
2178 mib
[1] = KERN_KDEBUG
;
2179 mib
[2] = KERN_KDSETBUF
;
2182 mib
[5] = 0; /* no flags */
2184 if (sysctl(mib
, 4, NULL
, &needed
, NULL
, 0) < 0)
2185 quit("trace facility failure, KERN_KDSETBUF\n");
2188 mib
[1] = KERN_KDEBUG
;
2189 mib
[2] = KERN_KDSETUP
;
2192 mib
[5] = 0; /* no flags */
2194 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0)
2195 quit("trace facility failure, KERN_KDSETUP\n");
2199 set_pidcheck(int pid
, int on_off
)
2203 kr
.type
= KDBG_TYPENONE
;
2206 needed
= sizeof(kd_regtype
);
2208 mib
[1] = KERN_KDEBUG
;
2209 mib
[2] = KERN_KDPIDTR
;
2214 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0) {
2216 fprintf(stderr
, "pid %d does not exist\n", pid
);
2222 * on_off == 0 turns off pid exclusion
2223 * on_off == 1 turns on pid exclusion
2226 set_pidexclude(int pid
, int on_off
)
2232 kr
.type
= KDBG_TYPENONE
;
2235 needed
= sizeof(kd_regtype
);
2237 mib
[1] = KERN_KDEBUG
;
2238 mib
[2] = KERN_KDPIDEX
;
2243 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0) {
2245 fprintf(stderr
, "pid %d does not exist\n", pid
);
2250 get_bufinfo(kbufinfo_t
*val
)
2252 needed
= sizeof (*val
);
2254 mib
[1] = KERN_KDEBUG
;
2255 mib
[2] = KERN_KDGETBUF
;
2258 mib
[5] = 0; /* no flags */
2260 if (sysctl(mib
, 3, val
, &needed
, 0, 0) < 0)
2261 quit("trace facility failure, KERN_KDGETBUF\n");
2271 mib
[1] = KERN_KDEBUG
;
2272 mib
[2] = KERN_KDREMOVE
; /* protocol */
2275 mib
[5] = 0; /* no flags */
2277 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0) {
2278 set_remove_flag
= 0;
2281 quit("the trace facility is currently in use...\n fs_usage, sc_usage, and latency use this feature.\n\n");
2283 quit("trace facility failure, KERN_KDREMOVE\n");
2291 kr
.type
= KDBG_RANGETYPE
;
2294 needed
= sizeof(kd_regtype
);
2297 mib
[1] = KERN_KDEBUG
;
2298 mib
[2] = KERN_KDSETREG
;
2301 mib
[5] = 0; /* no flags */
2303 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0)
2304 quit("trace facility failure, KERN_KDSETREG\n");
2307 mib
[1] = KERN_KDEBUG
;
2308 mib
[2] = KERN_KDSETUP
;
2311 mib
[5] = 0; /* no flags */
2313 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0)
2314 quit("trace facility failure, KERN_KDSETUP\n");
2323 uint32_t my_buffer_size
= 0;
2326 get_bufinfo(&bufinfo
);
2328 my_buffer_size
= num_events
* sizeof(kd_buf
);
2335 needed
= bufinfo
.nkdbufs
* sizeof(kd_buf
);
2338 mib
[1] = KERN_KDEBUG
;
2339 mib
[2] = KERN_KDREADTR
;
2342 mib
[5] = 0; /* no flags */
2344 if (sysctl(mib
, 3, my_buffer
, &needed
, NULL
, 0) < 0)
2345 quit("trace facility failure, KERN_KDREADTR\n");
2348 if (count
> (num_events
/ 8)) {
2349 if (usleep_ms
> USLEEP_BEHIND
)
2350 usleep_ms
= USLEEP_BEHIND
;
2351 else if (usleep_ms
> USLEEP_MIN
)
2354 } else if (count
< (num_events
/ 16)) {
2355 if (usleep_ms
< USLEEP_MAX
)
2359 if (bufinfo
.flags
& KDBG_WRAPPED
) {
2360 fprintf(stderr
, "fs_usage: buffer overrun, events generated too quickly: %d\n", count
);
2362 delete_all_events();
2372 if ((bytes_read
= read(RAW_fd
, my_buffer
, my_buffer_size
)) < sizeof(kd_buf
))
2374 count
= bytes_read
/ sizeof(kd_buf
);
2376 kd
= (kd_buf
*)my_buffer
;
2378 fprintf(stderr
, "READTR returned %d items\n", count
);
2380 for (i
= 0; i
< count
; i
++) {
2394 thread
= kd
[i
].arg5
;
2395 debugid
= kd
[i
].debugid
;
2396 type
= kd
[i
].debugid
& DBG_FUNC_MASK
;
2398 now
= kdbg_get_timestamp(&kd
[i
]);
2400 if (i
== 0 && !RAW_flag
) {
2402 curr_time
= time((long *)0);
2404 * Compute bias seconds after each trace buffer read.
2405 * This helps resync timestamps with the system clock
2406 * in the event of a system sleep.
2408 if (bias_secs
== 0 || curr_time
< last_time
|| curr_time
> (last_time
+ 2)) {
2409 l_usecs
= (long long)(now
/ divisor
);
2410 secs
= l_usecs
/ 1000000;
2411 bias_secs
= curr_time
- secs
;
2414 if (RAW_flag
&& bias_now
== 0.0)
2417 if ((type
& P_DISKIO_MASK
) == P_DISKIO
) {
2418 insert_diskio(type
, kd
[i
].arg1
, kd
[i
].arg2
, kd
[i
].arg3
, kd
[i
].arg4
, thread
, (double)now
);
2421 if ((type
& P_DISKIO_MASK
) == P_DISKIO_DONE
) {
2422 if ((dio
= complete_diskio(kd
[i
].arg1
, kd
[i
].arg4
, kd
[i
].arg3
, thread
, (double)now
))) {
2429 if ((type
& CLASS_MASK
) == P_CS_Class
) {
2431 // the usual DBG_FUNC_START/END does not work for i/o since it will
2432 // return on a different thread, this code uses the P_CS_IO_Done (0x4) bit
2433 // instead. the trace command doesn't know how handle either method
2434 // (unmatched start/end or 0x4) but works a little better this way.
2436 int cs_type
= type
& P_CS_Type_Mask
; // strip out the done bit
2437 bool start
= (type
& P_CS_IO_Done
) != P_CS_IO_Done
;
2441 case P_CS_ReadChunk
:
2442 case P_CS_WriteChunk
:
2444 case P_CS_MetaWrite
:
2446 insert_diskio(cs_type
, kd
[i
].arg2
, kd
[i
].arg1
, kd
[i
].arg3
, kd
[i
].arg4
, thread
, (double)now
);
2448 if ((dio
= complete_diskio(kd
[i
].arg2
, kd
[i
].arg4
, kd
[i
].arg3
, thread
, (double)now
))) {
2455 case P_CS_TransformRead
:
2456 case P_CS_TransformWrite
:
2457 case P_CS_MigrationRead
:
2458 case P_CS_MigrationWrite
:
2460 insert_diskio(cs_type
, kd
[i
].arg2
, CS_DEV
, kd
[i
].arg3
, kd
[i
].arg4
, thread
, (double)now
);
2462 if ((dio
= complete_diskio(kd
[i
].arg2
, kd
[i
].arg4
, kd
[i
].arg3
, thread
, (double)now
))) {
2469 case P_CS_SYNC_DISK
:
2471 enter_event(thread
, cs_type
, &kd
[i
], NULL
, (double)now
);
2473 exit_event(" SyncCacheCS", thread
, cs_type
, kd
[i
].arg1
, 0, 0, 0, FMT_SYNC_DISK_CS
, (double)now
);
2478 continue; // ignore other cs timestamps
2483 case TRACE_DATA_NEWTHREAD
:
2485 if ((ti
= add_event(thread
, TRACE_DATA_NEWTHREAD
)) == NULL
)
2487 ti
->child_thread
= kd
[i
].arg1
;
2488 ti
->pid
= kd
[i
].arg2
;
2492 case TRACE_STRING_NEWTHREAD
:
2493 if ((ti
= find_event(thread
, TRACE_DATA_NEWTHREAD
)) == (struct th_info
*)0)
2496 create_map_entry(ti
->child_thread
, ti
->pid
, (char *)&kd
[i
].arg1
);
2501 case TRACE_DATA_EXEC
:
2502 if ((ti
= add_event(thread
, TRACE_DATA_EXEC
)) == NULL
)
2505 ti
->pid
= kd
[i
].arg1
;
2508 case TRACE_STRING_EXEC
:
2509 if ((ti
= find_event(thread
, BSC_execve
))) {
2510 if (ti
->pathname
[0])
2511 exit_event("execve", thread
, BSC_execve
, 0, 0, 0, 0, FMT_DEFAULT
, (double)now
);
2513 } else if ((ti
= find_event(thread
, BSC_posix_spawn
))) {
2514 if (ti
->pathname
[0])
2515 exit_event("posix_spawn", thread
, BSC_posix_spawn
, 0, 0, 0, 0, FMT_DEFAULT
, (double)now
);
2517 if ((ti
= find_event(thread
, TRACE_DATA_EXEC
)) == (struct th_info
*)0)
2520 create_map_entry(thread
, ti
->pid
, (char *)&kd
[i
].arg1
);
2525 case BSC_thread_terminate
:
2526 delete_map_entry(thread
);
2533 kd
[i
].arg1
= kd
[i
].arg2
>> 8;
2538 if (kd
[i
].arg4
& MAP_ANON
)
2544 case MACH_stkhandoff
:
2545 mark_thread_waited(thread
);
2549 if ((ti
= find_event(thread
, 0)) == (struct th_info
*)0)
2552 if (debugid
& DBG_FUNC_START
) {
2553 if (ti
->pathname2
[0])
2555 if (ti
->pathname
[0] == 0)
2556 sargptr
= ti
->pathname
;
2558 sargptr
= ti
->pathname2
;
2559 *sargptr
++ = kd
[i
].arg2
;
2560 *sargptr
++ = kd
[i
].arg3
;
2561 *sargptr
++ = kd
[i
].arg4
;
2563 * NULL terminate the 'string'
2567 ti
->pathptr
= sargptr
;
2569 sargptr
= ti
->pathptr
;
2572 * We don't want to overrun our pathname buffer if the
2573 * kernel sends us more VFS_LOOKUP entries than we can
2574 * handle and we only handle 2 pathname lookups for
2575 * a given system call
2579 if (ti
->pathname2
[0]) {
2580 if ((uintptr_t)sargptr
>= (uintptr_t)&ti
->pathname2
[NUMPARMS
])
2583 if ((uintptr_t)sargptr
>= (uintptr_t)&ti
->pathname
[NUMPARMS
])
2586 *sargptr
++ = kd
[i
].arg1
;
2587 *sargptr
++ = kd
[i
].arg2
;
2588 *sargptr
++ = kd
[i
].arg3
;
2589 *sargptr
++ = kd
[i
].arg4
;
2591 * NULL terminate the 'string'
2595 if (debugid
& DBG_FUNC_END
) {
2596 if (ti
->pathname2
[0])
2599 ti
->pathptr
= ti
->pathname2
;
2601 ti
->pathptr
= sargptr
;
2606 if (debugid
& DBG_FUNC_START
) {
2609 if ((type
& CLASS_MASK
) == FILEMGR_BASE
) {
2611 index
= filemgr_index(type
);
2613 if (index
>= MAX_FILEMGR
)
2616 if ((p
= filemgr_calls
[index
].fm_name
) == NULL
)
2621 enter_event(thread
, type
, &kd
[i
], p
, (double)now
);
2628 exit_event(" THROTTLED", thread
, type
, 0, 0, 0, 0, FMT_DEFAULT
, (double)now
);
2631 case SPEC_unmap_info
:
2632 if (check_filter_mode(NULL
, SPEC_unmap_info
, 0, 0, "SPEC_unmap_info"))
2633 format_print(NULL
, " TrimExtent", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, kd
[i
].arg3
, 0, FMT_UNMAP_INFO
, now
, now
, 0, "", NULL
);
2637 if (kd
[i
].arg2
== DKIOCSYNCHRONIZECACHE
)
2638 exit_event("IOCTL", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, FMT_IOCTL_SYNC
, (double)now
);
2639 else if (kd
[i
].arg2
== DKIOCUNMAP
)
2640 exit_event("IOCTL", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, FMT_IOCTL_UNMAP
, (double)now
);
2642 if ((ti
= find_event(thread
, type
)))
2649 exit_event("PAGE_OUT_ANON", thread
, type
, 0, kd
[i
].arg1
, 0, 0, FMT_PGOUT
, (double)now
);
2651 exit_event("PAGE_OUT_FILE", thread
, type
, 0, kd
[i
].arg1
, 0, 0, FMT_PGOUT
, (double)now
);
2655 if (kd
[i
].arg4
== DBG_PAGEIN_FAULT
)
2656 exit_event("PAGE_IN", thread
, type
, 0, kd
[i
].arg1
, kd
[i
].arg2
, 0, FMT_PGIN
, (double)now
);
2657 else if (kd
[i
].arg4
== DBG_PAGEINV_FAULT
)
2658 exit_event("PAGE_IN_FILE", thread
, type
, 0, kd
[i
].arg1
, kd
[i
].arg2
, 0, FMT_PGIN
, (double)now
);
2659 else if (kd
[i
].arg4
== DBG_PAGEIND_FAULT
)
2660 exit_event("PAGE_IN_ANON", thread
, type
, 0, kd
[i
].arg1
, kd
[i
].arg2
, 0, FMT_PGIN
, (double)now
);
2661 else if (kd
[i
].arg4
== DBG_CACHE_HIT_FAULT
)
2662 exit_event("CACHE_HIT", thread
, type
, 0, kd
[i
].arg1
, kd
[i
].arg2
, 0, FMT_CACHEHIT
, (double)now
);
2664 if ((ti
= find_event(thread
, type
)))
2670 exit_event("map_fd", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, FMT_FD
, (double)now
);
2673 case BSC_mmap_extended
:
2674 case BSC_mmap_extended2
:
2675 case BSC_msync_extended
:
2676 case BSC_pread_extended
:
2677 case BSC_pwrite_extended
:
2678 extend_syscall(thread
, type
, &kd
[i
]);
2682 if ((type
& CSC_MASK
) == BSC_BASE
) {
2684 if ((index
= BSC_INDEX(type
)) >= MAX_BSD_SYSCALL
)
2687 if (bsd_syscalls
[index
].sc_name
) {
2688 exit_event(bsd_syscalls
[index
].sc_name
, thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, kd
[i
].arg3
, kd
[i
].arg4
,
2689 bsd_syscalls
[index
].sc_format
, (double)now
);
2691 if (type
== BSC_exit
)
2692 delete_map_entry(thread
);
2694 } else if ((type
& CLASS_MASK
) == FILEMGR_BASE
) {
2696 if ((index
= filemgr_index(type
)) >= MAX_FILEMGR
)
2699 if (filemgr_calls
[index
].fm_name
) {
2700 exit_event(filemgr_calls
[index
].fm_name
, thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, kd
[i
].arg3
, kd
[i
].arg4
,
2701 FMT_DEFAULT
, (double)now
);
2710 enter_event_now(uintptr_t thread
, int type
, kd_buf
*kd
, char *name
, double now
)
2724 if ((ti
= add_event(thread
, type
)) == NULL
)
2728 ti
->arg1
= kd
->arg1
;
2729 ti
->arg2
= kd
->arg2
;
2730 ti
->arg3
= kd
->arg3
;
2731 ti
->arg4
= kd
->arg4
;
2733 if ((type
& CLASS_MASK
) == FILEMGR_BASE
&&
2734 (!RAW_flag
|| (now
>= start_time
&& now
<= end_time
))) {
2736 filemgr_in_progress
++;
2740 l_usecs
= (long long)((now
- bias_now
) / divisor
);
2741 l_usecs
+= (sample_TOD_secs
* 1000000) + sample_TOD_usecs
;
2743 l_usecs
= (long long)(now
/ divisor
);
2744 secs
= l_usecs
/ 1000000;
2745 curr_time
= bias_secs
+ secs
;
2747 sprintf(buf
, "%-8.8s", &(ctime(&curr_time
)[11]));
2748 tsclen
= strlen(buf
);
2750 if (columns
> MAXCOLS
|| wideflag
) {
2751 usecs
= l_usecs
- (long long)((long long)secs
* 1000000);
2752 sprintf(&buf
[tsclen
], ".%06ld", (long)usecs
);
2753 tsclen
= strlen(buf
);
2757 * Print timestamp column
2761 tme
= find_map_entry(thread
);
2763 sprintf(buf
, " %-25.25s ", name
);
2764 nmclen
= strlen(buf
);
2767 sprintf(buf
, "(%d, 0x%lx, 0x%lx, 0x%lx)", (short)kd
->arg1
, kd
->arg2
, kd
->arg3
, kd
->arg4
);
2768 argsclen
= strlen(buf
);
2771 * Calculate white space out to command
2773 if (columns
> MAXCOLS
|| wideflag
) {
2774 clen
= columns
- (tsclen
+ nmclen
+ argsclen
+ 20 + 11);
2776 clen
= columns
- (tsclen
+ nmclen
+ argsclen
+ 12);
2779 printf("%s", buf
); /* print the kdargs */
2780 memset(buf
, ' ', clen
);
2784 else if ((argsclen
+ clen
) > 0) {
2786 * no room so wipe out the kdargs
2788 memset(buf
, ' ', (argsclen
+ clen
));
2789 buf
[argsclen
+ clen
] = '\0';
2792 if (columns
> MAXCOLS
|| wideflag
)
2793 printf("%s.%d\n", tme
->tm_command
, (int)thread
);
2795 printf("%-12.12s\n", tme
->tm_command
);
2797 printf(" %-24.24s (%5d, %#lx, 0x%lx, 0x%lx)\n", name
, (short)kd
->arg1
, kd
->arg2
, kd
->arg3
, kd
->arg4
);
2803 enter_event(uintptr_t thread
, int type
, kd_buf
*kd
, char *name
, double now
)
2807 if (type
== MACH_pageout
|| type
== MACH_vmfault
|| type
== MSC_map_fd
|| type
== SPEC_ioctl
|| type
== Throttled
|| type
== P_CS_SYNC_DISK
) {
2808 enter_event_now(thread
, type
, kd
, name
, now
);
2811 if ((type
& CSC_MASK
) == BSC_BASE
) {
2813 if ((index
= BSC_INDEX(type
)) >= MAX_BSD_SYSCALL
)
2816 if (bsd_syscalls
[index
].sc_name
)
2817 enter_event_now(thread
, type
, kd
, name
, now
);
2820 if ((type
& CLASS_MASK
) == FILEMGR_BASE
) {
2822 if ((index
= filemgr_index(type
)) >= MAX_FILEMGR
)
2825 if (filemgr_calls
[index
].fm_name
)
2826 enter_event_now(thread
, type
, kd
, name
, now
);
2831 * Handle system call extended trace data.
2833 * Wipe out the kd args that were collected upon syscall_entry
2834 * because it is the extended info that we really want, and it
2835 * is all we really need.
2839 extend_syscall(uintptr_t thread
, int type
, kd_buf
*kd
)
2844 case BSC_mmap_extended
:
2845 if ((ti
= find_event(thread
, BSC_mmap
)) == (struct th_info
*)0)
2847 ti
->arg8
= ti
->arg3
; /* save protection */
2848 ti
->arg1
= kd
->arg1
; /* the fd */
2849 ti
->arg3
= kd
->arg2
; /* bottom half address */
2850 ti
->arg5
= kd
->arg3
; /* bottom half size */
2852 case BSC_mmap_extended2
:
2853 if ((ti
= find_event(thread
, BSC_mmap
)) == (struct th_info
*)0)
2855 ti
->arg2
= kd
->arg1
; /* top half address */
2856 ti
->arg4
= kd
->arg2
; /* top half size */
2857 ti
->arg6
= kd
->arg3
; /* top half file offset */
2858 ti
->arg7
= kd
->arg4
; /* bottom half file offset */
2860 case BSC_msync_extended
:
2861 if ((ti
= find_event(thread
, BSC_msync
)) == (struct th_info
*)0) {
2862 if ((ti
= find_event(thread
, BSC_msync_nocancel
)) == (struct th_info
*)0)
2865 ti
->arg4
= kd
->arg1
; /* top half address */
2866 ti
->arg5
= kd
->arg2
; /* top half size */
2868 case BSC_pread_extended
:
2869 if ((ti
= find_event(thread
, BSC_pread
)) == (struct th_info
*)0) {
2870 if ((ti
= find_event(thread
, BSC_pread_nocancel
)) == (struct th_info
*)0)
2873 ti
->arg1
= kd
->arg1
; /* the fd */
2874 ti
->arg2
= kd
->arg2
; /* nbytes */
2875 ti
->arg3
= kd
->arg3
; /* top half offset */
2876 ti
->arg4
= kd
->arg4
; /* bottom half offset */
2878 case BSC_pwrite_extended
:
2879 if ((ti
= find_event(thread
, BSC_pwrite
)) == (struct th_info
*)0) {
2880 if ((ti
= find_event(thread
, BSC_pwrite_nocancel
)) == (struct th_info
*)0)
2883 ti
->arg1
= kd
->arg1
; /* the fd */
2884 ti
->arg2
= kd
->arg2
; /* nbytes */
2885 ti
->arg3
= kd
->arg3
; /* top half offset */
2886 ti
->arg4
= kd
->arg4
; /* bottom half offset */
2895 exit_event(char *sc_name
, uintptr_t thread
, int type
, int arg1
, int arg2
, int arg3
, int arg4
,
2896 int format
, double now
)
2900 if ((ti
= find_event(thread
, type
)) == (struct th_info
*)0)
2903 if (check_filter_mode(ti
, type
, arg1
, arg2
, sc_name
))
2904 format_print(ti
, sc_name
, thread
, type
, arg1
, arg2
, arg3
, arg4
, format
, now
, ti
->stime
, ti
->waited
, (char *)ti
->pathname
, NULL
);
2906 if ((type
& CLASS_MASK
) == FILEMGR_BASE
) {
2909 if (filemgr_in_progress
> 0)
2910 filemgr_in_progress
--;
2917 get_mode_nibble(char * buf
, int smode
, int special
, char x_on
, char x_off
)
2936 get_mode_string(int mode
, char *buf
)
2938 memset(buf
, '-', 9);
2941 get_mode_nibble(&buf
[6], mode
, (mode
& 01000), 't', 'T');
2942 get_mode_nibble(&buf
[3], (mode
>>3), (mode
& 02000), 's', 'S');
2943 get_mode_nibble(&buf
[0], (mode
>>6), (mode
& 04000), 's', 'S');
2947 int clip_64bit(char *s
, uint64_t value
)
2951 if ( (value
& 0xff00000000000000LL
) )
2952 clen
= printf("%s0x%16.16qx", s
, value
);
2953 else if ( (value
& 0x00ff000000000000LL
) )
2954 clen
= printf("%s0x%14.14qx ", s
, value
);
2955 else if ( (value
& 0x0000ff0000000000LL
) )
2956 clen
= printf("%s0x%12.12qx ", s
, value
);
2957 else if ( (value
& 0x000000ff00000000LL
) )
2958 clen
= printf("%s0x%10.10qx ", s
, value
);
2960 clen
= printf("%s0x%8.8qx ", s
, value
);
2967 format_print(struct th_info
*ti
, char *sc_name
, uintptr_t thread
, int type
, int arg1
, int arg2
, int arg3
, int arg4
,
2968 int format
, double now
, double stime
, int waited
, char *pathname
, struct diskio
*dio
)
2983 char *framework_name
;
2984 char *framework_type
;
2988 char cs_diskname
[32];
2990 static char timestamp
[32];
2991 static int last_timestamp
= -1;
2992 static int timestamp_len
= 0;
2995 l_usecs
= (long long)((now
- bias_now
) / divisor
);
2997 if ((double)l_usecs
< start_time
|| (double)l_usecs
> end_time
)
3000 l_usecs
+= (sample_TOD_secs
* 1000000) + sample_TOD_usecs
;
3003 l_usecs
= (long long)(now
/ divisor
);
3004 secs
= l_usecs
/ 1000000;
3005 curr_time
= bias_secs
+ secs
;
3010 command_name
= dio
->issuing_command
;
3014 if ((tme
= find_map_entry(thread
)))
3015 command_name
= tme
->tm_command
;
3017 if (last_timestamp
!= curr_time
) {
3018 timestamp_len
= sprintf(timestamp
, "%-8.8s", &(ctime(&curr_time
)[11]));
3019 last_timestamp
= curr_time
;
3021 if (columns
> MAXCOLS
|| wideflag
) {
3024 tlen
= timestamp_len
;
3026 usec
= (l_usecs
- (long long)((long long)secs
* 1000000));
3028 sprintf(×tamp
[tlen
], ".%06ld", (long)usec
);
3031 timestamp
[tlen
] = '\0';
3033 if (filemgr_in_progress
) {
3034 if (class != FILEMGR_CLASS
) {
3035 if (find_event(thread
, -1))
3042 if ((class == FILEMGR_CLASS
) && (columns
> MAXCOLS
|| wideflag
))
3043 clen
= printf("%s %-20.20s", timestamp
, sc_name
);
3044 else if (in_filemgr
)
3045 clen
= printf("%s %-15.15s", timestamp
, sc_name
);
3047 clen
= printf("%s %-17.17s", timestamp
, sc_name
);
3050 framework_name
= NULL
;
3052 if (columns
> MAXCOLS
|| wideflag
) {
3054 off_t offset_reassembled
= 0LL;
3060 * pathname based system calls or
3061 * calls with no fd or pathname (i.e. sync)
3064 clen
+= printf(" [%3d] ", arg1
);
3066 clen
+= printf(" ");
3071 * fd based system call... no I/O
3074 clen
+= printf(" F=%-3d[%3d]", ti
->arg1
, arg1
);
3076 clen
+= printf(" F=%-3d", ti
->arg1
);
3084 clen
+= printf(" F=%-3d[%3d]", ti
->arg1
, arg1
);
3086 clen
+= printf(" F=%-3d F=%-3d", ti
->arg1
, arg2
);
3091 * system calls with fd's that return an I/O completion count
3094 clen
+= printf(" F=%-3d[%3d]", ti
->arg1
, arg1
);
3096 clen
+= printf(" F=%-3d B=0x%-6x", ti
->arg1
, arg2
);
3103 user_addr
= ((uint64_t)arg2
<< 32) | (uint32_t)arg3
;
3105 lookup_name(user_addr
, &framework_type
, &framework_name
);
3106 clen
+= clip_64bit(" A=", user_addr
);
3113 user_addr
= ((uint64_t)arg2
<< 32) | (uint32_t)arg3
;
3115 lookup_name(user_addr
, &framework_type
, &framework_name
);
3116 clen
+= clip_64bit(" A=", user_addr
);
3123 clen
+= printf(" B=0x%-8x", arg2
);
3131 clen
+= printf(" D=0x%8.8x [%3d]", dio
->blkno
, dio
->io_errno
);
3133 clen
+= printf(" D=0x%8.8x B=0x%-10x /dev/%s", dio
->blkno
, dio
->iosize
, find_disk_name(dio
->dev
));
3141 clen
+= printf(" D=0x%8.8x [%3d]", dio
->blkno
, dio
->io_errno
);
3143 clen
+= printf(" D=0x%8.8x B=0x%-10x /dev/%s", dio
->blkno
, dio
->iosize
, generate_cs_disk_name(dio
->dev
, &cs_diskname
[0]));
3146 case FMT_SYNC_DISK_CS
:
3148 * physical disk sync cache
3150 clen
+= printf(" /dev/%s", generate_cs_disk_name(arg1
, &cs_diskname
[0]));
3163 if (ti
->arg3
& MS_ASYNC
)
3164 mlen
+= sprintf(&buf
[mlen
], "MS_ASYNC | ");
3166 mlen
+= sprintf(&buf
[mlen
], "MS_SYNC | ");
3168 if (ti
->arg3
& MS_INVALIDATE
)
3169 mlen
+= sprintf(&buf
[mlen
], "MS_INVALIDATE | ");
3170 if (ti
->arg3
& MS_KILLPAGES
)
3171 mlen
+= sprintf(&buf
[mlen
], "MS_KILLPAGES | ");
3172 if (ti
->arg3
& MS_DEACTIVATE
)
3173 mlen
+= sprintf(&buf
[mlen
], "MS_DEACTIVATE | ");
3175 if (ti
->arg3
& ~(MS_ASYNC
| MS_SYNC
| MS_INVALIDATE
| MS_KILLPAGES
| MS_DEACTIVATE
))
3176 mlen
+= sprintf(&buf
[mlen
], "UNKNOWN | ");
3179 buf
[mlen
- 3] = '\0';
3182 clen
+= printf(" [%3d]", arg1
);
3184 user_addr
= (((off_t
)(unsigned int)(ti
->arg4
)) << 32) | (unsigned int)(ti
->arg1
);
3185 clen
+= clip_64bit(" A=", user_addr
);
3187 user_size
= (((off_t
)(unsigned int)(ti
->arg5
)) << 32) | (unsigned int)(ti
->arg2
);
3189 clen
+= printf(" B=0x%-16qx <%s>", user_size
, buf
);
3203 clen
+= printf(" F=%-3d[%3d]", ti
->arg1
, arg1
);
3205 clen
+= printf(" F=%-3d", ti
->arg1
);
3269 case F_PATHPKG_CHECK
:
3270 p
= "PATHPKG_CHECK";
3284 case F_CHECK_OPENEVT
:
3285 p
= "CHECK_OPENEVT";
3295 case F_GLOBAL_NOCACHE
:
3297 p
= "CACHING OFF (GLOBAL)";
3299 p
= "CACHING ON (GLOBAL)";
3305 clen
+= printf(" <%s>", p
);
3307 clen
+= printf(" <%s> F=%d", p
, fd
);
3309 clen
+= printf(" <CMD=%d>", ti
->arg2
);
3320 clen
+= printf(" F=%-3d[%3d]", ti
->arg1
, arg1
);
3322 clen
+= printf(" F=%-3d", ti
->arg1
);
3324 clen
+= printf(" <CMD=0x%x>", ti
->arg2
);
3329 case FMT_IOCTL_SYNC
:
3334 clen
+= printf(" <DKIOCSYNCHRONIZECACHE> /dev/%s", find_disk_name(arg1
));
3339 case FMT_IOCTL_UNMAP
:
3344 clen
+= printf(" <DKIOCUNMAP> /dev/%s", find_disk_name(arg1
));
3349 case FMT_UNMAP_INFO
:
3351 clen
+= printf(" D=0x%8.8x B=0x%-10x /dev/%s", arg2
, arg3
, find_disk_name(arg1
));
3361 clen
+= printf(" [%3d]", arg1
);
3363 clen
+= printf(" S=%-3d", arg2
);
3370 * pread, pwrite, lseek
3372 clen
+= printf(" F=%-3d", ti
->arg1
);
3375 clen
+= printf("[%3d] ", arg1
);
3377 if (format
== FMT_PREAD
)
3378 clen
+= printf(" B=0x%-8x ", arg2
);
3380 clen
+= printf(" ");
3382 if (format
== FMT_PREAD
)
3383 offset_reassembled
= (((off_t
)(unsigned int)(ti
->arg3
)) << 32) | (unsigned int)(ti
->arg4
);
3386 offset_reassembled
= (((off_t
)(unsigned int)(arg2
)) << 32) | (unsigned int)(arg3
);
3388 offset_reassembled
= (((off_t
)(unsigned int)(arg3
)) << 32) | (unsigned int)(arg2
);
3390 clen
+= clip_64bit("O=", offset_reassembled
);
3392 if (format
== FMT_LSEEK
) {
3395 if (ti
->arg4
== SEEK_SET
)
3397 else if (ti
->arg4
== SEEK_CUR
)
3399 else if (ti
->arg4
== SEEK_END
)
3404 clen
+= printf(" <%s>", mode
);
3412 clen
+= printf(" F=%-3d ", ti
->arg1
);
3415 clen
+= printf("[%3d] ", arg1
);
3418 user_addr
= (((off_t
)(unsigned int)(ti
->arg2
)) << 32) | (unsigned int)(ti
->arg3
);
3420 clen
+= clip_64bit("A=", user_addr
);
3422 offset_reassembled
= (((off_t
)(unsigned int)(ti
->arg6
)) << 32) | (unsigned int)(ti
->arg7
);
3424 clen
+= clip_64bit("O=", offset_reassembled
);
3426 user_size
= (((off_t
)(unsigned int)(ti
->arg4
)) << 32) | (unsigned int)(ti
->arg5
);
3428 clen
+= printf("B=0x%-16qx", user_size
);
3430 clen
+= printf(" <");
3432 if (ti
->arg8
& PROT_READ
)
3433 clen
+= printf("READ");
3435 if (ti
->arg8
& PROT_WRITE
)
3436 clen
+= printf("|WRITE");
3438 if (ti
->arg8
& PROT_EXEC
)
3439 clen
+= printf("|EXEC");
3441 clen
+= printf(">");
3448 * ftruncate, truncate
3450 if (format
== FMT_FTRUNC
)
3451 clen
+= printf(" F=%-3d", ti
->arg1
);
3453 clen
+= printf(" ");
3456 clen
+= printf("[%3d]", arg1
);
3459 offset_reassembled
= (((off_t
)(unsigned int)(ti
->arg2
)) << 32) | (unsigned int)(ti
->arg3
);
3461 offset_reassembled
= (((off_t
)(unsigned int)(ti
->arg3
)) << 32) | (unsigned int)(ti
->arg2
);
3463 clen
+= clip_64bit(" O=", offset_reassembled
);
3476 if (format
== FMT_FCHFLAGS
) {
3478 clen
+= printf(" F=%-3d[%3d]", ti
->arg1
, arg1
);
3480 clen
+= printf(" F=%-3d", ti
->arg1
);
3483 clen
+= printf(" [%3d] ", arg1
);
3488 if (ti
->arg2
& UF_NODUMP
)
3489 mlen
+= sprintf(&buf
[mlen
], "UF_NODUMP | ");
3490 if (ti
->arg2
& UF_IMMUTABLE
)
3491 mlen
+= sprintf(&buf
[mlen
], "UF_IMMUTABLE | ");
3492 if (ti
->arg2
& UF_APPEND
)
3493 mlen
+= sprintf(&buf
[mlen
], "UF_APPEND | ");
3494 if (ti
->arg2
& UF_OPAQUE
)
3495 mlen
+= sprintf(&buf
[mlen
], "UF_OPAQUE | ");
3496 if (ti
->arg2
& SF_ARCHIVED
)
3497 mlen
+= sprintf(&buf
[mlen
], "SF_ARCHIVED | ");
3498 if (ti
->arg2
& SF_IMMUTABLE
)
3499 mlen
+= sprintf(&buf
[mlen
], "SF_IMMUTABLE | ");
3500 if (ti
->arg2
& SF_APPEND
)
3501 mlen
+= sprintf(&buf
[mlen
], "SF_APPEND | ");
3504 mlen
+= sprintf(&buf
[mlen
], "CLEAR_ALL_FLAGS | ");
3505 else if (ti
->arg2
& ~(UF_NODUMP
| UF_IMMUTABLE
| UF_APPEND
| SF_ARCHIVED
| SF_IMMUTABLE
| SF_APPEND
))
3506 mlen
+= sprintf(&buf
[mlen
], "UNKNOWN | ");
3515 memset(&buf
[mlen
], ' ', 19 - mlen
);
3518 clen
+= printf("%s", buf
);
3526 case FMT_FCHMOD_EXT
:
3531 * fchmod, fchmod_extended, chmod, chmod_extended
3535 if (format
== FMT_FCHMOD
|| format
== FMT_FCHMOD_EXT
) {
3537 clen
+= printf(" F=%-3d[%3d] ", ti
->arg1
, arg1
);
3539 clen
+= printf(" F=%-3d ", ti
->arg1
);
3542 clen
+= printf(" [%3d] ", arg1
);
3544 clen
+= printf(" ");
3546 if (format
== FMT_UMASK
)
3548 else if (format
== FMT_FCHMOD
|| format
== FMT_CHMOD
)
3553 get_mode_string(mode
, &buf
[0]);
3556 clen
+= printf("<%s> ", buf
);
3558 clen
+= printf("<%s>", buf
);
3569 memset(mode
, '_', 4);
3572 if (ti
->arg2
& R_OK
)
3574 if (ti
->arg2
& W_OK
)
3576 if (ti
->arg2
& X_OK
)
3578 if (ti
->arg2
== F_OK
)
3582 clen
+= printf(" [%3d] (%s) ", arg1
, mode
);
3584 clen
+= printf(" (%s) ", mode
);
3593 clen
+= printf(" [%3d] <FLGS=0x%x> ", arg1
, ti
->arg3
);
3595 clen
+= printf(" <FLGS=0x%x> ", ti
->arg3
);
3605 if (ti
->arg2
& MNT_FORCE
)
3606 mountflag
= "<FORCE>";
3611 clen
+= printf(" [%3d] %s ", arg1
, mountflag
);
3613 clen
+= printf(" %s ", mountflag
);
3626 memset(mode
, '_', 6);
3629 if (ti
->arg2
& O_RDWR
) {
3632 } else if (ti
->arg2
& O_WRONLY
)
3637 if (ti
->arg2
& O_CREAT
)
3640 if (ti
->arg2
& O_APPEND
)
3643 if (ti
->arg2
& O_TRUNC
)
3646 if (ti
->arg2
& O_EXCL
)
3650 clen
+= printf(" [%3d] (%s) ", arg1
, mode
);
3652 clen
+= printf(" F=%-3d (%s) ", arg2
, mode
);
3686 domain
= "AF_IMPLINK";
3697 type
= "SOCK_STREAM";
3701 type
= "SOCK_DGRAM";
3708 case SOCK_SEQPACKET
:
3709 type
= "SOCK_SEQPACKET";
3722 clen
+= printf(" [%3d] <%s, %s, 0x%x>", arg1
, domain
, type
, ti
->arg3
);
3724 clen
+= printf(" F=%-3d <%s, %s, 0x%x>", arg2
, domain
, type
, ti
->arg3
);
3731 * aio_fsync [errno] AIOCBP OP
3735 if (ti
->arg1
== O_SYNC
|| ti
->arg1
== 0)
3738 else if (ti
->arg1
== O_DSYNC
)
3745 clen
+= printf(" [%3d] P=0x%8.8x <%s>", arg1
, ti
->arg2
, op
);
3747 clen
+= printf(" P=0x%8.8x <%s>", ti
->arg2
, op
);
3751 case FMT_AIO_RETURN
:
3753 * aio_return [errno] AIOCBP IOSIZE
3756 clen
+= printf(" [%3d] P=0x%8.8x", arg1
, ti
->arg1
);
3758 clen
+= printf(" P=0x%8.8x B=0x%-8x", ti
->arg1
, arg2
);
3761 case FMT_AIO_SUSPEND
:
3763 * aio_suspend [errno] NENTS
3766 clen
+= printf(" [%3d] N=%d", arg1
, ti
->arg2
);
3768 clen
+= printf(" N=%d", ti
->arg2
);
3771 case FMT_AIO_CANCEL
:
3773 * aio_cancel [errno] FD or AIOCBP (if non-null)
3777 clen
+= printf(" [%3d] P=0x%8.8x", arg1
, ti
->arg2
);
3779 clen
+= printf(" P=0x%8.8x", ti
->arg2
);
3782 clen
+= printf(" F=%-3d[%3d]", ti
->arg1
, arg1
);
3784 clen
+= printf(" F=%-3d", ti
->arg1
);
3790 * aio_error, aio_read, aio_write [errno] AIOCBP
3793 clen
+= printf(" [%3d] P=0x%8.8x", arg1
, ti
->arg1
);
3795 clen
+= printf(" P=0x%8.8x", ti
->arg1
);
3798 case FMT_LIO_LISTIO
:
3801 * lio_listio [errno] NENTS MODE
3805 if (ti
->arg1
== LIO_NOWAIT
)
3807 else if (ti
->arg1
== LIO_WAIT
)
3813 clen
+= printf(" [%3d] N=%d <%s>", arg1
, ti
->arg3
, op
);
3815 clen
+= printf(" N=%d <%s>", ti
->arg3
, op
);
3823 * Calculate space available to print pathname
3825 if (columns
> MAXCOLS
|| wideflag
)
3826 clen
= columns
- (clen
+ 14 + 20 + 11);
3828 clen
= columns
- (clen
+ 14 + 12);
3830 if (class != FILEMGR_CLASS
&& !nopadding
)
3834 len
= sprintf(&buf
[0], " %s %s ", framework_type
, framework_name
);
3835 else if (*pathname
!= '\0') {
3836 len
= sprintf(&buf
[0], " %s ", pathname
);
3838 if (format
== FMT_MOUNT
&& ti
->pathname2
[0]) {
3841 memset(&buf
[len
], ' ', 2);
3843 len2
= sprintf(&buf
[len
+2], " %s ", (char *)ti
->pathname2
);
3844 len
= len
+ 2 + len2
;
3851 * Add null padding if column length
3852 * is wider than the pathname length.
3854 memset(&buf
[len
], ' ', clen
- len
);
3859 } else if (clen
== len
) {
3862 } else if ((clen
> 0) && (clen
< len
)) {
3864 * This prints the tail end of the pathname
3866 buf
[len
-clen
] = ' ';
3868 pathname
= &buf
[len
- clen
];
3875 * fudge some additional system call overhead
3876 * that currently isn't tracked... this also
3877 * insures that we see a minimum of 1 us for
3880 usecs
= (unsigned long)(((now
- stime
) + (divisor
-1)) / divisor
);
3881 secs
= usecs
/ 1000000;
3882 usecs
-= secs
* 1000000;
3884 if (class != FILEMGR_CLASS
&& !nopadding
)
3894 if (columns
> MAXCOLS
|| wideflag
)
3895 printf("%s%s %3ld.%06ld%s %s.%d\n", p1
, pathname
, (unsigned long)secs
, (unsigned long)usecs
, p2
, command_name
, (int)thread
);
3897 printf("%s%s %3ld.%06ld%s %-12.12s\n", p1
, pathname
, (unsigned long)secs
, (unsigned long)usecs
, p2
, command_name
);
3902 delete_event(th_info_t ti_to_delete
) {
3907 hashid
= ti_to_delete
->thread
& HASH_MASK
;
3909 if ((ti
= th_info_hash
[hashid
])) {
3910 if (ti
== ti_to_delete
)
3911 th_info_hash
[hashid
] = ti
->next
;
3915 for (ti
= ti
->next
; ti
; ti
= ti
->next
) {
3916 if (ti
== ti_to_delete
) {
3917 ti_prev
->next
= ti
->next
;
3924 ti
->next
= th_info_freelist
;
3925 th_info_freelist
= ti
;
3931 add_event(uintptr_t thread
, int type
) {
3935 if ((ti
= th_info_freelist
))
3936 th_info_freelist
= ti
->next
;
3938 ti
= (th_info_t
)malloc(sizeof(struct th_info
));
3940 hashid
= thread
& HASH_MASK
;
3942 ti
->next
= th_info_hash
[hashid
];
3943 th_info_hash
[hashid
] = ti
;
3945 ti
->thread
= thread
;
3950 ti
->pathptr
= ti
->pathname
;
3951 ti
->pathname
[0] = 0;
3952 ti
->pathname2
[0] = 0;
3958 find_event(uintptr_t thread
, int type
) {
3962 hashid
= thread
& HASH_MASK
;
3964 for (ti
= th_info_hash
[hashid
]; ti
; ti
= ti
->next
) {
3965 if (ti
->thread
== thread
) {
3966 if (type
== ti
->type
)
3968 if (ti
->in_filemgr
) {
3977 return ((th_info_t
) 0);
3981 delete_all_events() {
3983 th_info_t ti_next
= 0;
3986 for (i
= 0; i
< HASH_SIZE
; i
++) {
3988 for (ti
= th_info_hash
[i
]; ti
; ti
= ti_next
) {
3990 ti
->next
= th_info_freelist
;
3991 th_info_freelist
= ti
;
3993 th_info_hash
[i
] = 0;
3999 mark_thread_waited(uintptr_t thread
) {
4003 hashid
= thread
& HASH_MASK
;
4005 for (ti
= th_info_hash
[hashid
]; ti
; ti
= ti
->next
) {
4006 if (ti
->thread
== thread
)
4012 void read_command_map()
4016 int total_threads
= 0;
4017 kd_threadmap
*mapptr
= 0;
4019 delete_all_map_entries();
4023 total_threads
= bufinfo
.nkdthreads
;
4024 size
= bufinfo
.nkdthreads
* sizeof(kd_threadmap
);
4027 if ((mapptr
= (kd_threadmap
*) malloc(size
))) {
4030 bzero (mapptr
, size
);
4032 * Now read the threadmap
4035 mib
[1] = KERN_KDEBUG
;
4036 mib
[2] = KERN_KDTHRMAP
;
4039 mib
[5] = 0; /* no flags */
4041 if (sysctl(mib
, 3, mapptr
, &size
, NULL
, 0) < 0) {
4043 * This is not fatal -- just means I cant map command strings
4054 RAW_fd
= open(RAW_file
, O_RDONLY
);
4057 perror("Can't open RAW file");
4060 if (read(RAW_fd
, &header
, sizeof(RAW_header
)) != sizeof(RAW_header
)) {
4061 perror("read failed");
4064 if (header
.version_no
!= RAW_VERSION1
) {
4065 header
.version_no
= RAW_VERSION0
;
4066 header
.TOD_secs
= time((long *)0);
4067 header
.TOD_usecs
= 0;
4069 lseek(RAW_fd
, (off_t
)0, SEEK_SET
);
4071 if (read(RAW_fd
, &header
.thread_count
, sizeof(int)) != sizeof(int)) {
4072 perror("read failed");
4076 sample_TOD_secs
= header
.TOD_secs
;
4077 sample_TOD_usecs
= header
.TOD_usecs
;
4079 total_threads
= header
.thread_count
;
4080 size
= total_threads
* sizeof(kd_threadmap
);
4083 if ((mapptr
= (kd_threadmap
*) malloc(size
))) {
4084 bzero (mapptr
, size
);
4086 if (read(RAW_fd
, mapptr
, size
) != size
) {
4092 if (header
.version_no
!= RAW_VERSION0
) {
4093 offset
= lseek(RAW_fd
, (off_t
)0, SEEK_CUR
);
4094 offset
= (offset
+ (4095)) & ~4095;
4096 lseek(RAW_fd
, offset
, SEEK_SET
);
4099 for (i
= 0; i
< total_threads
; i
++)
4100 create_map_entry(mapptr
[i
].thread
, mapptr
[i
].valid
, &mapptr
[i
].command
[0]);
4106 void delete_all_map_entries()
4108 threadmap_t tme
= 0;
4109 threadmap_t tme_next
= 0;
4112 for (i
= 0; i
< HASH_SIZE
; i
++) {
4114 for (tme
= threadmap_hash
[i
]; tme
; tme
= tme_next
) {
4116 free(tme
->tm_setptr
);
4117 tme_next
= tme
->tm_next
;
4118 tme
->tm_next
= threadmap_freelist
;
4119 threadmap_freelist
= tme
;
4121 threadmap_hash
[i
] = 0;
4126 void create_map_entry(uintptr_t thread
, int pid
, char *command
)
4131 if ((tme
= threadmap_freelist
))
4132 threadmap_freelist
= tme
->tm_next
;
4134 tme
= (threadmap_t
)malloc(sizeof(struct threadmap
));
4136 tme
->tm_thread
= thread
;
4137 tme
->tm_setsize
= 0;
4140 (void)strncpy (tme
->tm_command
, command
, MAXCOMLEN
);
4141 tme
->tm_command
[MAXCOMLEN
] = '\0';
4143 hashid
= thread
& HASH_MASK
;
4145 tme
->tm_next
= threadmap_hash
[hashid
];
4146 threadmap_hash
[hashid
] = tme
;
4148 if (pid
!= 0 && pid
!= 1) {
4149 if (!strncmp(command
, "LaunchCFMA", 10))
4150 (void)get_real_command_name(pid
, tme
->tm_command
, MAXCOMLEN
);
4156 find_map_entry(uintptr_t thread
)
4161 hashid
= thread
& HASH_MASK
;
4163 for (tme
= threadmap_hash
[hashid
]; tme
; tme
= tme
->tm_next
) {
4164 if (tme
->tm_thread
== thread
)
4172 delete_map_entry(uintptr_t thread
)
4174 threadmap_t tme
= 0;
4175 threadmap_t tme_prev
;
4178 hashid
= thread
& HASH_MASK
;
4180 if ((tme
= threadmap_hash
[hashid
])) {
4181 if (tme
->tm_thread
== thread
)
4182 threadmap_hash
[hashid
] = tme
->tm_next
;
4186 for (tme
= tme
->tm_next
; tme
; tme
= tme
->tm_next
) {
4187 if (tme
->tm_thread
== thread
) {
4188 tme_prev
->tm_next
= tme
->tm_next
;
4196 free(tme
->tm_setptr
);
4198 tme
->tm_next
= threadmap_freelist
;
4199 threadmap_freelist
= tme
;
4206 fs_usage_fd_set(uintptr_t thread
, unsigned int fd
)
4210 if ((tme
= find_map_entry(thread
)) == 0)
4213 * If the map is not allocated, then now is the time
4215 if (tme
->tm_setptr
== (unsigned long *)0) {
4216 if ((tme
->tm_setptr
= (unsigned long *)malloc(FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE
))) == 0)
4219 tme
->tm_setsize
= FS_USAGE_FD_SETSIZE
;
4220 bzero(tme
->tm_setptr
, (FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE
)));
4223 * If the map is not big enough, then reallocate it
4225 while (tme
->tm_setsize
<= fd
) {
4228 n
= tme
->tm_setsize
* 2;
4229 tme
->tm_setptr
= (unsigned long *)realloc(tme
->tm_setptr
, (FS_USAGE_NFDBYTES(n
)));
4231 bzero(&tme
->tm_setptr
[(tme
->tm_setsize
/FS_USAGE_NFDBITS
)], (FS_USAGE_NFDBYTES(tme
->tm_setsize
)));
4232 tme
->tm_setsize
= n
;
4237 tme
->tm_setptr
[fd
/FS_USAGE_NFDBITS
] |= (1 << ((fd
) % FS_USAGE_NFDBITS
));
4243 * 0 : File Descriptor bit is not set
4244 * 1 : File Descriptor bit is set
4247 fs_usage_fd_isset(uintptr_t thread
, unsigned int fd
)
4252 if ((tme
= find_map_entry(thread
))) {
4253 if (tme
->tm_setptr
&& fd
< tme
->tm_setsize
)
4254 ret
= tme
->tm_setptr
[fd
/FS_USAGE_NFDBITS
] & (1 << (fd
% FS_USAGE_NFDBITS
));
4261 fs_usage_fd_clear(uintptr_t thread
, unsigned int fd
)
4265 if ((tme
= find_map_entry(thread
))) {
4266 if (tme
->tm_setptr
&& fd
< tme
->tm_setsize
)
4267 tme
->tm_setptr
[fd
/FS_USAGE_NFDBITS
] &= ~(1 << (fd
% FS_USAGE_NFDBITS
));
4280 ret
= (int)strtol(str
, &cp
, 10);
4282 if (cp
== str
|| *cp
) {
4284 * Assume this is a command string and find matching pids
4289 for (i
= 0; i
< kp_nentries
&& num_of_pids
< (MAX_PIDS
- 1); i
++) {
4290 if (kp_buffer
[i
].kp_proc
.p_stat
== 0)
4293 if (!strncmp(str
, kp_buffer
[i
].kp_proc
.p_comm
,
4294 sizeof(kp_buffer
[i
].kp_proc
.p_comm
) -1))
4295 pids
[num_of_pids
++] = kp_buffer
[i
].kp_proc
.p_pid
;
4299 else if (num_of_pids
< (MAX_PIDS
- 1))
4300 pids
[num_of_pids
++] = ret
;
4306 lookup_name(uint64_t user_addr
, char **type
, char **name
)
4314 if (numFrameworks
) {
4316 if ((user_addr
>= framework32
.b_address
&& user_addr
< framework32
.e_address
) ||
4317 (user_addr
>= framework64
.b_address
&& user_addr
< framework64
.e_address
)) {
4320 last
= numFrameworks
;
4322 for (i
= numFrameworks
/ 2; start
< last
; i
= start
+ ((last
- start
) / 2)) {
4323 if (user_addr
> frameworkInfo
[i
].e_address
)
4328 if (start
< numFrameworks
&&
4329 user_addr
>= frameworkInfo
[start
].b_address
&& user_addr
< frameworkInfo
[start
].e_address
) {
4330 *type
= frameworkType
[frameworkInfo
[start
].r_type
];
4331 *name
= frameworkInfo
[start
].name
;
4339 * Comparison routines for sorting
4341 static int compareFrameworkAddress(const void *aa
, const void *bb
)
4343 LibraryInfo
*a
= (LibraryInfo
*)aa
;
4344 LibraryInfo
*b
= (LibraryInfo
*)bb
;
4346 if (a
->b_address
< b
->b_address
) return -1;
4347 if (a
->b_address
== b
->b_address
) return 0;
4352 int scanline(char *inputstring
, char **argv
, int maxtokens
)
4355 char **ap
= argv
, *p
, *val
;
4357 for (p
= inputstring
; n
< maxtokens
&& p
!= NULL
; ) {
4359 while ((val
= strsep(&p
, " \t")) != NULL
&& *val
== '\0');
4370 int ReadSharedCacheMap(const char *path
, LibraryRange
*lr
, char *linkedit_name
)
4372 uint64_t b_address
, e_address
;
4376 char frameworkName
[256];
4380 int linkedit_found
= 0;
4381 char *substring
, *ptr
;
4383 bzero(buf
, sizeof(buf
));
4384 bzero(tokens
, sizeof(tokens
));
4389 if ((fd
= fopen(path
, "r")) == 0)
4392 while (fgets(buf
, 1023, fd
)) {
4393 if (strncmp(buf
, "mapping", 7))
4396 buf
[strlen(buf
)-1] = 0;
4398 frameworkName
[0] = 0;
4402 * Extract lib name from path name
4404 if ((substring
= strrchr(buf
, '.')))
4407 * There is a ".": name is whatever is between the "/" around the "."
4409 while ( *substring
!= '/') /* find "/" before "." */
4413 strncpy(frameworkName
, substring
, 256); /* copy path from "/" */
4414 frameworkName
[255] = 0;
4415 substring
= frameworkName
;
4417 while ( *substring
!= '/' && *substring
) /* find "/" after "." and stop string there */
4424 * No ".": take segment after last "/"
4431 substring
= ptr
+ 1;
4434 strncpy(frameworkName
, substring
, 256);
4435 frameworkName
[255] = 0;
4437 fnp
= (char *)malloc(strlen(frameworkName
) + 1);
4438 strcpy(fnp
, frameworkName
);
4440 while (fgets(buf
, 1023, fd
) && numFrameworks
< (MAXINDEX
- 2)) {
4444 buf
[strlen(buf
)-1] = 0;
4446 ntokens
= scanline(buf
, tokens
, 64);
4451 if (strncmp(tokens
[0], "__TEXT", 6) == 0)
4453 else if (strncmp(tokens
[0], "__DATA", 6) == 0)
4455 else if (strncmp(tokens
[0], "__OBJC", 6) == 0)
4457 else if (strncmp(tokens
[0], "__IMPORT", 8) == 0)
4459 else if (strncmp(tokens
[0], "__UNICODE", 9) == 0)
4461 else if (strncmp(tokens
[0], "__IMAGE", 7) == 0)
4463 else if (strncmp(tokens
[0], "__LINKEDIT", 10) == 0)
4468 if (type
== LINKEDIT_R
&& linkedit_found
)
4472 b_address
= strtoull(tokens
[1], 0, 16);
4473 e_address
= strtoull(tokens
[3], 0, 16);
4475 frameworkInfo
[numFrameworks
].b_address
= b_address
;
4476 frameworkInfo
[numFrameworks
].e_address
= e_address
;
4477 frameworkInfo
[numFrameworks
].r_type
= type
;
4479 if (type
== LINKEDIT_R
) {
4480 frameworkInfo
[numFrameworks
].name
= linkedit_name
;
4483 frameworkInfo
[numFrameworks
].name
= fnp
;
4485 printf("%s(%d): %qx-%qx\n", frameworkInfo
[numFrameworks
].name
, type
, b_address
, e_address
);
4487 if (lr
->b_address
== 0 || b_address
< lr
->b_address
)
4488 lr
->b_address
= b_address
;
4490 if (lr
->e_address
== 0 || e_address
> lr
->e_address
)
4491 lr
->e_address
= e_address
;
4495 if (type
== LINKEDIT_R
)
4498 if (fgets(buf
, 1023, fd
) == 0)
4501 buf
[strlen(buf
)-1] = 0;
4506 printf("%s range, %qx-%qx\n", path
, lr
->b_address
, lr
->e_address
);
4513 SortFrameworkAddresses()
4516 frameworkInfo
[numFrameworks
].b_address
= frameworkInfo
[numFrameworks
- 1].b_address
+ 0x800000;
4517 frameworkInfo
[numFrameworks
].e_address
= frameworkInfo
[numFrameworks
].b_address
;
4518 frameworkInfo
[numFrameworks
].name
= (char *)0;
4520 qsort(frameworkInfo
, numFrameworks
, sizeof(LibraryInfo
), compareFrameworkAddress
);
4524 struct diskio
*insert_diskio(int type
, int bp
, int dev
, int blkno
, int io_size
, uintptr_t thread
, double curtime
)
4529 if ((dio
= free_diskios
))
4530 free_diskios
= dio
->next
;
4532 if ((dio
= (struct diskio
*)malloc(sizeof(struct diskio
))) == NULL
)
4541 dio
->iosize
= io_size
;
4542 dio
->issued_time
= curtime
;
4543 dio
->issuing_thread
= thread
;
4545 if ((tme
= find_map_entry(thread
))) {
4546 strncpy(dio
->issuing_command
, tme
->tm_command
, MAXCOMLEN
);
4547 dio
->issuing_command
[MAXCOMLEN
-1] = '\0';
4549 strcpy(dio
->issuing_command
, "");
4551 dio
->next
= busy_diskios
;
4553 dio
->next
->prev
= dio
;
4560 struct diskio
*complete_diskio(int bp
, int io_errno
, int resid
, uintptr_t thread
, double curtime
)
4564 for (dio
= busy_diskios
; dio
; dio
= dio
->next
) {
4566 if (dio
->bp
== bp
) {
4567 if (dio
== busy_diskios
) {
4568 if ((busy_diskios
= dio
->next
))
4569 dio
->next
->prev
= NULL
;
4572 dio
->next
->prev
= dio
->prev
;
4573 dio
->prev
->next
= dio
->next
;
4575 dio
->iosize
-= resid
;
4576 dio
->io_errno
= io_errno
;
4577 dio
->completed_time
= curtime
;
4578 dio
->completion_thread
= thread
;
4583 return ((struct diskio
*)0);
4587 void free_diskio(struct diskio
*dio
)
4589 dio
->next
= free_diskios
;
4594 void print_diskio(struct diskio
*dio
)
4599 int format
= FMT_DISKIO
;
4604 if ((type
& P_CS_Class
) == P_CS_Class
) {
4608 case P_CS_ReadChunk
:
4611 format
= FMT_DISKIO_CS
;
4613 case P_CS_WriteChunk
:
4616 format
= FMT_DISKIO_CS
;
4621 format
= FMT_DISKIO_CS
;
4623 case P_CS_MetaWrite
:
4626 format
= FMT_DISKIO_CS
;
4628 case P_CS_TransformRead
:
4632 case P_CS_TransformWrite
:
4636 case P_CS_MigrationRead
:
4640 case P_CS_MigrationWrite
:
4645 strncpy(buf
, p
, len
);
4648 switch (type
& P_DISKIO_TYPE
) {
4679 strncpy(buf
, p
, len
);
4683 if (type
& P_DISKIO_ASYNC
)
4688 if (type
& P_DISKIO_NOCACHE
)
4691 if (type
& P_DISKIO_THROTTLE
)
4693 else if (type
& P_DISKIO_PASSIVE
)
4700 if (check_filter_mode(NULL
, type
, 0, 0, buf
))
4701 format_print(NULL
, buf
, dio
->issuing_thread
, type
, 0, 0, 0, 0, format
, dio
->completed_time
, dio
->issued_time
, 1, "", dio
);
4705 void cache_disk_names()
4710 struct diskrec
*dnp
;
4713 if ((dirp
= opendir("/dev")) == NULL
)
4716 while ((dir
= readdir(dirp
)) != NULL
) {
4717 char nbuf
[MAXPATHLEN
];
4719 if (dir
->d_namlen
< 5 || strncmp("disk", dir
->d_name
, 4))
4722 snprintf(nbuf
, MAXPATHLEN
, "%s/%s", "/dev", dir
->d_name
);
4724 if (stat(nbuf
, &st
) < 0)
4727 if ((dnp
= (struct diskrec
*)malloc(sizeof(struct diskrec
))) == NULL
)
4730 if ((dnp
->diskname
= (char *)malloc(dir
->d_namlen
+ 1)) == NULL
) {
4734 strncpy(dnp
->diskname
, dir
->d_name
, dir
->d_namlen
);
4735 dnp
->diskname
[dir
->d_namlen
] = 0;
4736 dnp
->dev
= st
.st_rdev
;
4738 dnp
->next
= disk_list
;
4741 (void) closedir(dirp
);
4745 void recache_disk_names()
4747 struct diskrec
*dnp
, *next_dnp
;
4749 for (dnp
= disk_list
; dnp
; dnp
= next_dnp
) {
4750 next_dnp
= dnp
->next
;
4752 free(dnp
->diskname
);
4761 char *find_disk_name(int dev
)
4763 struct diskrec
*dnp
;
4772 for (i
= 0; i
< 2; i
++) {
4773 for (dnp
= disk_list
; dnp
; dnp
= dnp
->next
) {
4774 if (dnp
->dev
== dev
)
4775 return (dnp
->diskname
);
4777 recache_disk_names();
4779 return ("NOTFOUND");
4783 char *generate_cs_disk_name(int dev
, char *s
)
4788 sprintf(s
, "disk%ds%d", (dev
>> 16) & 0xffff, dev
& 0xffff);
4796 * ret = 1 means print the entry
4797 * ret = 0 means don't print the entry
4800 check_filter_mode(struct th_info
* ti
, int type
, int error
, int retval
, char *sc_name
)
4803 int network_fd_isset
= 0;
4806 if (filter_mode
== DEFAULT_DO_NOT_FILTER
)
4809 if (sc_name
[0] == 'C' && !strcmp (sc_name
, "CACHE_HIT")) {
4810 if (filter_mode
& CACHEHIT_FILTER
)
4811 /* Do not print if cachehit filter is set */
4816 if (filter_mode
& EXEC_FILTER
) {
4817 if (type
== BSC_execve
|| type
== BSC_posix_spawn
)
4822 if (filter_mode
& PATHNAME_FILTER
) {
4823 if (ti
&& ti
->pathname
[0])
4825 if (type
== BSC_close
|| type
== BSC_close_nocancel
)
4830 if ( !(filter_mode
& (FILESYS_FILTER
| NETWORK_FILTER
)))
4833 if (ti
== (struct th_info
*)0) {
4834 if (filter_mode
& FILESYS_FILTER
)
4842 case BSC_close_nocancel
:
4844 network_fd_isset
= fs_usage_fd_isset(ti
->thread
, fd
);
4847 fs_usage_fd_clear(ti
->thread
,fd
);
4849 if (network_fd_isset
) {
4850 if (filter_mode
& NETWORK_FILTER
)
4852 } else if (filter_mode
& FILESYS_FILTER
)
4858 case BSC_read_nocancel
:
4859 case BSC_write_nocancel
:
4861 * we don't care about error in these cases
4864 network_fd_isset
= fs_usage_fd_isset(ti
->thread
, fd
);
4866 if (network_fd_isset
) {
4867 if (filter_mode
& NETWORK_FILTER
)
4869 } else if (filter_mode
& FILESYS_FILTER
)
4874 case BSC_accept_nocancel
:
4879 fs_usage_fd_set(ti
->thread
, fd
);
4880 if (filter_mode
& NETWORK_FILTER
)
4891 case BSC_sendto_nocancel
:
4892 case BSC_recvfrom_nocancel
:
4893 case BSC_recvmsg_nocancel
:
4894 case BSC_sendmsg_nocancel
:
4895 case BSC_connect_nocancel
:
4899 fs_usage_fd_set(ti
->thread
, fd
);
4900 if (filter_mode
& NETWORK_FILTER
)
4905 case BSC_select_nocancel
:
4906 case BSC_socketpair
:
4908 * Cannot determine info about file descriptors
4910 if (filter_mode
& NETWORK_FILTER
)
4917 * We track these cases for fd state only
4920 network_fd_isset
= fs_usage_fd_isset(ti
->thread
, fd
);
4922 if (error
== 0 && network_fd_isset
) {
4924 * then we are duping a socket descriptor
4926 fd
= retval
; /* the new fd */
4927 fs_usage_fd_set(ti
->thread
, fd
);
4932 if (filter_mode
& FILESYS_FILTER
)
4941 * Allocate a buffer that is large enough to hold the maximum arguments
4942 * to execve(). This is used when getting the arguments to programs
4943 * when we see LaunchCFMApps. If this fails, it is not fatal, we will
4944 * simply not resolve the command name.
4948 init_arguments_buffer()
4954 mib
[1] = KERN_ARGMAX
;
4955 size
= sizeof(argmax
);
4957 if (sysctl(mib
, 2, &argmax
, &size
, NULL
, 0) == -1)
4960 /* Hack to avoid kernel bug. */
4961 if (argmax
> 8192) {
4965 arguments
= (char *)malloc(argmax
);
4970 get_real_command_name(int pid
, char *cbuf
, int csize
)
4973 * Get command and arguments.
4977 char *command_beg
, *command
, *command_end
;
4983 bzero(arguments
, argmax
);
4988 * A sysctl() is made to find out the full path that the command
4992 mib
[1] = KERN_PROCARGS2
;
4996 if (sysctl(mib
, 3, arguments
, (size_t *)&argmax
, NULL
, 0) < 0)
5000 * Skip the saved exec_path
5002 for (cp
= arguments
; cp
< &arguments
[argmax
]; cp
++) {
5005 * End of exec_path reached
5010 if (cp
== &arguments
[argmax
])
5014 * Skip trailing '\0' characters
5016 for (; cp
< &arguments
[argmax
]; cp
++) {
5019 * Beginning of first argument reached
5024 if (cp
== &arguments
[argmax
])
5029 * Make sure that the command is '\0'-terminated. This protects
5030 * against malicious programs; under normal operation this never
5031 * ends up being a problem..
5033 for (; cp
< &arguments
[argmax
]; cp
++) {
5036 * End of first argument reached
5041 if (cp
== &arguments
[argmax
])
5044 command_end
= command
= cp
;
5047 * Get the basename of command
5049 for (command
--; command
>= command_beg
; command
--) {
5050 if (*command
== '/') {
5055 (void) strncpy(cbuf
, (char *)command
, csize
);
5056 cbuf
[csize
-1] = '\0';