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. -DPRIVATE -D__APPLE_PRIVATE -O -o fs_usage fs_usage.c
29 #define Default_DELAY 1 /* default delay interval */
40 #include <sys/types.h>
41 #include <sys/param.h>
46 #include <sys/ioctl.h>
48 #ifndef KERNEL_PRIVATE
49 #define KERNEL_PRIVATE
50 #include <sys/kdebug.h>
53 #include <sys/kdebug.h>
54 #endif /*KERNEL_PRIVATE*/
56 #include <sys/sysctl.h>
58 #import <mach/clock_types.h>
59 #import <mach/mach_time.h>
68 typedef struct LibraryInfo
{
69 unsigned long address
;
73 LibraryInfo frameworkInfo
[MAXINDEX
];
74 int numFrameworks
= 0;
76 char seg_addr_table
[256]="/AppleInternal/Developer/seg_addr_table";
82 MAXCOLS controls when extra data kicks in.
83 MAX_WIDE_MODE_COLS controls -w mode to get even wider data in path.
84 If NUMPARMS changes to match the kernel, it will automatically
85 get reflected in the -w mode output.
88 #define PATHLENGTH (NUMPARMS*sizeof(long))
90 #define MAX_WIDE_MODE_COLS (PATHLENGTH + 80)
91 #define MAXWIDTH MAX_WIDE_MODE_COLS + 64
107 long pathname
[NUMPARMS
+ 1]; /* add room for null terminator */
110 #define MAX_THREADS 512
111 struct th_info th_state
[MAX_THREADS
];
115 int need_new_map
= 1;
119 int select_pid_mode
= 0; /* Flag set indicates that output is restricted
120 to selected pids or commands */
122 int one_good_pid
= 0; /* Used to fail gracefully when bad pids given */
128 * Network only or filesystem only output filter
129 * Default of zero means report all activity - no filtering
131 #define FILESYS_FILTER 0x01
132 #define NETWORK_FILTER 0x02
133 #define CACHEHIT_FILTER 0x04
134 #define EXEC_FILTER 0x08
135 #define DEFAULT_DO_NOT_FILTER 0x00
137 int filter_mode
= CACHEHIT_FILTER
;
142 struct diskrec
*next
;
157 int completion_thread
;
158 char issuing_command
[MAXCOMLEN
];
160 double completed_time
;
163 struct diskrec
*disk_list
= NULL
;
164 struct diskio
*free_diskios
= NULL
;
165 struct diskio
*busy_diskios
= NULL
;
167 struct diskio
*insert_diskio();
168 struct diskio
*complete_diskio();
172 char *find_disk_name();
173 void cache_disk_names();
174 int ReadSegAddrTable();
175 void mark_thread_waited(int);
176 int check_filter_mode(struct th_info
*, int, int, int, char *);
177 void fs_usage_fd_set(unsigned int, unsigned int);
178 int fs_usage_fd_isset(unsigned int, unsigned int);
179 void fs_usage_fd_clear(unsigned int, unsigned int);
180 void init_arguments_buffer();
181 int get_real_command_name(int, char *, int);
182 void create_map_entry(int, int, char *);
184 void enter_syscall();
186 void extend_syscall();
187 void kill_thread_map();
189 #define TRACE_DATA_NEWTHREAD 0x07000004
190 #define TRACE_DATA_EXEC 0x07000008
191 #define TRACE_STRING_NEWTHREAD 0x07010004
192 #define TRACE_STRING_EXEC 0x07010008
194 #define MACH_vmfault 0x01300000
195 #define MACH_pageout 0x01300004
196 #define MACH_sched 0x01400000
197 #define MACH_stkhandoff 0x01400008
198 #define VFS_LOOKUP 0x03010090
199 #define BSC_exit 0x040C0004
201 #define P_WrData 0x03020000
202 #define P_RdData 0x03020008
203 #define P_WrMeta 0x03020020
204 #define P_RdMeta 0x03020028
205 #define P_PgOut 0x03020040
206 #define P_PgIn 0x03020048
207 #define P_WrDataAsync 0x03020010
208 #define P_RdDataAsync 0x03020018
209 #define P_WrMetaAsync 0x03020030
210 #define P_RdMetaAsync 0x03020038
211 #define P_PgOutAsync 0x03020050
212 #define P_PgInAsync 0x03020058
214 #define P_WrDataDone 0x03020004
215 #define P_RdDataDone 0x0302000C
216 #define P_WrMetaDone 0x03020024
217 #define P_RdMetaDone 0x0302002C
218 #define P_PgOutDone 0x03020044
219 #define P_PgInDone 0x0302004C
220 #define P_WrDataAsyncDone 0x03020014
221 #define P_RdDataAsyncDone 0x0302001C
222 #define P_WrMetaAsyncDone 0x03020034
223 #define P_RdMetaAsyncDone 0x0302003C
224 #define P_PgOutAsyncDone 0x03020054
225 #define P_PgInAsyncDone 0x0302005C
228 #define MSC_map_fd 0x010c00ac
230 // Network related codes
231 #define BSC_recvmsg 0x040C006C
232 #define BSC_sendmsg 0x040C0070
233 #define BSC_recvfrom 0x040C0074
234 #define BSC_accept 0x040C0078
235 #define BSC_select 0x040C0174
236 #define BSC_socket 0x040C0184
237 #define BSC_connect 0x040C0188
238 #define BSC_bind 0x040C01A0
239 #define BSC_listen 0x040C01A8
240 #define BSC_sendto 0x040C0214
241 #define BSC_socketpair 0x040C021C
243 #define BSC_read 0x040C000C
244 #define BSC_write 0x040C0010
245 #define BSC_open 0x040C0014
246 #define BSC_close 0x040C0018
247 #define BSC_link 0x040C0024
248 #define BSC_unlink 0x040C0028
249 #define BSC_chdir 0x040c0030
250 #define BSC_fchdir 0x040c0034
251 #define BSC_mknod 0x040C0038
252 #define BSC_chmod 0x040C003C
253 #define BSC_chown 0x040C0040
254 #define BSC_access 0x040C0084
255 #define BSC_chflags 0x040C0088
256 #define BSC_fchflags 0x040C008C
257 #define BSC_sync 0x040C0090
258 #define BSC_dup 0x040C00A4
259 #define BSC_revoke 0x040C00E0
260 #define BSC_symlink 0x040C00E4
261 #define BSC_readlink 0x040C00E8
262 #define BSC_execve 0x040C00EC
263 #define BSC_chroot 0x040C00F4
264 #define BSC_dup2 0x040C0168
265 #define BSC_fsync 0x040C017C
266 #define BSC_readv 0x040C01E0
267 #define BSC_writev 0x040C01E4
268 #define BSC_fchown 0x040C01EC
269 #define BSC_fchmod 0x040C01F0
270 #define BSC_rename 0x040C0200
271 #define BSC_mkfifo 0x040c0210
272 #define BSC_mkdir 0x040C0220
273 #define BSC_rmdir 0x040C0224
274 #define BSC_utimes 0x040C0228
275 #define BSC_futimes 0x040C022C
276 #define BSC_pread 0x040C0264
277 #define BSC_pread_extended 0x040E0264
278 #define BSC_pwrite 0x040C0268
279 #define BSC_pwrite_extended 0x040E0268
280 #define BSC_statfs 0x040C0274
281 #define BSC_fstatfs 0x040C0278
282 #define BSC_stat 0x040C02F0
283 #define BSC_fstat 0x040C02F4
284 #define BSC_lstat 0x040C02F8
285 #define BSC_pathconf 0x040C02FC
286 #define BSC_fpathconf 0x040C0300
287 #define BSC_getdirentries 0x040C0310
288 #define BSC_mmap 0x040c0314
289 #define BSC_lseek 0x040c031c
290 #define BSC_truncate 0x040C0320
291 #define BSC_ftruncate 0x040C0324
292 #define BSC_undelete 0x040C0334
293 #define BSC_statv 0x040C0364
294 #define BSC_lstatv 0x040C0368
295 #define BSC_fstatv 0x040C036C
296 #define BSC_mkcomplex 0x040C0360
297 #define BSC_getattrlist 0x040C0370
298 #define BSC_setattrlist 0x040C0374
299 #define BSC_getdirentriesattr 0x040C0378
300 #define BSC_exchangedata 0x040C037C
301 #define BSC_checkuseraccess 0x040C0380
302 #define BSC_searchfs 0x040C0384
303 #define BSC_delete 0x040C0388
304 #define BSC_copyfile 0x040C038C
305 #define BSC_getxattr 0x040C03A8
306 #define BSC_fgetxattr 0x040C03AC
307 #define BSC_setxattr 0x040C03B0
308 #define BSC_fsetxattr 0x040C03B4
309 #define BSC_removexattr 0x040C03B8
310 #define BSC_fremovexattr 0x040C03BC
311 #define BSC_listxattr 0x040C03C0
312 #define BSC_flistxattr 0x040C03C4
313 #define BSC_fsctl 0x040C03C8
314 #define BSC_open_extended 0x040C0454
315 #define BSC_stat_extended 0x040C045C
316 #define BSC_lstat_extended 0x040C0460
317 #define BSC_fstat_extended 0x040C0464
318 #define BSC_chmod_extended 0x040C0468
319 #define BSC_fchmod_extended 0x040C046C
320 #define BSC_access_extended 0x040C0470
321 #define BSC_mkfifo_extended 0x040C048C
322 #define BSC_mkdir_extended 0x040C0490
323 #define BSC_load_shared_file 0x040C04A0
324 #define BSC_lchown 0x040C05B0
326 // Carbon File Manager support
327 #define FILEMGR_PBGETCATALOGINFO 0x1e000020
328 #define FILEMGR_PBGETCATALOGINFOBULK 0x1e000024
329 #define FILEMGR_PBCREATEFILEUNICODE 0x1e000028
330 #define FILEMGR_PBCREATEDIRECTORYUNICODE 0x1e00002c
331 #define FILEMGR_PBCREATEFORK 0x1e000030
332 #define FILEMGR_PBDELETEFORK 0x1e000034
333 #define FILEMGR_PBITERATEFORK 0x1e000038
334 #define FILEMGR_PBOPENFORK 0x1e00003c
335 #define FILEMGR_PBREADFORK 0x1e000040
336 #define FILEMGR_PBWRITEFORK 0x1e000044
337 #define FILEMGR_PBALLOCATEFORK 0x1e000048
338 #define FILEMGR_PBDELETEOBJECT 0x1e00004c
339 #define FILEMGR_PBEXCHANGEOBJECT 0x1e000050
340 #define FILEMGR_PBGETFORKCBINFO 0x1e000054
341 #define FILEMGR_PBGETVOLUMEINFO 0x1e000058
342 #define FILEMGR_PBMAKEFSREF 0x1e00005c
343 #define FILEMGR_PBMAKEFSREFUNICODE 0x1e000060
344 #define FILEMGR_PBMOVEOBJECT 0x1e000064
345 #define FILEMGR_PBOPENITERATOR 0x1e000068
346 #define FILEMGR_PBRENAMEUNICODE 0x1e00006c
347 #define FILEMGR_PBSETCATALOGINFO 0x1e000070
348 #define FILEMGR_PBSETVOLUMEINFO 0x1e000074
349 #define FILEMGR_FSREFMAKEPATH 0x1e000078
350 #define FILEMGR_FSPATHMAKEREF 0x1e00007c
352 #define FILEMGR_PBGETCATINFO 0x1e010000
353 #define FILEMGR_PBGETCATINFOLITE 0x1e010004
354 #define FILEMGR_PBHGETFINFO 0x1e010008
355 #define FILEMGR_PBXGETVOLINFO 0x1e01000c
356 #define FILEMGR_PBHCREATE 0x1e010010
357 #define FILEMGR_PBHOPENDF 0x1e010014
358 #define FILEMGR_PBHOPENRF 0x1e010018
359 #define FILEMGR_PBHGETDIRACCESS 0x1e01001c
360 #define FILEMGR_PBHSETDIRACCESS 0x1e010020
361 #define FILEMGR_PBHMAPID 0x1e010024
362 #define FILEMGR_PBHMAPNAME 0x1e010028
363 #define FILEMGR_PBCLOSE 0x1e01002c
364 #define FILEMGR_PBFLUSHFILE 0x1e010030
365 #define FILEMGR_PBGETEOF 0x1e010034
366 #define FILEMGR_PBSETEOF 0x1e010038
367 #define FILEMGR_PBGETFPOS 0x1e01003c
368 #define FILEMGR_PBREAD 0x1e010040
369 #define FILEMGR_PBWRITE 0x1e010044
370 #define FILEMGR_PBGETFCBINFO 0x1e010048
371 #define FILEMGR_PBSETFINFO 0x1e01004c
372 #define FILEMGR_PBALLOCATE 0x1e010050
373 #define FILEMGR_PBALLOCCONTIG 0x1e010054
374 #define FILEMGR_PBSETFPOS 0x1e010058
375 #define FILEMGR_PBSETCATINFO 0x1e01005c
376 #define FILEMGR_PBGETVOLPARMS 0x1e010060
377 #define FILEMGR_PBSETVINFO 0x1e010064
378 #define FILEMGR_PBMAKEFSSPEC 0x1e010068
379 #define FILEMGR_PBHGETVINFO 0x1e01006c
380 #define FILEMGR_PBCREATEFILEIDREF 0x1e010070
381 #define FILEMGR_PBDELETEFILEIDREF 0x1e010074
382 #define FILEMGR_PBRESOLVEFILEIDREF 0x1e010078
383 #define FILEMGR_PBFLUSHVOL 0x1e01007c
384 #define FILEMGR_PBHRENAME 0x1e010080
385 #define FILEMGR_PBCATMOVE 0x1e010084
386 #define FILEMGR_PBEXCHANGEFILES 0x1e010088
387 #define FILEMGR_PBHDELETE 0x1e01008c
388 #define FILEMGR_PBDIRCREATE 0x1e010090
389 #define FILEMGR_PBCATSEARCH 0x1e010094
390 #define FILEMGR_PBHSETFLOCK 0x1e010098
391 #define FILEMGR_PBHRSTFLOCK 0x1e01009c
392 #define FILEMGR_PBLOCKRANGE 0x1e0100a0
393 #define FILEMGR_PBUNLOCKRANGE 0x1e0100a4
396 #define FILEMGR_CLASS 0x1e
402 int exclude_pids
= 0;
403 int exclude_default_pids
= 1;
405 struct kinfo_proc
*kp_buffer
= 0;
408 #define SAMPLE_SIZE 60000
410 #define DBG_ZERO_FILL_FAULT 1
411 #define DBG_PAGEIN_FAULT 2
412 #define DBG_COW_FAULT 3
413 #define DBG_CACHE_HIT_FAULT 4
415 #define DBG_FUNC_ALL (DBG_FUNC_START | DBG_FUNC_END)
416 #define DBG_FUNC_MASK 0xfffffffc
418 double divisor
= 0.0; /* Trace divisor converts to microseconds */
424 kbufinfo_t bufinfo
= {0, 0, 0, 0, 0};
426 int total_threads
= 0;
427 kd_threadmap
*mapptr
= 0; /* pointer to list of threads */
429 /* defines for tracking file descriptor state */
430 #define FS_USAGE_FD_SETSIZE 256 /* Initial number of file descriptors per
431 thread that we will track */
433 #define FS_USAGE_NFDBITS (sizeof (unsigned long) * 8)
434 #define FS_USAGE_NFDBYTES(n) (((n) / FS_USAGE_NFDBITS) * sizeof (unsigned long))
437 unsigned int fd_valid
; /* set if this is a valid entry */
438 unsigned int fd_thread
;
439 unsigned int fd_setsize
; /* this is a bit count */
440 unsigned long *fd_setptr
; /* file descripter bitmap */
443 fd_threadmap
*fdmapptr
= 0; /* pointer to list of threads for fd tracking */
445 int trace_enabled
= 0;
446 int set_remove_flag
= 1;
458 void leave() /* exit under normal conditions -- INT handler */
463 void set_pidexclude();
468 if (exclude_pids
== 0) {
469 for (i
= 0; i
< num_of_pids
; i
++)
470 set_pidcheck(pids
[i
], 0);
473 for (i
= 0; i
< num_of_pids
; i
++)
474 set_pidexclude(pids
[i
], 0);
481 void get_screenwidth()
488 if (ioctl(1, TIOCGWINSZ
, &size
) != -1) {
489 columns
= size
.ws_col
;
491 if (columns
> MAXWIDTH
)
505 exit_usage(char *myname
) {
507 fprintf(stderr
, "Usage: %s [-e] [-w] [-f mode] [pid | cmd [pid | cmd]....]\n", myname
);
508 fprintf(stderr
, " -e exclude the specified list of pids from the sample\n");
509 fprintf(stderr
, " and exclude fs_usage by default\n");
510 fprintf(stderr
, " -w force wider, detailed, output\n");
511 fprintf(stderr
, " -f Output is based on the mode provided\n");
512 fprintf(stderr
, " mode = \"network\" Show only network related output\n");
513 fprintf(stderr
, " mode = \"filesys\" Show only file system related output\n");
514 fprintf(stderr
, " mode = \"exec\" Show only execs\n");
515 fprintf(stderr
, " mode = \"cachehit\" In addition, show cachehits\n");
516 fprintf(stderr
, " pid selects process(s) to sample\n");
517 fprintf(stderr
, " cmd selects process(s) matching command string to sample\n");
518 fprintf(stderr
, "\n%s will handle a maximum list of %d pids.\n\n", myname
, MAX_PIDS
);
519 fprintf(stderr
, "By default (no options) the following processes are excluded from the output:\n");
520 fprintf(stderr
, "fs_usage, Terminal, telnetd, sshd, rlogind, tcsh, csh, sh\n\n");
530 char *myname
= "fs_usage";
537 void set_pidexclude();
540 if ( geteuid() != 0 ) {
541 fprintf(stderr
, "'fs_usage' must be run as root...\n");
548 if ((myname
= rindex(argv
[0], '/')) == 0) {
557 while ((ch
= getopt(argc
, argv
, "ewf:")) != EOF
) {
561 exclude_default_pids
= 0;
565 if ((uint
)columns
< MAX_WIDE_MODE_COLS
)
566 columns
= MAX_WIDE_MODE_COLS
;
569 if (!strcmp(optarg
, "network"))
570 filter_mode
|= NETWORK_FILTER
;
571 else if (!strcmp(optarg
, "filesys"))
572 filter_mode
|= FILESYS_FILTER
;
573 else if (!strcmp(optarg
, "cachehit"))
574 filter_mode
&= ~CACHEHIT_FILTER
; /* turns on CACHE_HIT */
575 else if (!strcmp(optarg
, "exec"))
576 filter_mode
|= EXEC_FILTER
;
587 /* If we process any list of pids/cmds, then turn off the defaults */
589 exclude_default_pids
= 0;
591 while (argc
> 0 && num_of_pids
< (MAX_PIDS
- 1)) {
598 /* Exclude a set of default pids */
599 if (exclude_default_pids
)
601 argtopid("Terminal");
614 if (num_of_pids
< (MAX_PIDS
- 1))
615 pids
[num_of_pids
++] = getpid();
621 for (i
= 0; i
< num_of_pids
; i
++)
624 fprintf(stderr
, "exclude pid %d\n", pids
[i
]);
626 fprintf(stderr
, "pid %d\n", pids
[i
]);
630 /* set up signal handlers */
631 signal(SIGINT
, leave
);
632 signal(SIGQUIT
, leave
);
633 signal(SIGHUP
, leave
);
634 signal(SIGTERM
, leave
);
635 signal(SIGWINCH
, sigwinch
);
637 if ((my_buffer
= malloc(SAMPLE_SIZE
* sizeof(kd_buf
))) == (char *)0)
638 quit("can't allocate memory for tracing info\n");
644 set_numbufs(SAMPLE_SIZE
);
647 if (exclude_pids
== 0) {
648 for (i
= 0; i
< num_of_pids
; i
++)
649 set_pidcheck(pids
[i
], 1);
651 for (i
= 0; i
< num_of_pids
; i
++)
652 set_pidexclude(pids
[i
], 1);
655 if (select_pid_mode
&& !one_good_pid
)
658 An attempt to restrict output to a given
659 pid or command has failed. Exit gracefully
667 init_arguments_buffer();
683 struct kinfo_proc
*kp
;
688 mib
[2] = KERN_PROC_ALL
;
691 if (sysctl(mib
, 4, NULL
, &bufSize
, NULL
, 0) < 0)
692 quit("trace facility failure, KERN_PROC_ALL\n");
694 if((kp
= (struct kinfo_proc
*)malloc(bufSize
)) == (struct kinfo_proc
*)0)
695 quit("can't allocate memory for proc buffer\n");
697 if (sysctl(mib
, 4, kp
, &bufSize
, NULL
, 0) < 0)
698 quit("trace facility failure, KERN_PROC_ALL\n");
700 kp_nentries
= bufSize
/ sizeof(struct kinfo_proc
);
705 struct th_info
*find_thread(int thread
, int type
) {
708 for (ti
= th_state
; ti
< &th_state
[cur_max
]; ti
++) {
709 if (ti
->thread
== thread
) {
710 if (type
== ti
->type
)
712 if (ti
->in_filemgr
) {
721 return ((struct th_info
*)0);
726 mark_thread_waited(int thread
) {
729 for (ti
= th_state
; ti
< &th_state
[cur_max
]; ti
++) {
730 if (ti
->thread
== thread
) {
741 mib
[1] = KERN_KDEBUG
;
742 mib
[2] = KERN_KDENABLE
; /* protocol */
745 mib
[5] = 0; /* no flags */
746 if (sysctl(mib
, 4, NULL
, &needed
, NULL
, 0) < 0)
747 quit("trace facility failure, KERN_KDENABLE\n");
756 set_numbufs(int nbufs
)
759 mib
[1] = KERN_KDEBUG
;
760 mib
[2] = KERN_KDSETBUF
;
763 mib
[5] = 0; /* no flags */
764 if (sysctl(mib
, 4, NULL
, &needed
, NULL
, 0) < 0)
765 quit("trace facility failure, KERN_KDSETBUF\n");
768 mib
[1] = KERN_KDEBUG
;
769 mib
[2] = KERN_KDSETUP
;
772 mib
[5] = 0; /* no flags */
773 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0)
774 quit("trace facility failure, KERN_KDSETUP\n");
778 set_pidcheck(int pid
, int on_off
)
782 kr
.type
= KDBG_TYPENONE
;
785 needed
= sizeof(kd_regtype
);
787 mib
[1] = KERN_KDEBUG
;
788 mib
[2] = KERN_KDPIDTR
;
793 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0) {
795 fprintf(stderr
, "pid %d does not exist\n", pid
);
803 on_off == 0 turns off pid exclusion
804 on_off == 1 turns on pid exclusion
807 set_pidexclude(int pid
, int on_off
)
813 kr
.type
= KDBG_TYPENONE
;
816 needed
= sizeof(kd_regtype
);
818 mib
[1] = KERN_KDEBUG
;
819 mib
[2] = KERN_KDPIDEX
;
824 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0) {
826 fprintf(stderr
, "pid %d does not exist\n", pid
);
831 get_bufinfo(kbufinfo_t
*val
)
833 needed
= sizeof (*val
);
835 mib
[1] = KERN_KDEBUG
;
836 mib
[2] = KERN_KDGETBUF
;
839 mib
[5] = 0; /* no flags */
841 if (sysctl(mib
, 3, val
, &needed
, 0, 0) < 0)
842 quit("trace facility failure, KERN_KDGETBUF\n");
852 mib
[1] = KERN_KDEBUG
;
853 mib
[2] = KERN_KDREMOVE
; /* protocol */
856 mib
[5] = 0; /* no flags */
857 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0)
862 quit("the trace facility is currently in use...\n fs_usage, sc_usage, and latency use this feature.\n\n");
864 quit("trace facility failure, KERN_KDREMOVE\n");
872 kr
.type
= KDBG_RANGETYPE
;
875 needed
= sizeof(kd_regtype
);
877 mib
[1] = KERN_KDEBUG
;
878 mib
[2] = KERN_KDSETREG
;
881 mib
[5] = 0; /* no flags */
883 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0)
884 quit("trace facility failure, KERN_KDSETREG\n");
887 mib
[1] = KERN_KDEBUG
;
888 mib
[2] = KERN_KDSETUP
;
891 mib
[5] = 0; /* no flags */
893 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0)
894 quit("trace facility failure, KERN_KDSETUP\n");
903 void read_command_map();
904 void create_map_entry();
906 /* Get kernel buffer information */
907 get_bufinfo(&bufinfo
);
913 needed
= bufinfo
.nkdbufs
* sizeof(kd_buf
);
915 mib
[1] = KERN_KDEBUG
;
916 mib
[2] = KERN_KDREADTR
;
919 mib
[5] = 0; /* no flags */
921 if (sysctl(mib
, 3, my_buffer
, &needed
, NULL
, 0) < 0)
922 quit("trace facility failure, KERN_KDREADTR\n");
925 if (bufinfo
.flags
& KDBG_WRAPPED
) {
926 fprintf(stderr
, "fs_usage: buffer overrun, events generated too quickly\n");
928 for (i
= 0; i
< cur_max
; i
++) {
929 th_state
[i
].thread
= 0;
931 th_state
[i
].pathptr
= (long *)NULL
;
932 th_state
[i
].pathname
[0] = 0;
940 kd
= (kd_buf
*)my_buffer
;
942 fprintf(stderr
, "READTR returned %d items\n", count
);
944 for (i
= 0; i
< count
; i
++) {
957 debugid
= kd
[i
].debugid
;
958 type
= kd
[i
].debugid
& DBG_FUNC_MASK
;
960 now
= kd
[i
].timestamp
& KDBG_TIMESTAMP_MASK
;
965 * Compute bias seconds after each trace buffer read.
966 * This helps resync timestamps with the system clock
967 * in the event of a system sleep.
969 l_usecs
= (long long)(now
/ divisor
);
970 secs
= l_usecs
/ 1000000;
971 curr_time
= time((long *)0);
972 bias_secs
= curr_time
- secs
;
990 insert_diskio(type
, kd
[i
].arg1
, kd
[i
].arg2
, kd
[i
].arg3
, kd
[i
].arg4
, thread
, (double)now
);
999 case P_RdMetaAsyncDone
:
1000 case P_WrMetaAsyncDone
:
1001 case P_RdDataAsyncDone
:
1002 case P_WrDataAsyncDone
:
1003 case P_PgInAsyncDone
:
1004 case P_PgOutAsyncDone
:
1005 if ((dio
= complete_diskio(kd
[i
].arg1
, kd
[i
].arg4
, kd
[i
].arg3
, thread
, (double)now
))) {
1012 case TRACE_DATA_NEWTHREAD
:
1014 for (n
= 0, ti
= th_state
; ti
< &th_state
[MAX_THREADS
]; ti
++, n
++) {
1015 if (ti
->thread
== 0)
1018 if (ti
== &th_state
[MAX_THREADS
])
1023 ti
->thread
= thread
;
1024 ti
->child_thread
= kd
[i
].arg1
;
1025 ti
->pid
= kd
[i
].arg2
;
1028 case TRACE_STRING_NEWTHREAD
:
1029 if ((ti
= find_thread(thread
, 0)) == (struct th_info
*)0)
1031 if (ti
->child_thread
== 0)
1033 create_map_entry(ti
->child_thread
, ti
->pid
, (char *)&kd
[i
].arg1
);
1035 if (ti
== &th_state
[cur_max
- 1])
1037 ti
->child_thread
= 0;
1042 case TRACE_DATA_EXEC
:
1044 for (n
= 0, ti
= th_state
; ti
< &th_state
[MAX_THREADS
]; ti
++, n
++) {
1045 if (ti
->thread
== 0)
1048 if (ti
== &th_state
[MAX_THREADS
])
1053 ti
->thread
= thread
;
1054 ti
->pid
= kd
[i
].arg1
;
1057 case TRACE_STRING_EXEC
:
1058 if ((ti
= find_thread(thread
, 0)) == (struct th_info
*)0)
1060 /* this is for backwards compatibility */
1061 create_map_entry(thread
, 0, (char *)&kd
[i
].arg1
);
1065 create_map_entry(thread
, ti
->pid
, (char *)&kd
[i
].arg1
);
1067 if (ti
== &th_state
[cur_max
- 1])
1075 kill_thread_map(thread
);
1079 case MACH_stkhandoff
:
1080 mark_thread_waited(thread
);
1084 if ((ti
= find_thread(thread
, 0)) == (struct th_info
*)0)
1088 sargptr
= ti
->pathname
;
1089 *sargptr
++ = kd
[i
].arg2
;
1090 *sargptr
++ = kd
[i
].arg3
;
1091 *sargptr
++ = kd
[i
].arg4
;
1093 * NULL terminate the 'string'
1097 ti
->pathptr
= sargptr
;
1099 sargptr
= ti
->pathptr
;
1102 We don't want to overrun our pathname buffer if the
1103 kernel sends us more VFS_LOOKUP entries than we can
1106 if (sargptr
>= &ti
->pathname
[NUMPARMS
]) {
1110 We need to detect consecutive vfslookup entries.
1111 So, if we get here and find a START entry,
1112 fake the pathptr so we can bypass all further
1116 if (debugid
& DBG_FUNC_START
) {
1117 ti
->pathptr
= &ti
->pathname
[NUMPARMS
];
1120 *sargptr
++ = kd
[i
].arg1
;
1121 *sargptr
++ = kd
[i
].arg2
;
1122 *sargptr
++ = kd
[i
].arg3
;
1123 *sargptr
++ = kd
[i
].arg4
;
1125 * NULL terminate the 'string'
1129 ti
->pathptr
= sargptr
;
1134 if (debugid
& DBG_FUNC_START
) {
1138 case FILEMGR_PBGETCATALOGINFO
:
1139 p
= "GetCatalogInfo";
1141 case FILEMGR_PBGETCATALOGINFOBULK
:
1142 p
= "GetCatalogInfoBulk";
1144 case FILEMGR_PBCREATEFILEUNICODE
:
1145 p
= "CreateFileUnicode";
1147 case FILEMGR_PBCREATEDIRECTORYUNICODE
:
1148 p
= "CreateDirectoryUnicode";
1150 case FILEMGR_PBCREATEFORK
:
1153 case FILEMGR_PBDELETEFORK
:
1156 case FILEMGR_PBITERATEFORK
:
1157 p
= "PBIterateFork";
1159 case FILEMGR_PBOPENFORK
:
1162 case FILEMGR_PBREADFORK
:
1165 case FILEMGR_PBWRITEFORK
:
1168 case FILEMGR_PBALLOCATEFORK
:
1169 p
= "PBAllocateFork";
1171 case FILEMGR_PBDELETEOBJECT
:
1172 p
= "PBDeleteObject";
1174 case FILEMGR_PBEXCHANGEOBJECT
:
1175 p
= "PBExchangeObject";
1177 case FILEMGR_PBGETFORKCBINFO
:
1178 p
= "PBGetForkCBInfo";
1180 case FILEMGR_PBGETVOLUMEINFO
:
1181 p
= "PBGetVolumeInfo";
1183 case FILEMGR_PBMAKEFSREF
:
1186 case FILEMGR_PBMAKEFSREFUNICODE
:
1187 p
= "PBMakeFSRefUnicode";
1189 case FILEMGR_PBMOVEOBJECT
:
1192 case FILEMGR_PBOPENITERATOR
:
1193 p
= "PBOpenIterator";
1195 case FILEMGR_PBRENAMEUNICODE
:
1196 p
= "PBRenameUnicode";
1198 case FILEMGR_PBSETCATALOGINFO
:
1199 p
= "SetCatalogInfo";
1201 case FILEMGR_PBSETVOLUMEINFO
:
1202 p
= "SetVolumeInfo";
1204 case FILEMGR_FSREFMAKEPATH
:
1205 p
= "FSRefMakePath";
1207 case FILEMGR_FSPATHMAKEREF
:
1208 p
= "FSPathMakeRef";
1211 case FILEMGR_PBGETCATINFO
:
1214 case FILEMGR_PBGETCATINFOLITE
:
1215 p
= "GetCatInfoLite";
1217 case FILEMGR_PBHGETFINFO
:
1220 case FILEMGR_PBXGETVOLINFO
:
1221 p
= "PBXGetVolInfo";
1223 case FILEMGR_PBHCREATE
:
1226 case FILEMGR_PBHOPENDF
:
1229 case FILEMGR_PBHOPENRF
:
1232 case FILEMGR_PBHGETDIRACCESS
:
1233 p
= "PBHGetDirAccess";
1235 case FILEMGR_PBHSETDIRACCESS
:
1236 p
= "PBHSetDirAccess";
1238 case FILEMGR_PBHMAPID
:
1241 case FILEMGR_PBHMAPNAME
:
1244 case FILEMGR_PBCLOSE
:
1247 case FILEMGR_PBFLUSHFILE
:
1250 case FILEMGR_PBGETEOF
:
1253 case FILEMGR_PBSETEOF
:
1256 case FILEMGR_PBGETFPOS
:
1259 case FILEMGR_PBREAD
:
1262 case FILEMGR_PBWRITE
:
1265 case FILEMGR_PBGETFCBINFO
:
1268 case FILEMGR_PBSETFINFO
:
1271 case FILEMGR_PBALLOCATE
:
1274 case FILEMGR_PBALLOCCONTIG
:
1275 p
= "PBAllocContig";
1277 case FILEMGR_PBSETFPOS
:
1280 case FILEMGR_PBSETCATINFO
:
1283 case FILEMGR_PBGETVOLPARMS
:
1284 p
= "PBGetVolParms";
1286 case FILEMGR_PBSETVINFO
:
1289 case FILEMGR_PBMAKEFSSPEC
:
1292 case FILEMGR_PBHGETVINFO
:
1295 case FILEMGR_PBCREATEFILEIDREF
:
1296 p
= "PBCreateFileIDRef";
1298 case FILEMGR_PBDELETEFILEIDREF
:
1299 p
= "PBDeleteFileIDRef";
1301 case FILEMGR_PBRESOLVEFILEIDREF
:
1302 p
= "PBResolveFileIDRef";
1304 case FILEMGR_PBFLUSHVOL
:
1307 case FILEMGR_PBHRENAME
:
1310 case FILEMGR_PBCATMOVE
:
1313 case FILEMGR_PBEXCHANGEFILES
:
1314 p
= "PBExchangeFiles";
1316 case FILEMGR_PBHDELETE
:
1319 case FILEMGR_PBDIRCREATE
:
1322 case FILEMGR_PBCATSEARCH
:
1325 case FILEMGR_PBHSETFLOCK
:
1328 case FILEMGR_PBHRSTFLOCK
:
1331 case FILEMGR_PBLOCKRANGE
:
1334 case FILEMGR_PBUNLOCKRANGE
:
1335 p
= "PBUnlockRange";
1341 enter_syscall(thread
, type
, &kd
[i
], p
, (double)now
);
1347 case BSC_pread_extended
:
1348 case BSC_pwrite_extended
:
1349 extend_syscall(thread
, type
, &kd
[i
], (double)now
);
1353 exit_syscall("PAGE_OUT_D", thread
, type
, 0, kd
[i
].arg1
, 0, 4, (double)now
);
1355 exit_syscall("PAGE_OUT_V", thread
, type
, 0, kd
[i
].arg1
, 0, 4, (double)now
);
1359 if (kd
[i
].arg2
== DBG_PAGEIN_FAULT
)
1360 exit_syscall("PAGE_IN", thread
, type
, kd
[i
].arg4
, kd
[i
].arg1
, 0, 6, (double)now
);
1361 else if (kd
[i
].arg2
== DBG_CACHE_HIT_FAULT
)
1362 exit_syscall("CACHE_HIT", thread
, type
, 0, kd
[i
].arg1
, 0, 2, (double)now
);
1364 if ((ti
= find_thread(thread
, type
))) {
1365 if (ti
== &th_state
[cur_max
- 1])
1373 exit_syscall("map_fd", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1377 exit_syscall("mmap", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1381 exit_syscall("recvmsg", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1385 exit_syscall("sendmsg", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1389 exit_syscall("recvfrom", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1393 exit_syscall("accept", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 2, 0, (double)now
);
1397 exit_syscall("select", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 8, (double)now
);
1401 exit_syscall("socket", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 2, 0, (double)now
);
1405 exit_syscall("connect", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1409 exit_syscall("bind", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1413 exit_syscall("listen", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1417 exit_syscall("sendto", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1420 case BSC_socketpair
:
1421 exit_syscall("socketpair", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1425 exit_syscall("getxattr", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1429 exit_syscall("setxattr", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1432 case BSC_removexattr
:
1433 exit_syscall("removexattr", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1437 exit_syscall("listxattr", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1441 exit_syscall("stat", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1444 case BSC_stat_extended
:
1445 exit_syscall("stat_extended", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1449 exit_syscall("execve", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1452 case BSC_load_shared_file
:
1453 exit_syscall("load_sf", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1457 exit_syscall("open", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 2, 0, (double)now
);
1460 case BSC_open_extended
:
1461 exit_syscall("open_extended", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 2, 0, (double)now
);
1465 exit_syscall("dup", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 2, 0, (double)now
);
1469 exit_syscall("dup2", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 2, 0, (double)now
);
1473 exit_syscall("close", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1477 exit_syscall("read", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1481 exit_syscall("write", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1485 exit_syscall("fgetxattr", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1489 exit_syscall("fsetxattr", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1492 case BSC_fremovexattr
:
1493 exit_syscall("fremovexattr", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1496 case BSC_flistxattr
:
1497 exit_syscall("flistxattr", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1501 exit_syscall("fstat", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1504 case BSC_fstat_extended
:
1505 exit_syscall("fstat_extended", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1509 exit_syscall("lstat", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1512 case BSC_lstat_extended
:
1513 exit_syscall("lstat_extended", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1517 exit_syscall("link", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1521 exit_syscall("unlink", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1525 exit_syscall("mknod", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1529 exit_syscall("chmod", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1532 case BSC_chmod_extended
:
1533 exit_syscall("chmod_extended", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1537 exit_syscall("chown", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1541 exit_syscall("lchown", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1545 exit_syscall("access", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1548 case BSC_access_extended
:
1549 exit_syscall("access_extended", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1553 exit_syscall("chdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1557 exit_syscall("chroot", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1561 exit_syscall("utimes", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1565 exit_syscall("delete", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1569 exit_syscall("undelete", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1573 exit_syscall("revoke", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1577 exit_syscall("fsctl", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1581 exit_syscall("chflags", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1585 exit_syscall("fchflags", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1589 exit_syscall("fchdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1593 exit_syscall("futimes", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1597 exit_syscall("sync", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1601 exit_syscall("symlink", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1605 exit_syscall("readlink", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1609 exit_syscall("fsync", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1613 exit_syscall("readv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1617 exit_syscall("writev", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1621 exit_syscall("pread", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 9, (double)now
);
1625 exit_syscall("pwrite", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 9, (double)now
);
1629 exit_syscall("fchown", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1633 exit_syscall("fchmod", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1636 case BSC_fchmod_extended
:
1637 exit_syscall("fchmod_extended", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1641 exit_syscall("mkdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1644 case BSC_mkdir_extended
:
1645 exit_syscall("mkdir_extended", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1649 exit_syscall("mkfifo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1652 case BSC_mkfifo_extended
:
1653 exit_syscall("mkfifo_extended", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1657 exit_syscall("rmdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1661 exit_syscall("statfs", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1665 exit_syscall("fstatfs", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1669 exit_syscall("pathconf", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1673 exit_syscall("fpathconf", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1676 case BSC_getdirentries
:
1677 exit_syscall("getdirentries", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1681 exit_syscall("lseek", thread
, type
, kd
[i
].arg1
, kd
[i
].arg3
, 1, 5, (double)now
);
1685 exit_syscall("truncate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1689 exit_syscall("ftruncate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 3, (double)now
);
1693 exit_syscall("statv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1697 exit_syscall("lstatv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1701 exit_syscall("fstatv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1705 exit_syscall("mkcomplex", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1708 case BSC_getattrlist
:
1709 exit_syscall("getattrlist", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1712 case BSC_setattrlist
:
1713 exit_syscall("setattrlist", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1716 case BSC_getdirentriesattr
:
1717 exit_syscall("getdirentriesattr", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 1, (double)now
);
1721 case BSC_exchangedata
:
1722 exit_syscall("exchangedata", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1726 exit_syscall("rename", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1730 exit_syscall("copyfile", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1734 case BSC_checkuseraccess
:
1735 exit_syscall("checkuseraccess", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1739 exit_syscall("searchfs", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1742 case FILEMGR_PBGETCATALOGINFO
:
1743 exit_syscall("GetCatalogInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1745 case FILEMGR_PBGETCATALOGINFOBULK
:
1746 exit_syscall("GetCatalogInfoBulk", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1748 case FILEMGR_PBCREATEFILEUNICODE
:
1749 exit_syscall("CreateFileUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1751 case FILEMGR_PBCREATEDIRECTORYUNICODE
:
1752 exit_syscall("CreateDirectoryUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1754 case FILEMGR_PBCREATEFORK
:
1755 exit_syscall("PBCreateFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1757 case FILEMGR_PBDELETEFORK
:
1758 exit_syscall("PBDeleteFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1760 case FILEMGR_PBITERATEFORK
:
1761 exit_syscall("PBIterateFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1763 case FILEMGR_PBOPENFORK
:
1764 exit_syscall("PBOpenFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1766 case FILEMGR_PBREADFORK
:
1767 exit_syscall("PBReadFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1769 case FILEMGR_PBWRITEFORK
:
1770 exit_syscall("PBWriteFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1772 case FILEMGR_PBALLOCATEFORK
:
1773 exit_syscall("PBAllocateFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1775 case FILEMGR_PBDELETEOBJECT
:
1776 exit_syscall("PBDeleteObject", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1778 case FILEMGR_PBEXCHANGEOBJECT
:
1779 exit_syscall("PBExchangeObject", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1781 case FILEMGR_PBGETFORKCBINFO
:
1782 exit_syscall("PBGetForkCBInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1784 case FILEMGR_PBGETVOLUMEINFO
:
1785 exit_syscall("PBGetVolumeInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1787 case FILEMGR_PBMAKEFSREF
:
1788 exit_syscall("PBMakeFSRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1790 case FILEMGR_PBMAKEFSREFUNICODE
:
1791 exit_syscall("PBMakeFSRefUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1793 case FILEMGR_PBMOVEOBJECT
:
1794 exit_syscall("PBMoveObject", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1796 case FILEMGR_PBOPENITERATOR
:
1797 exit_syscall("PBOpenIterator", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1799 case FILEMGR_PBRENAMEUNICODE
:
1800 exit_syscall("PBRenameUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1802 case FILEMGR_PBSETCATALOGINFO
:
1803 exit_syscall("PBSetCatalogInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1805 case FILEMGR_PBSETVOLUMEINFO
:
1806 exit_syscall("PBSetVolumeInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1808 case FILEMGR_FSREFMAKEPATH
:
1809 exit_syscall("FSRefMakePath", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1811 case FILEMGR_FSPATHMAKEREF
:
1812 exit_syscall("FSPathMakeRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1814 case FILEMGR_PBGETCATINFO
:
1815 exit_syscall("GetCatInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1817 case FILEMGR_PBGETCATINFOLITE
:
1818 exit_syscall("GetCatInfoLite", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1820 case FILEMGR_PBHGETFINFO
:
1821 exit_syscall("PBHGetFInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1823 case FILEMGR_PBXGETVOLINFO
:
1824 exit_syscall("PBXGetVolInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1826 case FILEMGR_PBHCREATE
:
1827 exit_syscall("PBHCreate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1829 case FILEMGR_PBHOPENDF
:
1830 exit_syscall("PBHOpenDF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1832 case FILEMGR_PBHOPENRF
:
1833 exit_syscall("PBHOpenRF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1835 case FILEMGR_PBHGETDIRACCESS
:
1836 exit_syscall("PBHGetDirAccess", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1838 case FILEMGR_PBHSETDIRACCESS
:
1839 exit_syscall("PBHSetDirAccess", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1841 case FILEMGR_PBHMAPID
:
1842 exit_syscall("PBHMapID", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1844 case FILEMGR_PBHMAPNAME
:
1845 exit_syscall("PBHMapName", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1847 case FILEMGR_PBCLOSE
:
1848 exit_syscall("PBClose", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1850 case FILEMGR_PBFLUSHFILE
:
1851 exit_syscall("PBFlushFile", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1853 case FILEMGR_PBGETEOF
:
1854 exit_syscall("PBGetEOF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1856 case FILEMGR_PBSETEOF
:
1857 exit_syscall("PBSetEOF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1859 case FILEMGR_PBGETFPOS
:
1860 exit_syscall("PBGetFPos", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1862 case FILEMGR_PBREAD
:
1863 exit_syscall("PBRead", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1865 case FILEMGR_PBWRITE
:
1866 exit_syscall("PBWrite", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1868 case FILEMGR_PBGETFCBINFO
:
1869 exit_syscall("PBGetFCBInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1871 case FILEMGR_PBSETFINFO
:
1872 exit_syscall("PBSetFInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1874 case FILEMGR_PBALLOCATE
:
1875 exit_syscall("PBAllocate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1877 case FILEMGR_PBALLOCCONTIG
:
1878 exit_syscall("PBAllocContig", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1880 case FILEMGR_PBSETFPOS
:
1881 exit_syscall("PBSetFPos", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1883 case FILEMGR_PBSETCATINFO
:
1884 exit_syscall("PBSetCatInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1886 case FILEMGR_PBGETVOLPARMS
:
1887 exit_syscall("PBGetVolParms", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1889 case FILEMGR_PBSETVINFO
:
1890 exit_syscall("PBSetVInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1892 case FILEMGR_PBMAKEFSSPEC
:
1893 exit_syscall("PBMakeFSSpec", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1895 case FILEMGR_PBHGETVINFO
:
1896 exit_syscall("PBHGetVInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1898 case FILEMGR_PBCREATEFILEIDREF
:
1899 exit_syscall("PBCreateFileIDRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1901 case FILEMGR_PBDELETEFILEIDREF
:
1902 exit_syscall("PBDeleteFileIDRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1904 case FILEMGR_PBRESOLVEFILEIDREF
:
1905 exit_syscall("PBResolveFileIDRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1907 case FILEMGR_PBFLUSHVOL
:
1908 exit_syscall("PBFlushVol", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1910 case FILEMGR_PBHRENAME
:
1911 exit_syscall("PBHRename", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1913 case FILEMGR_PBCATMOVE
:
1914 exit_syscall("PBCatMove", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1916 case FILEMGR_PBEXCHANGEFILES
:
1917 exit_syscall("PBExchangeFiles", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1919 case FILEMGR_PBHDELETE
:
1920 exit_syscall("PBHDelete", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1922 case FILEMGR_PBDIRCREATE
:
1923 exit_syscall("PBDirCreate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1925 case FILEMGR_PBCATSEARCH
:
1926 exit_syscall("PBCatSearch", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1928 case FILEMGR_PBHSETFLOCK
:
1929 exit_syscall("PBHSetFLock", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1931 case FILEMGR_PBHRSTFLOCK
:
1932 exit_syscall("PBHRstFLock", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1934 case FILEMGR_PBLOCKRANGE
:
1935 exit_syscall("PBLockRange", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1937 case FILEMGR_PBUNLOCKRANGE
:
1938 exit_syscall("PBUnlockRange", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1948 enter_syscall(int thread
, int type
, kd_buf
*kd
, char *name
, double now
)
1957 kd_threadmap
*find_thread_map();
1980 case BSC_socketpair
:
1986 case BSC_removexattr
:
1987 case BSC_fremovexattr
:
1989 case BSC_flistxattr
:
1990 case BSC_open_extended
:
1991 case BSC_stat_extended
:
1992 case BSC_lstat_extended
:
1993 case BSC_fstat_extended
:
1994 case BSC_chmod_extended
:
1995 case BSC_fchmod_extended
:
1996 case BSC_access_extended
:
1997 case BSC_mkfifo_extended
:
1998 case BSC_mkdir_extended
:
2000 case BSC_load_shared_file
:
2046 case BSC_getdirentries
:
2054 case BSC_getattrlist
:
2055 case BSC_setattrlist
:
2056 case BSC_getdirentriesattr
:
2057 case BSC_exchangedata
:
2058 case BSC_checkuseraccess
:
2060 case FILEMGR_PBGETCATALOGINFO
:
2061 case FILEMGR_PBGETCATALOGINFOBULK
:
2062 case FILEMGR_PBCREATEFILEUNICODE
:
2063 case FILEMGR_PBCREATEDIRECTORYUNICODE
:
2064 case FILEMGR_PBCREATEFORK
:
2065 case FILEMGR_PBDELETEFORK
:
2066 case FILEMGR_PBITERATEFORK
:
2067 case FILEMGR_PBOPENFORK
:
2068 case FILEMGR_PBREADFORK
:
2069 case FILEMGR_PBWRITEFORK
:
2070 case FILEMGR_PBALLOCATEFORK
:
2071 case FILEMGR_PBDELETEOBJECT
:
2072 case FILEMGR_PBEXCHANGEOBJECT
:
2073 case FILEMGR_PBGETFORKCBINFO
:
2074 case FILEMGR_PBGETVOLUMEINFO
:
2075 case FILEMGR_PBMAKEFSREF
:
2076 case FILEMGR_PBMAKEFSREFUNICODE
:
2077 case FILEMGR_PBMOVEOBJECT
:
2078 case FILEMGR_PBOPENITERATOR
:
2079 case FILEMGR_PBRENAMEUNICODE
:
2080 case FILEMGR_PBSETCATALOGINFO
:
2081 case FILEMGR_PBSETVOLUMEINFO
:
2082 case FILEMGR_FSREFMAKEPATH
:
2083 case FILEMGR_FSPATHMAKEREF
:
2085 case FILEMGR_PBGETCATINFO
:
2086 case FILEMGR_PBGETCATINFOLITE
:
2087 case FILEMGR_PBHGETFINFO
:
2088 case FILEMGR_PBXGETVOLINFO
:
2089 case FILEMGR_PBHCREATE
:
2090 case FILEMGR_PBHOPENDF
:
2091 case FILEMGR_PBHOPENRF
:
2092 case FILEMGR_PBHGETDIRACCESS
:
2093 case FILEMGR_PBHSETDIRACCESS
:
2094 case FILEMGR_PBHMAPID
:
2095 case FILEMGR_PBHMAPNAME
:
2096 case FILEMGR_PBCLOSE
:
2097 case FILEMGR_PBFLUSHFILE
:
2098 case FILEMGR_PBGETEOF
:
2099 case FILEMGR_PBSETEOF
:
2100 case FILEMGR_PBGETFPOS
:
2101 case FILEMGR_PBREAD
:
2102 case FILEMGR_PBWRITE
:
2103 case FILEMGR_PBGETFCBINFO
:
2104 case FILEMGR_PBSETFINFO
:
2105 case FILEMGR_PBALLOCATE
:
2106 case FILEMGR_PBALLOCCONTIG
:
2107 case FILEMGR_PBSETFPOS
:
2108 case FILEMGR_PBSETCATINFO
:
2109 case FILEMGR_PBGETVOLPARMS
:
2110 case FILEMGR_PBSETVINFO
:
2111 case FILEMGR_PBMAKEFSSPEC
:
2112 case FILEMGR_PBHGETVINFO
:
2113 case FILEMGR_PBCREATEFILEIDREF
:
2114 case FILEMGR_PBDELETEFILEIDREF
:
2115 case FILEMGR_PBRESOLVEFILEIDREF
:
2116 case FILEMGR_PBFLUSHVOL
:
2117 case FILEMGR_PBHRENAME
:
2118 case FILEMGR_PBCATMOVE
:
2119 case FILEMGR_PBEXCHANGEFILES
:
2120 case FILEMGR_PBHDELETE
:
2121 case FILEMGR_PBDIRCREATE
:
2122 case FILEMGR_PBCATSEARCH
:
2123 case FILEMGR_PBHSETFLOCK
:
2124 case FILEMGR_PBHRSTFLOCK
:
2125 case FILEMGR_PBLOCKRANGE
:
2126 case FILEMGR_PBUNLOCKRANGE
:
2128 if ((ti
= find_thread(thread
, BSC_execve
))) {
2130 exit_syscall("execve", thread
, BSC_execve
, 0, 0, 0, 0, (double)now
);
2133 for (i
= 0, ti
= th_state
; ti
< &th_state
[MAX_THREADS
]; ti
++, i
++) {
2134 if (ti
->thread
== 0)
2137 if (ti
== &th_state
[MAX_THREADS
])
2142 if ((type
>> 24) == FILEMGR_CLASS
) {
2145 l_usecs
= (long long)(now
/ divisor
);
2146 secs
= l_usecs
/ 1000000;
2147 curr_time
= bias_secs
+ secs
;
2149 sprintf(buf
, "%-8.8s", &(ctime(&curr_time
)[11]));
2150 tsclen
= strlen(buf
);
2152 if (columns
> MAXCOLS
|| wideflag
) {
2153 usecs
= l_usecs
- (long long)((long long)secs
* 1000000);
2154 sprintf(&buf
[tsclen
], ".%03ld", (long)usecs
/ 1000);
2155 tsclen
= strlen(buf
);
2158 /* Print timestamp column */
2161 map
= find_thread_map(thread
);
2163 sprintf(buf
, " %-25.25s ", name
);
2164 nmclen
= strlen(buf
);
2167 sprintf(buf
, "(%d, 0x%x, 0x%x, 0x%x)", (short)kd
->arg1
, kd
->arg2
, kd
->arg3
, kd
->arg4
);
2168 argsclen
= strlen(buf
);
2171 Calculate white space out to command
2173 if (columns
> MAXCOLS
|| wideflag
)
2175 clen
= columns
- (tsclen
+ nmclen
+ argsclen
+ 20);
2178 clen
= columns
- (tsclen
+ nmclen
+ argsclen
+ 12);
2182 printf("%s", buf
); /* print the kdargs */
2183 memset(buf
, ' ', clen
);
2187 else if ((argsclen
+ clen
) > 0)
2189 /* no room so wipe out the kdargs */
2190 memset(buf
, ' ', (argsclen
+ clen
));
2191 buf
[argsclen
+ clen
] = '\0';
2195 if (columns
> MAXCOLS
|| wideflag
)
2196 printf("%-20.20s\n", map
->command
);
2198 printf("%-12.12s\n", map
->command
);
2200 printf(" %-24.24s (%5d, %#x, 0x%x, 0x%x)\n", name
, (short)kd
->arg1
, kd
->arg2
, kd
->arg3
, kd
->arg4
);
2204 ti
->thread
= thread
;
2208 ti
->arg1
= kd
->arg1
;
2209 ti
->arg2
= kd
->arg2
;
2210 ti
->arg3
= kd
->arg3
;
2211 ti
->arg4
= kd
->arg4
;
2212 ti
->pathptr
= (long *)NULL
;
2213 ti
->pathname
[0] = 0;
2223 * Handle system call extended trace data.
2225 * Wipe out the kd args that were collected upon syscall_entry
2226 * because it is the extended info that we really want, and it
2227 * is all we really need.
2231 extend_syscall(int thread
, int type
, kd_buf
*kd
, char *name
, double now
)
2236 case BSC_pread_extended
:
2237 if ((ti
= find_thread(thread
, BSC_pread
)) == (struct th_info
*)0)
2239 ti
->arg1
= kd
->arg1
; /* the fd */
2240 ti
->arg2
= kd
->arg2
; /* nbytes */
2241 ti
->arg3
= kd
->arg3
; /* top half offset */
2242 ti
->arg4
= kd
->arg4
; /* bottom half offset */
2244 case BSC_pwrite_extended
:
2245 if ((ti
= find_thread(thread
, BSC_pwrite
)) == (struct th_info
*)0)
2247 ti
->arg1
= kd
->arg1
; /* the fd */
2248 ti
->arg2
= kd
->arg2
; /* nbytes */
2249 ti
->arg3
= kd
->arg3
; /* top half offset */
2250 ti
->arg4
= kd
->arg4
; /* bottom half offset */
2258 exit_syscall(char *sc_name
, int thread
, int type
, int error
, int retval
,
2259 int has_fd
, int has_ret
, double now
)
2263 if ((ti
= find_thread(thread
, type
)) == (struct th_info
*)0)
2266 if (check_filter_mode(ti
, type
, error
, retval
, sc_name
))
2267 format_print(ti
, sc_name
, thread
, type
, error
, retval
, has_fd
, has_ret
, now
, ti
->stime
, ti
->waited
, (char *)ti
->pathname
, NULL
);
2269 if (ti
== &th_state
[cur_max
- 1])
2277 format_print(struct th_info
*ti
, char *sc_name
, int thread
, int type
, int error
, int retval
,
2278 int has_fd
, int has_ret
, double now
, double stime
, int waited
, char *pathname
, struct diskio
*dio
)
2287 kd_threadmap
*find_thread_map();
2290 char *framework_name
;
2296 command_name
= dio
->issuing_command
;
2298 if ((map
= find_thread_map(thread
)))
2299 command_name
= map
->command
;
2302 l_usecs
= (long long)(now
/ divisor
);
2303 secs
= l_usecs
/ 1000000;
2304 curr_time
= bias_secs
+ secs
;
2305 sprintf(buf
, "%-8.8s", &(ctime(&curr_time
)[11]));
2308 if (columns
> MAXCOLS
|| wideflag
) {
2310 usecs
= l_usecs
- (long long)((long long)secs
* 1000000);
2311 sprintf(&buf
[clen
], ".%03ld", (long)usecs
/ 1000);
2314 if ((type
>> 24) != FILEMGR_CLASS
) {
2315 if (find_thread(thread
, -1)) {
2316 sprintf(&buf
[clen
], " ");
2324 if (((type
>> 24) == FILEMGR_CLASS
) && (columns
> MAXCOLS
|| wideflag
))
2325 sprintf(&buf
[clen
], " %-18.18s", sc_name
);
2327 sprintf(&buf
[clen
], " %-15.15s", sc_name
);
2331 framework_name
= (char *)0;
2333 if (columns
> MAXCOLS
|| wideflag
) {
2335 sprintf(&buf
[clen
], " D=0x%8.8x", dio
->blkno
);
2340 sprintf(&buf
[clen
], " [%3d] ", dio
->io_errno
);
2342 sprintf(&buf
[clen
], " B=0x%-6x /dev/%s", dio
->iosize
, find_disk_name(dio
->dev
));
2345 off_t offset_reassembled
= 0LL;
2347 if (has_fd
== 2 && error
== 0)
2348 sprintf(&buf
[clen
], " F=%-3d", retval
);
2349 else if (has_fd
== 1)
2350 sprintf(&buf
[clen
], " F=%-3d", ti
->arg1
);
2351 else if (has_ret
!= 2 && has_ret
!= 6)
2352 sprintf(&buf
[clen
], " ");
2356 if (has_ret
== 2 || has_ret
== 6)
2357 framework_name
= lookup_name(retval
);
2359 if (error
&& has_ret
!= 6)
2360 sprintf(&buf
[clen
], "[%3d] ", error
);
2361 else if (has_ret
== 3)
2362 sprintf(&buf
[clen
], "O=0x%8.8x", ti
->arg3
);
2363 else if (has_ret
== 5)
2364 sprintf(&buf
[clen
], "O=0x%8.8x", retval
);
2365 else if (has_ret
== 2)
2366 sprintf(&buf
[clen
], " A=0x%8.8x ", retval
);
2367 else if (has_ret
== 6)
2368 sprintf(&buf
[clen
], " A=0x%8.8x B=0x%-8x", retval
, error
);
2369 else if (has_ret
== 1)
2370 sprintf(&buf
[clen
], " B=0x%-6x", retval
);
2371 else if (has_ret
== 4)
2372 sprintf(&buf
[clen
], "B=0x%-8x", retval
);
2373 else if (has_ret
== 8) /* BSC_select */
2374 sprintf(&buf
[clen
], " S=%-3d ", retval
);
2375 else if (has_ret
== 9) /* BSC_pread, BSC_pwrite */
2377 sprintf(&buf
[clen
], "B=0x%-8x", retval
);
2379 offset_reassembled
= (((off_t
)(unsigned int)(ti
->arg3
)) << 32) | (unsigned int)(ti
->arg4
);
2380 if ((offset_reassembled
>> 32) != 0)
2381 sprintf(&buf
[clen
], "O=0x%16.16qx", (off_t
)offset_reassembled
);
2383 sprintf(&buf
[clen
], "O=0x%8.8qx", (off_t
)offset_reassembled
);
2386 sprintf(&buf
[clen
], " ");
2393 Calculate space available to print pathname
2395 if (columns
> MAXCOLS
|| wideflag
)
2396 clen
= columns
- (clen
+ 13 + 20);
2398 clen
= columns
- (clen
+ 13 + 12);
2400 if ((type
>> 24) != FILEMGR_CLASS
&& !nopadding
)
2404 sprintf(&buf
[0], " %s ", framework_name
);
2406 sprintf(&buf
[0], " %s ", pathname
);
2412 Add null padding if column length
2413 is wider than the pathname length.
2415 memset(&buf
[len
], ' ', clen
- len
);
2419 else if (clen
== len
)
2423 else if ((clen
> 0) && (clen
< len
))
2425 /* This prints the tail end of the pathname */
2426 buf
[len
-clen
] = ' ';
2427 printf("%s", &buf
[len
- clen
]);
2430 usecs
= (unsigned long)((now
- stime
) / divisor
);
2431 secs
= usecs
/ 1000000;
2432 usecs
-= secs
* 1000000;
2434 if ((type
>> 24) != FILEMGR_CLASS
&& !nopadding
)
2437 printf(" %2ld.%06ld", (unsigned long)secs
, (unsigned long)usecs
);
2444 if (columns
> MAXCOLS
|| wideflag
)
2445 printf(" %-20.20s", command_name
);
2447 printf(" %-12.12s", command_name
);
2461 This flag is turned off when calling
2462 quit() due to a set_remove() failure.
2464 if (set_remove_flag
)
2467 fprintf(stderr
, "fs_usage: ");
2469 fprintf(stderr
, "%s", s
);
2477 struct mach_timebase_info mti
;
2479 mach_timebase_info(&mti
);
2481 divisor
= ((double)mti
.denom
/ (double)mti
.numer
) * 1000;
2485 void read_command_map()
2489 int prev_total_threads
;
2497 prev_total_threads
= total_threads
;
2498 total_threads
= bufinfo
.nkdthreads
;
2499 size
= bufinfo
.nkdthreads
* sizeof(kd_threadmap
);
2503 if ((mapptr
= (kd_threadmap
*) malloc(size
)))
2505 bzero (mapptr
, size
);
2507 /* Now read the threadmap */
2509 mib
[1] = KERN_KDEBUG
;
2510 mib
[2] = KERN_KDTHRMAP
;
2513 mib
[5] = 0; /* no flags */
2514 if (sysctl(mib
, 3, mapptr
, &size
, NULL
, 0) < 0)
2516 /* This is not fatal -- just means I cant map command strings */
2523 if (mapptr
&& (filter_mode
& (NETWORK_FILTER
| FILESYS_FILTER
)))
2527 /* We accept the fact that we lose file descriptor state if the
2529 for (i
= 0; i
< prev_total_threads
; i
++)
2531 if (fdmapptr
[i
].fd_setptr
)
2532 free (fdmapptr
[i
].fd_setptr
);
2538 size
= total_threads
* sizeof(fd_threadmap
);
2539 if ((fdmapptr
= (fd_threadmap
*) malloc(size
)))
2541 bzero (fdmapptr
, size
);
2542 /* reinitialize file descriptor state map */
2543 for (i
= 0; i
< total_threads
; i
++)
2545 fdmapptr
[i
].fd_thread
= mapptr
[i
].thread
;
2546 fdmapptr
[i
].fd_valid
= mapptr
[i
].valid
;
2547 fdmapptr
[i
].fd_setsize
= 0;
2548 fdmapptr
[i
].fd_setptr
= 0;
2553 /* Resolve any LaunchCFMApp command names */
2554 if (mapptr
&& arguments
)
2556 for (i
=0; i
< total_threads
; i
++)
2560 pid
= mapptr
[i
].valid
;
2562 if (pid
== 0 || pid
== 1)
2564 else if (!strncmp(mapptr
[i
].command
,"LaunchCFMA", 10))
2566 (void)get_real_command_name(pid
, mapptr
[i
].command
, sizeof(mapptr
[i
].command
));
2573 void create_map_entry(int thread
, int pid
, char *command
)
2577 fd_threadmap
*fdmap
= 0;
2582 for (i
= 0, map
= 0; !map
&& i
< total_threads
; i
++)
2584 if ((int)mapptr
[i
].thread
== thread
)
2586 map
= &mapptr
[i
]; /* Reuse this entry, the thread has been
2588 if ((filter_mode
& (NETWORK_FILTER
| FILESYS_FILTER
)) && fdmapptr
)
2590 fdmap
= &fdmapptr
[i
];
2591 if (fdmap
->fd_thread
!= thread
) /* This shouldn't happen */
2592 fdmap
= (fd_threadmap
*)0;
2597 if (!map
) /* look for invalid entries that I can reuse*/
2599 for (i
= 0, map
= 0; !map
&& i
< total_threads
; i
++)
2601 if (mapptr
[i
].valid
== 0 )
2602 map
= &mapptr
[i
]; /* Reuse this invalid entry */
2603 if ((filter_mode
& (NETWORK_FILTER
| FILESYS_FILTER
)) && fdmapptr
)
2605 fdmap
= &fdmapptr
[i
];
2612 /* If reach here, then this is a new thread and
2613 * there are no invalid entries to reuse
2614 * Double the size of the thread map table.
2617 n
= total_threads
* 2;
2618 mapptr
= (kd_threadmap
*) realloc(mapptr
, n
* sizeof(kd_threadmap
));
2619 bzero(&mapptr
[total_threads
], total_threads
*sizeof(kd_threadmap
));
2620 map
= &mapptr
[total_threads
];
2622 if ((filter_mode
& (NETWORK_FILTER
| FILESYS_FILTER
)) && fdmapptr
)
2624 fdmapptr
= (fd_threadmap
*)realloc(fdmapptr
, n
* sizeof(fd_threadmap
));
2625 bzero(&fdmapptr
[total_threads
], total_threads
*sizeof(fd_threadmap
));
2626 fdmap
= &fdmapptr
[total_threads
];
2633 map
->thread
= thread
;
2635 The trace entry that returns the command name will hold
2636 at most, MAXCOMLEN chars, and in that case, is not
2637 guaranteed to be null terminated.
2639 (void)strncpy (map
->command
, command
, MAXCOMLEN
);
2640 map
->command
[MAXCOMLEN
] = '\0';
2644 fdmap
->fd_valid
= 1;
2645 fdmap
->fd_thread
= thread
;
2646 if (fdmap
->fd_setptr
)
2648 free(fdmap
->fd_setptr
);
2649 fdmap
->fd_setptr
= (unsigned long *)0;
2651 fdmap
->fd_setsize
= 0;
2654 if (pid
== 0 || pid
== 1)
2656 else if (!strncmp(map
->command
, "LaunchCFMA", 10))
2657 (void)get_real_command_name(pid
, map
->command
, sizeof(map
->command
));
2661 kd_threadmap
*find_thread_map(int thread
)
2667 return((kd_threadmap
*)0);
2669 for (i
= 0; i
< total_threads
; i
++)
2672 if (map
->valid
&& ((int)map
->thread
== thread
))
2677 return ((kd_threadmap
*)0);
2680 fd_threadmap
*find_fd_thread_map(int thread
)
2683 fd_threadmap
*fdmap
= 0;
2686 return((fd_threadmap
*)0);
2688 for (i
= 0; i
< total_threads
; i
++)
2690 fdmap
= &fdmapptr
[i
];
2691 if (fdmap
->fd_valid
&& ((int)fdmap
->fd_thread
== thread
))
2696 return ((fd_threadmap
*)0);
2701 kill_thread_map(int thread
)
2704 fd_threadmap
*fdmap
;
2706 if ((map
= find_thread_map(thread
))) {
2709 map
->command
[0] = '\0';
2712 if ((filter_mode
& (NETWORK_FILTER
| FILESYS_FILTER
)))
2714 if ((fdmap
= find_fd_thread_map(thread
)))
2716 fdmap
->fd_valid
= 0;
2717 fdmap
->fd_thread
= 0;
2718 if (fdmap
->fd_setptr
)
2720 free (fdmap
->fd_setptr
);
2721 fdmap
->fd_setptr
= (unsigned long *)0;
2723 fdmap
->fd_setsize
= 0;
2736 ret
= (int)strtol(str
, &cp
, 10);
2737 if (cp
== str
|| *cp
) {
2738 /* Assume this is a command string and find matching pids */
2742 for (i
=0; i
< kp_nentries
&& num_of_pids
< (MAX_PIDS
- 1); i
++) {
2743 if(kp_buffer
[i
].kp_proc
.p_stat
== 0)
2746 if(!strcmp(str
, kp_buffer
[i
].kp_proc
.p_comm
))
2747 pids
[num_of_pids
++] = kp_buffer
[i
].kp_proc
.p_pid
;
2751 else if (num_of_pids
< (MAX_PIDS
- 1))
2752 pids
[num_of_pids
++] = ret
;
2759 char *lookup_name(unsigned long addr
)
2762 register int start
, last
;
2765 if (numFrameworks
== 0 || addr
< frameworkInfo
[0].address
|| addr
> frameworkInfo
[numFrameworks
].address
)
2769 last
= numFrameworks
;
2771 for (i
= numFrameworks
/ 2; i
>= 0 && i
< numFrameworks
; ) {
2773 if (addr
>= frameworkInfo
[i
].address
&& addr
< frameworkInfo
[i
+1].address
)
2774 return(frameworkInfo
[i
].name
);
2776 if (addr
>= frameworkInfo
[i
].address
) {
2778 i
= start
+ ((last
- i
) / 2);
2781 i
= start
+ ((i
- start
) / 2);
2789 * Comparison routines for sorting
2791 static int compareFrameworkAddress(const void *aa
, const void *bb
)
2793 LibraryInfo
*a
= (LibraryInfo
*)aa
;
2794 LibraryInfo
*b
= (LibraryInfo
*)bb
;
2796 if (a
->address
< b
->address
) return -1;
2797 if (a
->address
== b
->address
) return 0;
2802 int scanline(char *inputstring
,char **argv
)
2805 char **ap
= argv
, *p
, *val
;
2807 for (p
= inputstring
; p
!= NULL
; )
2809 while ((val
= strsep(&p
, " \t")) != NULL
&& *val
== '\0');
2818 int ReadSegAddrTable()
2823 unsigned long frameworkAddress
, frameworkDataAddress
, previousFrameworkAddress
;
2824 char frameworkName
[256];
2827 char *substring
,*ptr
;
2831 bzero(buf
, sizeof(buf
));
2832 bzero(tokens
, sizeof(tokens
));
2836 if ((fd
= fopen(seg_addr_table
, "r")) == 0)
2840 fgets(buf
, 1023, fd
);
2845 frameworkName
[0] = 0;
2846 previousFrameworkAddress
= 0;
2848 while (fgets(buf
, 1023, fd
) && numFrameworks
< (MAXINDEX
- 2))
2853 buf
[strlen(buf
)-1] = 0;
2855 if (strncmp(buf
, "# dyld:", 7) == 0) {
2857 * the next line in the file will contain info about dyld
2863 * This is a split library line: parse it into 3 tokens
2865 ntokens
= scanline(buf
, tokens
);
2870 frameworkAddress
= strtoul(tokens
[0], 0, 16);
2871 frameworkDataAddress
= strtoul(tokens
[1], 0, 16);
2875 * dyld entry is of a different form from the std split library
2876 * it consists of a base address and a size instead of a code
2877 * and data base address
2879 frameworkInfo
[numFrameworks
].address
= frameworkAddress
;
2880 frameworkInfo
[numFrameworks
+1].address
= frameworkAddress
+ frameworkDataAddress
;
2882 frameworkInfo
[numFrameworks
].name
= (char *)"dylib";
2883 frameworkInfo
[numFrameworks
+1].name
= (char *)0;
2892 * Make sure that we have 2 addresses and a path
2894 if (!frameworkAddress
)
2896 if (!frameworkDataAddress
)
2898 if (*tokens
[2] != '/')
2900 if (frameworkAddress
== previousFrameworkAddress
)
2902 previousFrameworkAddress
= frameworkAddress
;
2905 * Extract lib name from path name
2907 if ((substring
= strrchr(tokens
[2], '.')))
2910 * There is a ".": name is whatever is between the "/" around the "."
2912 while ( *substring
!= '/') { /* find "/" before "." */
2916 strcpy(frameworkName
, substring
); /* copy path from "/" */
2917 substring
= frameworkName
;
2919 while ( *substring
!= '/' && *substring
) /* find "/" after "." and stop string there */
2926 * No ".": take segment after last "/"
2934 substring
= ptr
+ 1;
2937 strcpy(frameworkName
, substring
);
2939 frameworkInfo
[numFrameworks
].address
= frameworkAddress
;
2940 frameworkInfo
[numFrameworks
+1].address
= frameworkDataAddress
;
2942 frameworkInfo
[numFrameworks
].name
= (char *)malloc(strlen(frameworkName
) + 1);
2943 strcpy(frameworkInfo
[numFrameworks
].name
, frameworkName
);
2944 frameworkInfo
[numFrameworks
+1].name
= frameworkInfo
[numFrameworks
].name
;
2949 frameworkInfo
[numFrameworks
].address
= frameworkInfo
[numFrameworks
- 1].address
+ 0x800000;
2950 frameworkInfo
[numFrameworks
].name
= (char *)0;
2954 qsort(frameworkInfo
, numFrameworks
, sizeof(LibraryInfo
), compareFrameworkAddress
);
2960 struct diskio
*insert_diskio(int type
, int bp
, int dev
, int blkno
, int io_size
, int thread
, double curtime
)
2962 register struct diskio
*dio
;
2963 register kd_threadmap
*map
;
2965 if ((dio
= free_diskios
))
2966 free_diskios
= dio
->next
;
2968 if ((dio
= (struct diskio
*)malloc(sizeof(struct diskio
))) == NULL
)
2977 dio
->iosize
= io_size
;
2978 dio
->issued_time
= curtime
;
2979 dio
->issuing_thread
= thread
;
2981 if ((map
= find_thread_map(thread
)))
2983 strncpy(dio
->issuing_command
, map
->command
, MAXCOMLEN
);
2984 dio
->issuing_command
[MAXCOMLEN
-1] = '\0';
2987 strcpy(dio
->issuing_command
, "");
2989 dio
->next
= busy_diskios
;
2991 dio
->next
->prev
= dio
;
2998 struct diskio
*complete_diskio(int bp
, int io_errno
, int resid
, int thread
, double curtime
)
3000 register struct diskio
*dio
;
3002 for (dio
= busy_diskios
; dio
; dio
= dio
->next
) {
3003 if (dio
->bp
== bp
) {
3005 if (dio
== busy_diskios
) {
3006 if ((busy_diskios
= dio
->next
))
3007 dio
->next
->prev
= NULL
;
3010 dio
->next
->prev
= dio
->prev
;
3011 dio
->prev
->next
= dio
->next
;
3013 dio
->iosize
-= resid
;
3014 dio
->io_errno
= io_errno
;
3015 dio
->completed_time
= curtime
;
3016 dio
->completion_thread
= thread
;
3021 return ((struct diskio
*)0);
3025 void free_diskio(struct diskio
*dio
)
3027 dio
->next
= free_diskios
;
3032 void print_diskio(struct diskio
*dio
)
3036 switch (dio
->type
) {
3057 p
= " RdMeta[async]";
3060 p
= " WrMeta[async]";
3063 p
= " RdData[async]";
3066 p
= " WrData[async]";
3072 p
= " PgOut[async]";
3078 if (check_filter_mode(NULL
, dio
->type
,0, 0, p
))
3079 format_print(NULL
, p
, dio
->issuing_thread
, dio
->type
, 0, 0, 0, 7, dio
->completed_time
, dio
->issued_time
, 1, "", dio
);
3083 void cache_disk_names()
3088 struct diskrec
*dnp
;
3091 if ((dirp
= opendir("/dev")) == NULL
)
3094 while ((dir
= readdir(dirp
)) != NULL
) {
3095 char nbuf
[MAXPATHLEN
];
3097 if (dir
->d_namlen
< 5 || strncmp("disk", dir
->d_name
, 4))
3099 sprintf(nbuf
, "%s/%s", "/dev", dir
->d_name
);
3101 if (stat(nbuf
, &st
) < 0)
3104 if ((dnp
= (struct diskrec
*)malloc(sizeof(struct diskrec
))) == NULL
)
3107 if ((dnp
->diskname
= (char *)malloc(dir
->d_namlen
+ 1)) == NULL
) {
3111 strncpy(dnp
->diskname
, dir
->d_name
, dir
->d_namlen
);
3112 dnp
->diskname
[dir
->d_namlen
] = 0;
3113 dnp
->dev
= st
.st_rdev
;
3115 dnp
->next
= disk_list
;
3118 (void) closedir(dirp
);
3122 char *find_disk_name(int dev
)
3124 struct diskrec
*dnp
;
3129 for (dnp
= disk_list
; dnp
; dnp
= dnp
->next
) {
3130 if (dnp
->dev
== dev
)
3131 return (dnp
->diskname
);
3133 return ("NOTFOUND");
3137 fs_usage_fd_set(thread
, fd
)
3138 unsigned int thread
;
3142 fd_threadmap
*fdmap
;
3144 if(!(fdmap
= find_fd_thread_map(thread
)))
3147 /* If the map is not allocated, then now is the time */
3148 if (fdmap
->fd_setptr
== (unsigned long *)0)
3150 fdmap
->fd_setptr
= (unsigned long *)malloc(FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE
));
3151 if (fdmap
->fd_setptr
)
3153 fdmap
->fd_setsize
= FS_USAGE_FD_SETSIZE
;
3154 bzero(fdmap
->fd_setptr
,(FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE
)));
3160 /* If the map is not big enough, then reallocate it */
3161 while (fdmap
->fd_setsize
< fd
)
3163 fprintf(stderr
, "reallocating bitmap for threadid %d, fd = %d, setsize = %d\n",
3164 thread
, fd
, fdmap
->fd_setsize
);
3165 n
= fdmap
->fd_setsize
* 2;
3166 fdmap
->fd_setptr
= (unsigned long *)realloc(fdmap
->fd_setptr
, (FS_USAGE_NFDBYTES(n
)));
3167 bzero(&fdmap
->fd_setptr
[(fdmap
->fd_setsize
/FS_USAGE_NFDBITS
)], (FS_USAGE_NFDBYTES(fdmap
->fd_setsize
)));
3168 fdmap
->fd_setsize
= n
;
3172 fdmap
->fd_setptr
[fd
/FS_USAGE_NFDBITS
] |= (1 << ((fd
) % FS_USAGE_NFDBITS
));
3179 0 : File Descriptor bit is not set
3180 1 : File Descriptor bit is set
3184 fs_usage_fd_isset(thread
, fd
)
3185 unsigned int thread
;
3189 fd_threadmap
*fdmap
;
3191 if(!(fdmap
= find_fd_thread_map(thread
)))
3194 if (fdmap
->fd_setptr
== (unsigned long *)0)
3197 if (fd
< fdmap
->fd_setsize
)
3198 ret
= fdmap
->fd_setptr
[fd
/FS_USAGE_NFDBITS
] & (1 << (fd
% FS_USAGE_NFDBITS
));
3204 fs_usage_fd_clear(thread
, fd
)
3205 unsigned int thread
;
3210 if (!(map
= find_fd_thread_map(thread
)))
3213 if (map
->fd_setptr
== (unsigned long *)0)
3217 if (fd
< map
->fd_setsize
)
3218 map
->fd_setptr
[fd
/FS_USAGE_NFDBITS
] &= ~(1 << (fd
% FS_USAGE_NFDBITS
));
3225 * ret = 1 means print the entry
3226 * ret = 0 means don't print the entry
3229 check_filter_mode(struct th_info
* ti
, int type
, int error
, int retval
, char *sc_name
)
3232 int network_fd_isset
= 0;
3235 if (filter_mode
== DEFAULT_DO_NOT_FILTER
)
3238 if (!strcmp (sc_name
, "CACHE_HIT")) {
3239 if (filter_mode
& CACHEHIT_FILTER
)
3240 /* Do not print if cachehit filter is set */
3245 if (filter_mode
& EXEC_FILTER
)
3247 if (!strcmp (sc_name
, "execve"))
3251 if ( !(filter_mode
& (FILESYS_FILTER
| NETWORK_FILTER
)))
3255 if (ti
== (struct th_info
*)0)
3257 if(filter_mode
& FILESYS_FILTER
)
3267 network_fd_isset
= fs_usage_fd_isset(ti
->thread
, fd
);
3270 fs_usage_fd_clear(ti
->thread
,fd
);
3273 if (network_fd_isset
)
3275 if (filter_mode
& NETWORK_FILTER
)
3278 else if (filter_mode
& FILESYS_FILTER
)
3283 /* we don't care about error in this case */
3285 network_fd_isset
= fs_usage_fd_isset(ti
->thread
, fd
);
3286 if (network_fd_isset
)
3288 if (filter_mode
& NETWORK_FILTER
)
3291 else if (filter_mode
& FILESYS_FILTER
)
3298 fs_usage_fd_set(ti
->thread
, fd
);
3299 if (filter_mode
& NETWORK_FILTER
)
3311 fs_usage_fd_set(ti
->thread
, fd
);
3312 if (filter_mode
& NETWORK_FILTER
)
3316 case BSC_socketpair
:
3317 /* Cannot determine info about file descriptors */
3318 if (filter_mode
& NETWORK_FILTER
)
3323 ret
=0; /* We track these cases for fd state only */
3324 fd
= ti
->arg1
; /* oldd */
3325 network_fd_isset
= fs_usage_fd_isset(ti
->thread
, fd
);
3326 if (error
== 0 && network_fd_isset
)
3328 /* then we are duping a socket descriptor */
3329 fd
= retval
; /* the new fd */
3330 fs_usage_fd_set(ti
->thread
, fd
);
3335 if (filter_mode
& FILESYS_FILTER
)
3344 * Allocate a buffer that is large enough to hold the maximum arguments
3345 * to execve(). This is used when getting the arguments to programs
3346 * when we see LaunchCFMApps. If this fails, it is not fatal, we will
3347 * simply not resolve the command name.
3351 init_arguments_buffer()
3358 mib
[1] = KERN_ARGMAX
;
3359 size
= sizeof(argmax
);
3360 if (sysctl(mib
, 2, &argmax
, &size
, NULL
, 0) == -1)
3364 /* Hack to avoid kernel bug. */
3365 if (argmax
> 8192) {
3370 arguments
= (char *)malloc(argmax
);
3377 get_real_command_name(int pid
, char *cbuf
, int csize
)
3380 * Get command and arguments.
3384 char *command_beg
, *command
, *command_end
;
3391 bzero(arguments
, argmax
);
3396 * A sysctl() is made to find out the full path that the command
3400 mib
[1] = KERN_PROCARGS
;
3404 if (sysctl(mib
, 3, arguments
, (size_t *)&argmax
, NULL
, 0) < 0) {
3408 /* Skip the saved exec_path. */
3409 for (cp
= arguments
; cp
< &arguments
[argmax
]; cp
++) {
3411 /* End of exec_path reached. */
3415 if (cp
== &arguments
[argmax
]) {
3419 /* Skip trailing '\0' characters. */
3420 for (; cp
< &arguments
[argmax
]; cp
++) {
3422 /* Beginning of first argument reached. */
3426 if (cp
== &arguments
[argmax
]) {
3432 * Make sure that the command is '\0'-terminated. This protects
3433 * against malicious programs; under normal operation this never
3434 * ends up being a problem..
3436 for (; cp
< &arguments
[argmax
]; cp
++) {
3438 /* End of first argument reached. */
3442 if (cp
== &arguments
[argmax
]) {
3445 command_end
= command
= cp
;
3447 /* Get the basename of command. */
3448 for (command
--; command
>= command_beg
; command
--) {
3449 if (*command
== '/') {
3455 (void) strncpy(cbuf
, (char *)command
, csize
);
3456 cbuf
[csize
-1] = '\0';