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. -DKERNEL_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>
67 typedef struct LibraryInfo
{
68 unsigned long address
;
72 LibraryInfo frameworkInfo
[MAXINDEX
];
73 int numFrameworks
= 0;
75 char seg_addr_table
[256]="/AppleInternal/Developer/seg_addr_table";
81 MAXCOLS controls when extra data kicks in.
82 MAX_WIDE_MODE_COLS controls -w mode to get even wider data in path.
83 If NUMPARMS changes to match the kernel, it will automatically
84 get reflected in the -w mode output.
87 #define PATHLENGTH (NUMPARMS*sizeof(long))
89 #define MAX_WIDE_MODE_COLS (PATHLENGTH + 80)
104 char pathname
[PATHLENGTH
+ 1]; /* add room for null terminator */
107 #define MAX_THREADS 512
108 struct th_info th_state
[MAX_THREADS
];
112 int need_new_map
= 1;
116 int select_pid_mode
= 0; /* Flag set indicates that output is restricted
117 to selected pids or commands */
119 int one_good_pid
= 0; /* Used to fail gracefully when bad pids given */
125 * Network only or filesystem only output filter
126 * Default of zero means report all activity - no filtering
128 #define FILESYS_FILTER 0x01
129 #define NETWORK_FILTER 0x02
130 #define DEFAULT_DO_NOT_FILTER 0x0
131 int filter_mode
= DEFAULT_DO_NOT_FILTER
;
136 struct diskrec
*next
;
151 int completion_thread
;
152 char issuing_command
[MAXCOMLEN
];
154 double completed_time
;
157 struct diskrec
*disk_list
= NULL
;
158 struct diskio
*free_diskios
= NULL
;
159 struct diskio
*busy_diskios
= NULL
;
161 struct diskio
*insert_diskio();
162 struct diskio
*complete_diskio();
166 char *find_disk_name();
167 void cache_disk_names();
168 int ReadSegAddrTable();
169 void mark_thread_waited(int);
170 int check_filter_mode(struct th_info
*, int, int, int);
171 void fs_usage_fd_set(unsigned int, unsigned int);
172 int fs_usage_fd_isset(unsigned int, unsigned int);
173 void fs_usage_fd_clear(unsigned int, unsigned int);
174 void init_arguments_buffer();
175 int get_real_command_name(int, char *, int);
176 void create_map_entry(int, int, char *);
178 #define DBG_ZERO_FILL_FAULT 1
179 #define DBG_PAGEIN_FAULT 2
180 #define DBG_COW_FAULT 3
181 #define DBG_CACHE_HIT_FAULT 4
183 #define TRACE_DATA_NEWTHREAD 0x07000004
184 #define TRACE_DATA_EXEC 0x07000008
185 #define TRACE_STRING_NEWTHREAD 0x07010004
186 #define TRACE_STRING_EXEC 0x07010008
188 #define MACH_vmfault 0x01300000
189 #define MACH_pageout 0x01300004
190 #define MACH_sched 0x01400000
191 #define MACH_stkhandoff 0x01400008
192 #define VFS_LOOKUP 0x03010090
193 #define BSC_exit 0x040C0004
195 #define P_WrData 0x03020000
196 #define P_RdData 0x03020008
197 #define P_WrMeta 0x03020020
198 #define P_RdMeta 0x03020028
199 #define P_PgOut 0x03020040
200 #define P_PgIn 0x03020048
201 #define P_WrDataAsync 0x03020010
202 #define P_RdDataAsync 0x03020018
203 #define P_WrMetaAsync 0x03020030
204 #define P_RdMetaAsync 0x03020038
205 #define P_PgOutAsync 0x03020050
206 #define P_PgInAsync 0x03020058
208 #define P_WrDataDone 0x03020004
209 #define P_RdDataDone 0x0302000C
210 #define P_WrMetaDone 0x03020024
211 #define P_RdMetaDone 0x0302002C
212 #define P_PgOutDone 0x03020044
213 #define P_PgInDone 0x0302004C
214 #define P_WrDataAsyncDone 0x03020014
215 #define P_RdDataAsyncDone 0x0302001C
216 #define P_WrMetaAsyncDone 0x03020034
217 #define P_RdMetaAsyncDone 0x0302003C
218 #define P_PgOutAsyncDone 0x03020054
219 #define P_PgInAsyncDone 0x0302005C
222 #define MSC_map_fd 0x010c00ac
224 // Network related codes
225 #define BSC_recvmsg 0x040C006C
226 #define BSC_sendmsg 0x040C0070
227 #define BSC_recvfrom 0x040C0074
228 #define BSC_accept 0x040C0078
229 #define BSC_select 0x040C0174
230 #define BSC_socket 0x040C0184
231 #define BSC_connect 0x040C0188
232 #define BSC_bind 0x040C01A0
233 #define BSC_listen 0x040C01A8
234 #define BSC_sendto 0x040C0214
235 #define BSC_socketpair 0x040C021C
237 #define BSC_read 0x040C000C
238 #define BSC_write 0x040C0010
239 #define BSC_open 0x040C0014
240 #define BSC_close 0x040C0018
241 #define BSC_link 0x040C0024
242 #define BSC_unlink 0x040C0028
243 #define BSC_chdir 0x040c0030
244 #define BSC_fchdir 0x040c0034
245 #define BSC_mknod 0x040C0038
246 #define BSC_chmod 0x040C003C
247 #define BSC_chown 0x040C0040
248 #define BSC_access 0x040C0084
249 #define BSC_chflags 0x040C0088
250 #define BSC_fchflags 0x040C008C
251 #define BSC_sync 0x040C0090
252 #define BSC_dup 0x040C00A4
253 #define BSC_revoke 0x040C00E0
254 #define BSC_symlink 0x040C00E4
255 #define BSC_readlink 0x040C00E8
256 #define BSC_chroot 0x040C00F4
257 #define BSC_dup2 0x040C0168
258 #define BSC_fsync 0x040C017C
259 #define BSC_readv 0x040C01E0
260 #define BSC_writev 0x040C01E4
261 #define BSC_fchown 0x040C01EC
262 #define BSC_fchmod 0x040C01F0
263 #define BSC_rename 0x040C0200
264 #define BSC_mkfifo 0x040c0210
265 #define BSC_mkdir 0x040C0220
266 #define BSC_rmdir 0x040C0224
267 #define BSC_utimes 0x040C0228
268 #define BSC_futimes 0x040C022C
269 #define BSC_pread 0x040C0264
270 #define BSC_pread_extended 0x040E0264
271 #define BSC_pwrite 0x040C0268
272 #define BSC_pwrite_extended 0x040E0268
273 #define BSC_statfs 0x040C0274
274 #define BSC_fstatfs 0x040C0278
275 #define BSC_stat 0x040C02F0
276 #define BSC_fstat 0x040C02F4
277 #define BSC_lstat 0x040C02F8
278 #define BSC_pathconf 0x040C02FC
279 #define BSC_fpathconf 0x040C0300
280 #define BSC_getdirentries 0x040C0310
281 #define BSC_mmap 0x040c0314
282 #define BSC_lseek 0x040c031c
283 #define BSC_truncate 0x040C0320
284 #define BSC_ftruncate 0x040C0324
285 #define BSC_undelete 0x040C0334
286 #define BSC_statv 0x040C0364
287 #define BSC_lstatv 0x040C0368
288 #define BSC_fstatv 0x040C036C
289 #define BSC_mkcomplex 0x040C0360
290 #define BSC_getattrlist 0x040C0370
291 #define BSC_setattrlist 0x040C0374
292 #define BSC_getdirentriesattr 0x040C0378
293 #define BSC_exchangedata 0x040C037C
294 #define BSC_checkuseraccess 0x040C0380
295 #define BSC_searchfs 0x040C0384
296 #define BSC_delete 0x040C0388
297 #define BSC_copyfile 0x040C038C
298 #define BSC_fsctl 0x040C03C8
299 #define BSC_load_shared_file 0x040C04A0
301 // Carbon File Manager support
302 #define FILEMGR_PBGETCATALOGINFO 0x1e000020
303 #define FILEMGR_PBGETCATALOGINFOBULK 0x1e000024
304 #define FILEMGR_PBCREATEFILEUNICODE 0x1e000028
305 #define FILEMGR_PBCREATEDIRECTORYUNICODE 0x1e00002c
306 #define FILEMGR_PBCREATEFORK 0x1e000030
307 #define FILEMGR_PBDELETEFORK 0x1e000034
308 #define FILEMGR_PBITERATEFORK 0x1e000038
309 #define FILEMGR_PBOPENFORK 0x1e00003c
310 #define FILEMGR_PBREADFORK 0x1e000040
311 #define FILEMGR_PBWRITEFORK 0x1e000044
312 #define FILEMGR_PBALLOCATEFORK 0x1e000048
313 #define FILEMGR_PBDELETEOBJECT 0x1e00004c
314 #define FILEMGR_PBEXCHANGEOBJECT 0x1e000050
315 #define FILEMGR_PBGETFORKCBINFO 0x1e000054
316 #define FILEMGR_PBGETVOLUMEINFO 0x1e000058
317 #define FILEMGR_PBMAKEFSREF 0x1e00005c
318 #define FILEMGR_PBMAKEFSREFUNICODE 0x1e000060
319 #define FILEMGR_PBMOVEOBJECT 0x1e000064
320 #define FILEMGR_PBOPENITERATOR 0x1e000068
321 #define FILEMGR_PBRENAMEUNICODE 0x1e00006c
322 #define FILEMGR_PBSETCATALOGINFO 0x1e000070
323 #define FILEMGR_PBSETVOLUMEINFO 0x1e000074
324 #define FILEMGR_FSREFMAKEPATH 0x1e000078
325 #define FILEMGR_FSPATHMAKEREF 0x1e00007c
327 #define FILEMGR_PBGETCATINFO 0x1e010000
328 #define FILEMGR_PBGETCATINFOLITE 0x1e010004
329 #define FILEMGR_PBHGETFINFO 0x1e010008
330 #define FILEMGR_PBXGETVOLINFO 0x1e01000c
331 #define FILEMGR_PBHCREATE 0x1e010010
332 #define FILEMGR_PBHOPENDF 0x1e010014
333 #define FILEMGR_PBHOPENRF 0x1e010018
334 #define FILEMGR_PBHGETDIRACCESS 0x1e01001c
335 #define FILEMGR_PBHSETDIRACCESS 0x1e010020
336 #define FILEMGR_PBHMAPID 0x1e010024
337 #define FILEMGR_PBHMAPNAME 0x1e010028
338 #define FILEMGR_PBCLOSE 0x1e01002c
339 #define FILEMGR_PBFLUSHFILE 0x1e010030
340 #define FILEMGR_PBGETEOF 0x1e010034
341 #define FILEMGR_PBSETEOF 0x1e010038
342 #define FILEMGR_PBGETFPOS 0x1e01003c
343 #define FILEMGR_PBREAD 0x1e010040
344 #define FILEMGR_PBWRITE 0x1e010044
345 #define FILEMGR_PBGETFCBINFO 0x1e010048
346 #define FILEMGR_PBSETFINFO 0x1e01004c
347 #define FILEMGR_PBALLOCATE 0x1e010050
348 #define FILEMGR_PBALLOCCONTIG 0x1e010054
349 #define FILEMGR_PBSETFPOS 0x1e010058
350 #define FILEMGR_PBSETCATINFO 0x1e01005c
351 #define FILEMGR_PBGETVOLPARMS 0x1e010060
352 #define FILEMGR_PBSETVINFO 0x1e010064
353 #define FILEMGR_PBMAKEFSSPEC 0x1e010068
354 #define FILEMGR_PBHGETVINFO 0x1e01006c
355 #define FILEMGR_PBCREATEFILEIDREF 0x1e010070
356 #define FILEMGR_PBDELETEFILEIDREF 0x1e010074
357 #define FILEMGR_PBRESOLVEFILEIDREF 0x1e010078
358 #define FILEMGR_PBFLUSHVOL 0x1e01007c
359 #define FILEMGR_PBHRENAME 0x1e010080
360 #define FILEMGR_PBCATMOVE 0x1e010084
361 #define FILEMGR_PBEXCHANGEFILES 0x1e010088
362 #define FILEMGR_PBHDELETE 0x1e01008c
363 #define FILEMGR_PBDIRCREATE 0x1e010090
364 #define FILEMGR_PBCATSEARCH 0x1e010094
365 #define FILEMGR_PBHSETFLOCK 0x1e010098
366 #define FILEMGR_PBHRSTFLOCK 0x1e01009c
367 #define FILEMGR_PBLOCKRANGE 0x1e0100a0
368 #define FILEMGR_PBUNLOCKRANGE 0x1e0100a4
371 #define FILEMGR_CLASS 0x1e
377 int exclude_pids
= 0;
378 int exclude_default_pids
= 1;
380 struct kinfo_proc
*kp_buffer
= 0;
383 #define SAMPLE_SIZE 60000
385 #define DBG_ZERO_FILL_FAULT 1
386 #define DBG_PAGEIN_FAULT 2
387 #define DBG_COW_FAULT 3
388 #define DBG_CACHE_HIT_FAULT 4
390 #define DBG_FUNC_ALL (DBG_FUNC_START | DBG_FUNC_END)
391 #define DBG_FUNC_MASK 0xfffffffc
393 double divisor
= 0.0; /* Trace divisor converts to microseconds */
399 kbufinfo_t bufinfo
= {0, 0, 0, 0, 0};
401 int total_threads
= 0;
402 kd_threadmap
*mapptr
= 0; /* pointer to list of threads */
404 /* defines for tracking file descriptor state */
405 #define FS_USAGE_FD_SETSIZE 256 /* Initial number of file descriptors per
406 thread that we will track */
408 #define FS_USAGE_NFDBITS (sizeof (unsigned long) * 8)
409 #define FS_USAGE_NFDBYTES(n) (((n) / FS_USAGE_NFDBITS) * sizeof (unsigned long))
412 unsigned int fd_valid
; /* set if this is a valid entry */
413 unsigned int fd_thread
;
414 unsigned int fd_setsize
; /* this is a bit count */
415 unsigned long *fd_setptr
; /* file descripter bitmap */
418 fd_threadmap
*fdmapptr
= 0; /* pointer to list of threads for fd tracking */
420 int trace_enabled
= 0;
421 int set_remove_flag
= 1;
433 void leave() /* exit under normal conditions -- INT handler */
438 void set_pidexclude();
443 if (exclude_pids
== 0) {
444 for (i
= 0; i
< num_of_pids
; i
++)
445 set_pidcheck(pids
[i
], 0);
448 for (i
= 0; i
< num_of_pids
; i
++)
449 set_pidexclude(pids
[i
], 0);
456 void get_screenwidth()
463 if (ioctl(1, TIOCGWINSZ
, &size
) != -1)
464 columns
= size
.ws_col
;
476 exit_usage(char *myname
) {
478 fprintf(stderr
, "Usage: %s [-e] [-w] [-f mode] [pid | cmd [pid | cmd]....]\n", myname
);
479 fprintf(stderr
, " -e exclude the specified list of pids from the sample\n");
480 fprintf(stderr
, " and exclude fs_usage by default\n");
481 fprintf(stderr
, " -w force wider, detailed, output\n");
482 fprintf(stderr
, " -f Output is filtered based on the mode provided\n");
483 fprintf(stderr
, " mode = \"network\" Show only network related output\n");
484 fprintf(stderr
, " mode = \"filesys\" Show only file system related output\n");
485 fprintf(stderr
, " pid selects process(s) to sample\n");
486 fprintf(stderr
, " cmd selects process(s) matching command string to sample\n");
487 fprintf(stderr
, "\n%s will handle a maximum list of %d pids.\n\n", myname
, MAX_PIDS
);
488 fprintf(stderr
, "By default (no options) the following processes are excluded from the output:\n");
489 fprintf(stderr
, "fs_usage, Terminal, telnetd, sshd, rlogind, tcsh, csh, sh\n\n");
499 char *myname
= "fs_usage";
506 void set_pidexclude();
509 if ( geteuid() != 0 ) {
510 printf("'fs_usage' must be run as root...\n");
517 if ((myname
= rindex(argv
[0], '/')) == 0) {
526 while ((ch
= getopt(argc
, argv
, "ewf:")) != EOF
) {
530 exclude_default_pids
= 0;
534 if ((uint
)columns
< MAX_WIDE_MODE_COLS
)
535 columns
= MAX_WIDE_MODE_COLS
;
538 if (!strcmp(optarg
, "network"))
539 filter_mode
|= NETWORK_FILTER
;
540 else if (!strcmp(optarg
, "filesys"))
541 filter_mode
|= FILESYS_FILTER
;
552 /* If we process any list of pids/cmds, then turn off the defaults */
554 exclude_default_pids
= 0;
556 while (argc
> 0 && num_of_pids
< (MAX_PIDS
- 1)) {
563 /* Exclude a set of default pids */
564 if (exclude_default_pids
)
566 argtopid("Terminal");
579 if (num_of_pids
< (MAX_PIDS
- 1))
580 pids
[num_of_pids
++] = getpid();
586 for (i
= 0; i
< num_of_pids
; i
++)
589 printf("exclude pid %d\n", pids
[i
]);
591 printf("pid %d\n", pids
[i
]);
595 /* set up signal handlers */
596 signal(SIGINT
, leave
);
597 signal(SIGQUIT
, leave
);
598 signal(SIGHUP
, leave
);
599 signal(SIGTERM
, leave
);
600 signal(SIGWINCH
, sigwinch
);
602 if ((my_buffer
= malloc(SAMPLE_SIZE
* sizeof(kd_buf
))) == (char *)0)
603 quit("can't allocate memory for tracing info\n");
609 set_numbufs(SAMPLE_SIZE
);
612 if (exclude_pids
== 0) {
613 for (i
= 0; i
< num_of_pids
; i
++)
614 set_pidcheck(pids
[i
], 1);
616 for (i
= 0; i
< num_of_pids
; i
++)
617 set_pidexclude(pids
[i
], 1);
620 if (select_pid_mode
&& !one_good_pid
)
623 An attempt to restrict output to a given
624 pid or command has failed. Exit gracefully
632 init_arguments_buffer();
648 struct kinfo_proc
*kp
;
653 mib
[2] = KERN_PROC_ALL
;
656 if (sysctl(mib
, 4, NULL
, &bufSize
, NULL
, 0) < 0)
657 quit("trace facility failure, KERN_PROC_ALL\n");
659 if((kp
= (struct kinfo_proc
*)malloc(bufSize
)) == (struct kinfo_proc
*)0)
660 quit("can't allocate memory for proc buffer\n");
662 if (sysctl(mib
, 4, kp
, &bufSize
, NULL
, 0) < 0)
663 quit("trace facility failure, KERN_PROC_ALL\n");
665 kp_nentries
= bufSize
/ sizeof(struct kinfo_proc
);
670 struct th_info
*find_thread(int thread
, int type
) {
673 for (ti
= th_state
; ti
< &th_state
[cur_max
]; ti
++) {
674 if (ti
->thread
== thread
) {
675 if (type
== ti
->type
)
677 if (ti
->in_filemgr
) {
686 return ((struct th_info
*)0);
691 mark_thread_waited(int thread
) {
694 for (ti
= th_state
; ti
< &th_state
[cur_max
]; ti
++) {
695 if (ti
->thread
== thread
) {
706 mib
[1] = KERN_KDEBUG
;
707 mib
[2] = KERN_KDENABLE
; /* protocol */
710 mib
[5] = 0; /* no flags */
711 if (sysctl(mib
, 4, NULL
, &needed
, NULL
, 0) < 0)
712 quit("trace facility failure, KERN_KDENABLE\n");
721 set_numbufs(int nbufs
)
724 mib
[1] = KERN_KDEBUG
;
725 mib
[2] = KERN_KDSETBUF
;
728 mib
[5] = 0; /* no flags */
729 if (sysctl(mib
, 4, NULL
, &needed
, NULL
, 0) < 0)
730 quit("trace facility failure, KERN_KDSETBUF\n");
733 mib
[1] = KERN_KDEBUG
;
734 mib
[2] = KERN_KDSETUP
;
737 mib
[5] = 0; /* no flags */
738 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0)
739 quit("trace facility failure, KERN_KDSETUP\n");
743 set_pidcheck(int pid
, int on_off
)
747 kr
.type
= KDBG_TYPENONE
;
750 needed
= sizeof(kd_regtype
);
752 mib
[1] = KERN_KDEBUG
;
753 mib
[2] = KERN_KDPIDTR
;
758 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0) {
760 printf("pid %d does not exist\n", pid
);
768 on_off == 0 turns off pid exclusion
769 on_off == 1 turns on pid exclusion
772 set_pidexclude(int pid
, int on_off
)
778 kr
.type
= KDBG_TYPENONE
;
781 needed
= sizeof(kd_regtype
);
783 mib
[1] = KERN_KDEBUG
;
784 mib
[2] = KERN_KDPIDEX
;
789 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0) {
791 printf("pid %d does not exist\n", pid
);
796 get_bufinfo(kbufinfo_t
*val
)
798 needed
= sizeof (*val
);
800 mib
[1] = KERN_KDEBUG
;
801 mib
[2] = KERN_KDGETBUF
;
804 mib
[5] = 0; /* no flags */
806 if (sysctl(mib
, 3, val
, &needed
, 0, 0) < 0)
807 quit("trace facility failure, KERN_KDGETBUF\n");
817 mib
[1] = KERN_KDEBUG
;
818 mib
[2] = KERN_KDREMOVE
; /* protocol */
821 mib
[5] = 0; /* no flags */
822 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0)
827 quit("the trace facility is currently in use...\n fs_usage, sc_usage, and latency use this feature.\n\n");
829 quit("trace facility failure, KERN_KDREMOVE\n");
837 kr
.type
= KDBG_RANGETYPE
;
840 needed
= sizeof(kd_regtype
);
842 mib
[1] = KERN_KDEBUG
;
843 mib
[2] = KERN_KDSETREG
;
846 mib
[5] = 0; /* no flags */
848 if (sysctl(mib
, 3, &kr
, &needed
, NULL
, 0) < 0)
849 quit("trace facility failure, KERN_KDSETREG\n");
852 mib
[1] = KERN_KDEBUG
;
853 mib
[2] = KERN_KDSETUP
;
856 mib
[5] = 0; /* no flags */
858 if (sysctl(mib
, 3, NULL
, &needed
, NULL
, 0) < 0)
859 quit("trace facility failure, KERN_KDSETUP\n");
868 void read_command_map();
869 void create_map_entry();
871 /* Get kernel buffer information */
872 get_bufinfo(&bufinfo
);
878 needed
= bufinfo
.nkdbufs
* sizeof(kd_buf
);
880 mib
[1] = KERN_KDEBUG
;
881 mib
[2] = KERN_KDREADTR
;
884 mib
[5] = 0; /* no flags */
886 if (sysctl(mib
, 3, my_buffer
, &needed
, NULL
, 0) < 0)
887 quit("trace facility failure, KERN_KDREADTR\n");
890 if (bufinfo
.flags
& KDBG_WRAPPED
) {
891 printf("buffer wrapped count = %d\n", count
);
893 for (i
= 0; i
< cur_max
; i
++) {
894 th_state
[i
].thread
= 0;
896 th_state
[i
].pathptr
= (long *)0;
897 th_state
[i
].pathname
[0] = 0;
905 kd
= (kd_buf
*)my_buffer
;
907 printf("READTR returned %d items\n", count
);
909 for (i
= 0; i
< count
; i
++) {
919 void enter_syscall();
921 void extend_syscall();
922 void kill_thread_map();
924 thread
= kd
[i
].arg5
& KDBG_THREAD_MASK
;
925 debugid
= kd
[i
].debugid
;
926 type
= kd
[i
].debugid
& DBG_FUNC_MASK
;
928 now
= kd
[i
].timestamp
;
933 * Compute bias seconds after each trace buffer read.
934 * This helps resync timestamps with the system clock
935 * in the event of a system sleep.
937 l_usecs
= (long long)(now
/ divisor
);
938 secs
= l_usecs
/ 1000000;
939 curr_time
= time((long *)0);
940 bias_secs
= curr_time
- secs
;
958 insert_diskio(type
, kd
[i
].arg1
, kd
[i
].arg2
, kd
[i
].arg3
, kd
[i
].arg4
, thread
, (double)now
);
967 case P_RdMetaAsyncDone
:
968 case P_WrMetaAsyncDone
:
969 case P_RdDataAsyncDone
:
970 case P_WrDataAsyncDone
:
971 case P_PgInAsyncDone
:
972 case P_PgOutAsyncDone
:
973 if ((dio
= complete_diskio(kd
[i
].arg1
, kd
[i
].arg4
, kd
[i
].arg3
, thread
, (double)now
))) {
980 case TRACE_DATA_NEWTHREAD
:
982 for (n
= 0, ti
= th_state
; ti
< &th_state
[MAX_THREADS
]; ti
++, n
++) {
986 if (ti
== &th_state
[MAX_THREADS
])
992 ti
->child_thread
= kd
[i
].arg1
;
993 ti
->pid
= kd
[i
].arg2
;
996 case TRACE_STRING_NEWTHREAD
:
997 if ((ti
= find_thread(thread
, 0)) == (struct th_info
*)0)
999 if (ti
->child_thread
== 0)
1001 create_map_entry(ti
->child_thread
, ti
->pid
, (char *)&kd
[i
].arg1
);
1003 if (ti
== &th_state
[cur_max
- 1])
1005 ti
->child_thread
= 0;
1010 case TRACE_DATA_EXEC
:
1012 for (n
= 0, ti
= th_state
; ti
< &th_state
[MAX_THREADS
]; ti
++, n
++) {
1013 if (ti
->thread
== 0)
1016 if (ti
== &th_state
[MAX_THREADS
])
1021 ti
->thread
= thread
;
1022 ti
->pid
= kd
[i
].arg1
;
1025 case TRACE_STRING_EXEC
:
1026 if ((ti
= find_thread(thread
, 0)) == (struct th_info
*)0)
1028 /* this is for backwards compatibility */
1029 create_map_entry(thread
, 0, (char *)&kd
[i
].arg1
);
1033 create_map_entry(thread
, ti
->pid
, (char *)&kd
[i
].arg1
);
1034 if (ti
== &th_state
[cur_max
- 1])
1042 kill_thread_map(thread
);
1046 case MACH_stkhandoff
:
1047 mark_thread_waited(thread
);
1051 if ((ti
= find_thread(thread
, 0)) == (struct th_info
*)0)
1055 sargptr
= (long *)&ti
->pathname
[0];
1056 memset(&ti
->pathname
[0], 0, (PATHLENGTH
+ 1));
1057 *sargptr
++ = kd
[i
].arg2
;
1058 *sargptr
++ = kd
[i
].arg3
;
1059 *sargptr
++ = kd
[i
].arg4
;
1060 ti
->pathptr
= sargptr
;
1062 sargptr
= ti
->pathptr
;
1065 We don't want to overrun our pathname buffer if the
1066 kernel sends us more VFS_LOOKUP entries than we can
1070 if ((long *)sargptr
>= (long *)&ti
->pathname
[PATHLENGTH
])
1074 We need to detect consecutive vfslookup entries.
1075 So, if we get here and find a START entry,
1076 fake the pathptr so we can bypass all further
1080 if (debugid
& DBG_FUNC_START
)
1082 (long *)ti
->pathptr
= (long *)&ti
->pathname
[PATHLENGTH
];
1086 *sargptr
++ = kd
[i
].arg1
;
1087 *sargptr
++ = kd
[i
].arg2
;
1088 *sargptr
++ = kd
[i
].arg3
;
1089 *sargptr
++ = kd
[i
].arg4
;
1090 ti
->pathptr
= sargptr
;
1095 if (debugid
& DBG_FUNC_START
) {
1099 case FILEMGR_PBGETCATALOGINFO
:
1100 p
= "GetCatalogInfo";
1102 case FILEMGR_PBGETCATALOGINFOBULK
:
1103 p
= "GetCatalogInfoBulk";
1105 case FILEMGR_PBCREATEFILEUNICODE
:
1106 p
= "CreateFileUnicode";
1108 case FILEMGR_PBCREATEDIRECTORYUNICODE
:
1109 p
= "CreateDirectoryUnicode";
1111 case FILEMGR_PBCREATEFORK
:
1114 case FILEMGR_PBDELETEFORK
:
1117 case FILEMGR_PBITERATEFORK
:
1118 p
= "PBIterateFork";
1120 case FILEMGR_PBOPENFORK
:
1123 case FILEMGR_PBREADFORK
:
1126 case FILEMGR_PBWRITEFORK
:
1129 case FILEMGR_PBALLOCATEFORK
:
1130 p
= "PBAllocateFork";
1132 case FILEMGR_PBDELETEOBJECT
:
1133 p
= "PBDeleteObject";
1135 case FILEMGR_PBEXCHANGEOBJECT
:
1136 p
= "PBExchangeObject";
1138 case FILEMGR_PBGETFORKCBINFO
:
1139 p
= "PBGetForkCBInfo";
1141 case FILEMGR_PBGETVOLUMEINFO
:
1142 p
= "PBGetVolumeInfo";
1144 case FILEMGR_PBMAKEFSREF
:
1147 case FILEMGR_PBMAKEFSREFUNICODE
:
1148 p
= "PBMakeFSRefUnicode";
1150 case FILEMGR_PBMOVEOBJECT
:
1153 case FILEMGR_PBOPENITERATOR
:
1154 p
= "PBOpenIterator";
1156 case FILEMGR_PBRENAMEUNICODE
:
1157 p
= "PBRenameUnicode";
1159 case FILEMGR_PBSETCATALOGINFO
:
1160 p
= "SetCatalogInfo";
1162 case FILEMGR_PBSETVOLUMEINFO
:
1163 p
= "SetVolumeInfo";
1165 case FILEMGR_FSREFMAKEPATH
:
1166 p
= "FSRefMakePath";
1168 case FILEMGR_FSPATHMAKEREF
:
1169 p
= "FSPathMakeRef";
1172 case FILEMGR_PBGETCATINFO
:
1175 case FILEMGR_PBGETCATINFOLITE
:
1176 p
= "GetCatInfoLite";
1178 case FILEMGR_PBHGETFINFO
:
1181 case FILEMGR_PBXGETVOLINFO
:
1182 p
= "PBXGetVolInfo";
1184 case FILEMGR_PBHCREATE
:
1187 case FILEMGR_PBHOPENDF
:
1190 case FILEMGR_PBHOPENRF
:
1193 case FILEMGR_PBHGETDIRACCESS
:
1194 p
= "PBHGetDirAccess";
1196 case FILEMGR_PBHSETDIRACCESS
:
1197 p
= "PBHSetDirAccess";
1199 case FILEMGR_PBHMAPID
:
1202 case FILEMGR_PBHMAPNAME
:
1205 case FILEMGR_PBCLOSE
:
1208 case FILEMGR_PBFLUSHFILE
:
1211 case FILEMGR_PBGETEOF
:
1214 case FILEMGR_PBSETEOF
:
1217 case FILEMGR_PBGETFPOS
:
1220 case FILEMGR_PBREAD
:
1223 case FILEMGR_PBWRITE
:
1226 case FILEMGR_PBGETFCBINFO
:
1229 case FILEMGR_PBSETFINFO
:
1232 case FILEMGR_PBALLOCATE
:
1235 case FILEMGR_PBALLOCCONTIG
:
1236 p
= "PBAllocContig";
1238 case FILEMGR_PBSETFPOS
:
1241 case FILEMGR_PBSETCATINFO
:
1244 case FILEMGR_PBGETVOLPARMS
:
1245 p
= "PBGetVolParms";
1247 case FILEMGR_PBSETVINFO
:
1250 case FILEMGR_PBMAKEFSSPEC
:
1253 case FILEMGR_PBHGETVINFO
:
1256 case FILEMGR_PBCREATEFILEIDREF
:
1257 p
= "PBCreateFileIDRef";
1259 case FILEMGR_PBDELETEFILEIDREF
:
1260 p
= "PBDeleteFileIDRef";
1262 case FILEMGR_PBRESOLVEFILEIDREF
:
1263 p
= "PBResolveFileIDRef";
1265 case FILEMGR_PBFLUSHVOL
:
1268 case FILEMGR_PBHRENAME
:
1271 case FILEMGR_PBCATMOVE
:
1274 case FILEMGR_PBEXCHANGEFILES
:
1275 p
= "PBExchangeFiles";
1277 case FILEMGR_PBHDELETE
:
1280 case FILEMGR_PBDIRCREATE
:
1283 case FILEMGR_PBCATSEARCH
:
1286 case FILEMGR_PBHSETFLOCK
:
1289 case FILEMGR_PBHRSTFLOCK
:
1292 case FILEMGR_PBLOCKRANGE
:
1295 case FILEMGR_PBUNLOCKRANGE
:
1296 p
= "PBUnlockRange";
1302 enter_syscall(thread
, type
, &kd
[i
], p
, (double)now
);
1308 case BSC_pread_extended
:
1309 case BSC_pwrite_extended
:
1310 extend_syscall(thread
, type
, &kd
[i
], (double)now
);
1314 exit_syscall("PAGE_OUT_D", thread
, type
, 0, kd
[i
].arg1
, 0, 4, (double)now
);
1316 exit_syscall("PAGE_OUT_V", thread
, type
, 0, kd
[i
].arg1
, 0, 4, (double)now
);
1320 if (kd
[i
].arg2
== DBG_PAGEIN_FAULT
)
1321 exit_syscall("PAGE_IN", thread
, type
, kd
[i
].arg4
, kd
[i
].arg1
, 0, 6, (double)now
);
1322 else if (kd
[i
].arg2
== DBG_CACHE_HIT_FAULT
)
1323 exit_syscall("CACHE_HIT", thread
, type
, 0, kd
[i
].arg1
, 0, 2, (double)now
);
1325 if ((ti
= find_thread(thread
, type
))) {
1326 if (ti
== &th_state
[cur_max
- 1])
1334 exit_syscall("map_fd", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1338 exit_syscall("mmap", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1342 exit_syscall("recvmsg", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1346 exit_syscall("sendmsg", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1350 exit_syscall("recvfrom", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1354 exit_syscall("accept", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 2, 0, (double)now
);
1358 exit_syscall("select", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 8, (double)now
);
1362 exit_syscall("socket", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 2, 0, (double)now
);
1366 exit_syscall("connect", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1370 exit_syscall("bind", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1374 exit_syscall("listen", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1378 exit_syscall("sendto", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1381 case BSC_socketpair
:
1382 exit_syscall("socketpair", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1386 exit_syscall("stat", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1389 case BSC_load_shared_file
:
1390 exit_syscall("load_sf", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1394 exit_syscall("open", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 2, 0, (double)now
);
1398 exit_syscall("dup", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 2, 0, (double)now
);
1402 exit_syscall("dup2", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 2, 0, (double)now
);
1406 exit_syscall("close", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1410 exit_syscall("read", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1414 exit_syscall("write", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1418 exit_syscall("fstat", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1422 exit_syscall("lstat", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1426 exit_syscall("link", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1430 exit_syscall("unlink", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1434 exit_syscall("mknod", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1438 exit_syscall("chmod", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1442 exit_syscall("chown", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1446 exit_syscall("access", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1450 exit_syscall("chdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1454 exit_syscall("chroot", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1458 exit_syscall("utimes", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1462 exit_syscall("delete", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1466 exit_syscall("undelete", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1470 exit_syscall("revoke", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1474 exit_syscall("fsctl", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1478 exit_syscall("chflags", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1482 exit_syscall("fchflags", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1486 exit_syscall("fchdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1490 exit_syscall("futimes", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1494 exit_syscall("sync", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1498 exit_syscall("symlink", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1502 exit_syscall("readlink", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1506 exit_syscall("fsync", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1510 exit_syscall("readv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1514 exit_syscall("writev", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1518 exit_syscall("pread", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 9, (double)now
);
1522 exit_syscall("pwrite", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 9, (double)now
);
1526 exit_syscall("fchown", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1530 exit_syscall("fchmod", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1534 exit_syscall("mkdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1538 exit_syscall("mkfifo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1542 exit_syscall("rmdir", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1546 exit_syscall("statfs", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1550 exit_syscall("fstatfs", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1554 exit_syscall("pathconf", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1558 exit_syscall("fpathconf", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1561 case BSC_getdirentries
:
1562 exit_syscall("getdirentries", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 1, (double)now
);
1566 exit_syscall("lseek", thread
, type
, kd
[i
].arg1
, kd
[i
].arg3
, 1, 5, (double)now
);
1570 exit_syscall("truncate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1574 exit_syscall("ftruncate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 3, (double)now
);
1578 exit_syscall("statv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1582 exit_syscall("lstatv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1586 exit_syscall("fstatv", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 1, 0, (double)now
);
1590 exit_syscall("mkcomplex", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1593 case BSC_getattrlist
:
1594 exit_syscall("getattrlist", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1597 case BSC_setattrlist
:
1598 exit_syscall("setattrlist", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1601 case BSC_getdirentriesattr
:
1602 exit_syscall("getdirentriesattr", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 1, (double)now
);
1606 case BSC_exchangedata
:
1607 exit_syscall("exchangedata", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1611 exit_syscall("rename", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1615 exit_syscall("copyfile", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1619 case BSC_checkuseraccess
:
1620 exit_syscall("checkuseraccess", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1624 exit_syscall("searchfs", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1627 case FILEMGR_PBGETCATALOGINFO
:
1628 exit_syscall("GetCatalogInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1630 case FILEMGR_PBGETCATALOGINFOBULK
:
1631 exit_syscall("GetCatalogInfoBulk", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1633 case FILEMGR_PBCREATEFILEUNICODE
:
1634 exit_syscall("CreateFileUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1636 case FILEMGR_PBCREATEDIRECTORYUNICODE
:
1637 exit_syscall("CreateDirectoryUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1639 case FILEMGR_PBCREATEFORK
:
1640 exit_syscall("PBCreateFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1642 case FILEMGR_PBDELETEFORK
:
1643 exit_syscall("PBDeleteFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1645 case FILEMGR_PBITERATEFORK
:
1646 exit_syscall("PBIterateFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1648 case FILEMGR_PBOPENFORK
:
1649 exit_syscall("PBOpenFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1651 case FILEMGR_PBREADFORK
:
1652 exit_syscall("PBReadFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1654 case FILEMGR_PBWRITEFORK
:
1655 exit_syscall("PBWriteFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1657 case FILEMGR_PBALLOCATEFORK
:
1658 exit_syscall("PBAllocateFork", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1660 case FILEMGR_PBDELETEOBJECT
:
1661 exit_syscall("PBDeleteObject", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1663 case FILEMGR_PBEXCHANGEOBJECT
:
1664 exit_syscall("PBExchangeObject", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1666 case FILEMGR_PBGETFORKCBINFO
:
1667 exit_syscall("PBGetForkCBInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1669 case FILEMGR_PBGETVOLUMEINFO
:
1670 exit_syscall("PBGetVolumeInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1672 case FILEMGR_PBMAKEFSREF
:
1673 exit_syscall("PBMakeFSRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1675 case FILEMGR_PBMAKEFSREFUNICODE
:
1676 exit_syscall("PBMakeFSRefUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1678 case FILEMGR_PBMOVEOBJECT
:
1679 exit_syscall("PBMoveObject", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1681 case FILEMGR_PBOPENITERATOR
:
1682 exit_syscall("PBOpenIterator", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1684 case FILEMGR_PBRENAMEUNICODE
:
1685 exit_syscall("PBRenameUnicode", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1687 case FILEMGR_PBSETCATALOGINFO
:
1688 exit_syscall("PBSetCatalogInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1690 case FILEMGR_PBSETVOLUMEINFO
:
1691 exit_syscall("PBSetVolumeInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1693 case FILEMGR_FSREFMAKEPATH
:
1694 exit_syscall("FSRefMakePath", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1696 case FILEMGR_FSPATHMAKEREF
:
1697 exit_syscall("FSPathMakeRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1699 case FILEMGR_PBGETCATINFO
:
1700 exit_syscall("GetCatInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1702 case FILEMGR_PBGETCATINFOLITE
:
1703 exit_syscall("GetCatInfoLite", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1705 case FILEMGR_PBHGETFINFO
:
1706 exit_syscall("PBHGetFInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1708 case FILEMGR_PBXGETVOLINFO
:
1709 exit_syscall("PBXGetVolInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1711 case FILEMGR_PBHCREATE
:
1712 exit_syscall("PBHCreate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1714 case FILEMGR_PBHOPENDF
:
1715 exit_syscall("PBHOpenDF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1717 case FILEMGR_PBHOPENRF
:
1718 exit_syscall("PBHOpenRF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1720 case FILEMGR_PBHGETDIRACCESS
:
1721 exit_syscall("PBHGetDirAccess", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1723 case FILEMGR_PBHSETDIRACCESS
:
1724 exit_syscall("PBHSetDirAccess", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1726 case FILEMGR_PBHMAPID
:
1727 exit_syscall("PBHMapID", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1729 case FILEMGR_PBHMAPNAME
:
1730 exit_syscall("PBHMapName", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1732 case FILEMGR_PBCLOSE
:
1733 exit_syscall("PBClose", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1735 case FILEMGR_PBFLUSHFILE
:
1736 exit_syscall("PBFlushFile", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1738 case FILEMGR_PBGETEOF
:
1739 exit_syscall("PBGetEOF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1741 case FILEMGR_PBSETEOF
:
1742 exit_syscall("PBSetEOF", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1744 case FILEMGR_PBGETFPOS
:
1745 exit_syscall("PBGetFPos", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1747 case FILEMGR_PBREAD
:
1748 exit_syscall("PBRead", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1750 case FILEMGR_PBWRITE
:
1751 exit_syscall("PBWrite", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1753 case FILEMGR_PBGETFCBINFO
:
1754 exit_syscall("PBGetFCBInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1756 case FILEMGR_PBSETFINFO
:
1757 exit_syscall("PBSetFInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1759 case FILEMGR_PBALLOCATE
:
1760 exit_syscall("PBAllocate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1762 case FILEMGR_PBALLOCCONTIG
:
1763 exit_syscall("PBAllocContig", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1765 case FILEMGR_PBSETFPOS
:
1766 exit_syscall("PBSetFPos", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1768 case FILEMGR_PBSETCATINFO
:
1769 exit_syscall("PBSetCatInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1771 case FILEMGR_PBGETVOLPARMS
:
1772 exit_syscall("PBGetVolParms", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1774 case FILEMGR_PBSETVINFO
:
1775 exit_syscall("PBSetVInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1777 case FILEMGR_PBMAKEFSSPEC
:
1778 exit_syscall("PBMakeFSSpec", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1780 case FILEMGR_PBHGETVINFO
:
1781 exit_syscall("PBHGetVInfo", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1783 case FILEMGR_PBCREATEFILEIDREF
:
1784 exit_syscall("PBCreateFileIDRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1786 case FILEMGR_PBDELETEFILEIDREF
:
1787 exit_syscall("PBDeleteFileIDRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1789 case FILEMGR_PBRESOLVEFILEIDREF
:
1790 exit_syscall("PBResolveFileIDRef", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1792 case FILEMGR_PBFLUSHVOL
:
1793 exit_syscall("PBFlushVol", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1795 case FILEMGR_PBHRENAME
:
1796 exit_syscall("PBHRename", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1798 case FILEMGR_PBCATMOVE
:
1799 exit_syscall("PBCatMove", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1801 case FILEMGR_PBEXCHANGEFILES
:
1802 exit_syscall("PBExchangeFiles", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1804 case FILEMGR_PBHDELETE
:
1805 exit_syscall("PBHDelete", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1807 case FILEMGR_PBDIRCREATE
:
1808 exit_syscall("PBDirCreate", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1810 case FILEMGR_PBCATSEARCH
:
1811 exit_syscall("PBCatSearch", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1813 case FILEMGR_PBHSETFLOCK
:
1814 exit_syscall("PBHSetFLock", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1816 case FILEMGR_PBHRSTFLOCK
:
1817 exit_syscall("PBHRstFLock", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1819 case FILEMGR_PBLOCKRANGE
:
1820 exit_syscall("PBLockRange", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1822 case FILEMGR_PBUNLOCKRANGE
:
1823 exit_syscall("PBUnlockRange", thread
, type
, kd
[i
].arg1
, kd
[i
].arg2
, 0, 0, (double)now
);
1833 enter_syscall(int thread
, int type
, kd_buf
*kd
, char *name
, double now
)
1842 kd_threadmap
*find_thread_map();
1865 case BSC_socketpair
:
1867 case BSC_load_shared_file
:
1912 case BSC_getdirentries
:
1920 case BSC_getattrlist
:
1921 case BSC_setattrlist
:
1922 case BSC_getdirentriesattr
:
1923 case BSC_exchangedata
:
1924 case BSC_checkuseraccess
:
1926 case FILEMGR_PBGETCATALOGINFO
:
1927 case FILEMGR_PBGETCATALOGINFOBULK
:
1928 case FILEMGR_PBCREATEFILEUNICODE
:
1929 case FILEMGR_PBCREATEDIRECTORYUNICODE
:
1930 case FILEMGR_PBCREATEFORK
:
1931 case FILEMGR_PBDELETEFORK
:
1932 case FILEMGR_PBITERATEFORK
:
1933 case FILEMGR_PBOPENFORK
:
1934 case FILEMGR_PBREADFORK
:
1935 case FILEMGR_PBWRITEFORK
:
1936 case FILEMGR_PBALLOCATEFORK
:
1937 case FILEMGR_PBDELETEOBJECT
:
1938 case FILEMGR_PBEXCHANGEOBJECT
:
1939 case FILEMGR_PBGETFORKCBINFO
:
1940 case FILEMGR_PBGETVOLUMEINFO
:
1941 case FILEMGR_PBMAKEFSREF
:
1942 case FILEMGR_PBMAKEFSREFUNICODE
:
1943 case FILEMGR_PBMOVEOBJECT
:
1944 case FILEMGR_PBOPENITERATOR
:
1945 case FILEMGR_PBRENAMEUNICODE
:
1946 case FILEMGR_PBSETCATALOGINFO
:
1947 case FILEMGR_PBSETVOLUMEINFO
:
1948 case FILEMGR_FSREFMAKEPATH
:
1949 case FILEMGR_FSPATHMAKEREF
:
1951 case FILEMGR_PBGETCATINFO
:
1952 case FILEMGR_PBGETCATINFOLITE
:
1953 case FILEMGR_PBHGETFINFO
:
1954 case FILEMGR_PBXGETVOLINFO
:
1955 case FILEMGR_PBHCREATE
:
1956 case FILEMGR_PBHOPENDF
:
1957 case FILEMGR_PBHOPENRF
:
1958 case FILEMGR_PBHGETDIRACCESS
:
1959 case FILEMGR_PBHSETDIRACCESS
:
1960 case FILEMGR_PBHMAPID
:
1961 case FILEMGR_PBHMAPNAME
:
1962 case FILEMGR_PBCLOSE
:
1963 case FILEMGR_PBFLUSHFILE
:
1964 case FILEMGR_PBGETEOF
:
1965 case FILEMGR_PBSETEOF
:
1966 case FILEMGR_PBGETFPOS
:
1967 case FILEMGR_PBREAD
:
1968 case FILEMGR_PBWRITE
:
1969 case FILEMGR_PBGETFCBINFO
:
1970 case FILEMGR_PBSETFINFO
:
1971 case FILEMGR_PBALLOCATE
:
1972 case FILEMGR_PBALLOCCONTIG
:
1973 case FILEMGR_PBSETFPOS
:
1974 case FILEMGR_PBSETCATINFO
:
1975 case FILEMGR_PBGETVOLPARMS
:
1976 case FILEMGR_PBSETVINFO
:
1977 case FILEMGR_PBMAKEFSSPEC
:
1978 case FILEMGR_PBHGETVINFO
:
1979 case FILEMGR_PBCREATEFILEIDREF
:
1980 case FILEMGR_PBDELETEFILEIDREF
:
1981 case FILEMGR_PBRESOLVEFILEIDREF
:
1982 case FILEMGR_PBFLUSHVOL
:
1983 case FILEMGR_PBHRENAME
:
1984 case FILEMGR_PBCATMOVE
:
1985 case FILEMGR_PBEXCHANGEFILES
:
1986 case FILEMGR_PBHDELETE
:
1987 case FILEMGR_PBDIRCREATE
:
1988 case FILEMGR_PBCATSEARCH
:
1989 case FILEMGR_PBHSETFLOCK
:
1990 case FILEMGR_PBHRSTFLOCK
:
1991 case FILEMGR_PBLOCKRANGE
:
1992 case FILEMGR_PBUNLOCKRANGE
:
1995 for (i
= 0, ti
= th_state
; ti
< &th_state
[MAX_THREADS
]; ti
++, i
++) {
1996 if (ti
->thread
== 0)
1999 if (ti
== &th_state
[MAX_THREADS
])
2005 if ((type
>> 24) == FILEMGR_CLASS
) {
2008 l_usecs
= (long long)(now
/ divisor
);
2009 secs
= l_usecs
/ 1000000;
2010 curr_time
= bias_secs
+ secs
;
2012 sprintf(buf
, "%-8.8s", &(ctime(&curr_time
)[11]));
2013 tsclen
= strlen(buf
);
2015 if (columns
> MAXCOLS
|| wideflag
) {
2016 usecs
= l_usecs
- (long long)((long long)secs
* 1000000);
2017 sprintf(&buf
[tsclen
], ".%03ld", (long)usecs
/ 1000);
2018 tsclen
= strlen(buf
);
2021 /* Print timestamp column */
2024 map
= find_thread_map(thread
);
2026 sprintf(buf
, " %-25.25s ", name
);
2027 nmclen
= strlen(buf
);
2030 sprintf(buf
, "(%d, 0x%x, 0x%x, 0x%x)", (short)kd
->arg1
, kd
->arg2
, kd
->arg3
, kd
->arg4
);
2031 argsclen
= strlen(buf
);
2034 Calculate white space out to command
2036 if (columns
> MAXCOLS
|| wideflag
)
2038 clen
= columns
- (tsclen
+ nmclen
+ argsclen
+ 20);
2041 clen
= columns
- (tsclen
+ nmclen
+ argsclen
+ 12);
2045 printf("%s", buf
); /* print the kdargs */
2046 memset(buf
, ' ', clen
);
2050 else if ((argsclen
+ clen
) > 0)
2052 /* no room so wipe out the kdargs */
2053 memset(buf
, ' ', (argsclen
+ clen
));
2054 buf
[argsclen
+ clen
] = '\0';
2058 if (columns
> MAXCOLS
|| wideflag
)
2059 printf("%-20.20s\n", map
->command
);
2061 printf("%-12.12s\n", map
->command
);
2063 printf(" %-24.24s (%5d, %#x, 0x%x, 0x%x)\n", name
, (short)kd
->arg1
, kd
->arg2
, kd
->arg3
, kd
->arg4
);
2067 ti
->thread
= thread
;
2071 ti
->arg1
= kd
->arg1
;
2072 ti
->arg2
= kd
->arg2
;
2073 ti
->arg3
= kd
->arg3
;
2074 ti
->arg4
= kd
->arg4
;
2075 ti
->pathptr
= (long *)0;
2076 ti
->pathname
[0] = 0;
2086 * Handle system call extended trace data.
2088 * Wipe out the kd args that were collected upon syscall_entry
2089 * because it is the extended info that we really want, and it
2090 * is all we really need.
2094 extend_syscall(int thread
, int type
, kd_buf
*kd
, char *name
, double now
)
2099 case BSC_pread_extended
:
2100 if ((ti
= find_thread(thread
, BSC_pread
)) == (struct th_info
*)0)
2102 ti
->arg1
= kd
->arg1
; /* the fd */
2103 ti
->arg2
= kd
->arg2
; /* nbytes */
2104 ti
->arg3
= kd
->arg3
; /* top half offset */
2105 ti
->arg4
= kd
->arg4
; /* bottom half offset */
2107 case BSC_pwrite_extended
:
2108 if ((ti
= find_thread(thread
, BSC_pwrite
)) == (struct th_info
*)0)
2110 ti
->arg1
= kd
->arg1
; /* the fd */
2111 ti
->arg2
= kd
->arg2
; /* nbytes */
2112 ti
->arg3
= kd
->arg3
; /* top half offset */
2113 ti
->arg4
= kd
->arg4
; /* bottom half offset */
2121 exit_syscall(char *sc_name
, int thread
, int type
, int error
, int retval
,
2122 int has_fd
, int has_ret
, double now
)
2126 if ((ti
= find_thread(thread
, type
)) == (struct th_info
*)0)
2129 if (check_filter_mode(ti
, type
, error
, retval
))
2130 format_print(ti
, sc_name
, thread
, type
, error
, retval
, has_fd
, has_ret
, now
, ti
->stime
, ti
->waited
, ti
->pathname
, NULL
);
2132 if (ti
== &th_state
[cur_max
- 1])
2140 format_print(struct th_info
*ti
, char *sc_name
, int thread
, int type
, int error
, int retval
,
2141 int has_fd
, int has_ret
, double now
, double stime
, int waited
, char *pathname
, struct diskio
*dio
)
2150 kd_threadmap
*find_thread_map();
2153 char *framework_name
;
2159 command_name
= dio
->issuing_command
;
2161 if ((map
= find_thread_map(thread
)))
2162 command_name
= map
->command
;
2165 l_usecs
= (long long)(now
/ divisor
);
2166 secs
= l_usecs
/ 1000000;
2167 curr_time
= bias_secs
+ secs
;
2168 sprintf(buf
, "%-8.8s", &(ctime(&curr_time
)[11]));
2171 if (columns
> MAXCOLS
|| wideflag
) {
2173 usecs
= l_usecs
- (long long)((long long)secs
* 1000000);
2174 sprintf(&buf
[clen
], ".%03ld", (long)usecs
/ 1000);
2177 if ((type
>> 24) != FILEMGR_CLASS
) {
2178 if (find_thread(thread
, -1)) {
2179 sprintf(&buf
[clen
], " ");
2187 if (((type
>> 24) == FILEMGR_CLASS
) && (columns
> MAXCOLS
|| wideflag
))
2188 sprintf(&buf
[clen
], " %-18.18s", sc_name
);
2190 sprintf(&buf
[clen
], " %-15.15s", sc_name
);
2194 framework_name
= (char *)0;
2196 if (columns
> MAXCOLS
|| wideflag
) {
2198 sprintf(&buf
[clen
], " D=0x%8.8x", dio
->blkno
);
2203 sprintf(&buf
[clen
], " [%3d] ", dio
->io_errno
);
2205 sprintf(&buf
[clen
], " B=0x%-6x /dev/%s", dio
->iosize
, find_disk_name(dio
->dev
));
2208 off_t offset_reassembled
= 0LL;
2210 if (has_fd
== 2 && error
== 0)
2211 sprintf(&buf
[clen
], " F=%-3d", retval
);
2212 else if (has_fd
== 1)
2213 sprintf(&buf
[clen
], " F=%-3d", ti
->arg1
);
2214 else if (has_ret
!= 2 && has_ret
!= 6)
2215 sprintf(&buf
[clen
], " ");
2219 if (has_ret
== 2 || has_ret
== 6)
2220 framework_name
= lookup_name(retval
);
2222 if (error
&& has_ret
!= 6)
2223 sprintf(&buf
[clen
], "[%3d] ", error
);
2224 else if (has_ret
== 3)
2225 sprintf(&buf
[clen
], "O=0x%8.8x", ti
->arg3
);
2226 else if (has_ret
== 5)
2227 sprintf(&buf
[clen
], "O=0x%8.8x", retval
);
2228 else if (has_ret
== 2)
2229 sprintf(&buf
[clen
], " A=0x%8.8x ", retval
);
2230 else if (has_ret
== 6)
2231 sprintf(&buf
[clen
], " A=0x%8.8x B=0x%-8x", retval
, error
);
2232 else if (has_ret
== 1)
2233 sprintf(&buf
[clen
], " B=0x%-6x", retval
);
2234 else if (has_ret
== 4)
2235 sprintf(&buf
[clen
], "B=0x%-8x", retval
);
2236 else if (has_ret
== 8) /* BSC_select */
2237 sprintf(&buf
[clen
], " S=%-3d ", retval
);
2238 else if (has_ret
== 9) /* BSC_pread, BSC_pwrite */
2240 sprintf(&buf
[clen
], "B=0x%-8x", retval
);
2242 offset_reassembled
= (((off_t
)(unsigned int)(ti
->arg3
)) << 32) | (unsigned int)(ti
->arg4
);
2243 if ((offset_reassembled
>> 32) != 0)
2244 sprintf(&buf
[clen
], "O=0x%16.16qx", (off_t
)offset_reassembled
);
2246 sprintf(&buf
[clen
], "O=0x%8.8qx", (off_t
)offset_reassembled
);
2249 sprintf(&buf
[clen
], " ");
2256 Calculate space available to print pathname
2258 if (columns
> MAXCOLS
|| wideflag
)
2259 clen
= columns
- (clen
+ 13 + 20);
2261 clen
= columns
- (clen
+ 13 + 12);
2263 if ((type
>> 24) != FILEMGR_CLASS
&& !nopadding
)
2267 sprintf(&buf
[0], " %s ", framework_name
);
2269 sprintf(&buf
[0], " %s ", pathname
);
2275 Add null padding if column length
2276 is wider than the pathname length.
2278 memset(&buf
[len
], ' ', clen
- len
);
2282 else if (clen
== len
)
2286 else if ((clen
> 0) && (clen
< len
))
2288 /* This prints the tail end of the pathname */
2289 buf
[len
-clen
] = ' ';
2290 printf("%s", &buf
[len
- clen
]);
2293 usecs
= (unsigned long)((now
- stime
) / divisor
);
2294 secs
= usecs
/ 1000000;
2295 usecs
-= secs
* 1000000;
2297 if ((type
>> 24) != FILEMGR_CLASS
&& !nopadding
)
2300 printf(" %2ld.%06ld", (unsigned long)secs
, (unsigned long)usecs
);
2307 if (columns
> MAXCOLS
|| wideflag
)
2308 printf(" %-20.20s", command_name
);
2310 printf(" %-12.12s", command_name
);
2324 This flag is turned off when calling
2325 quit() due to a set_remove() failure.
2327 if (set_remove_flag
)
2330 printf("fs_usage: ");
2342 unsigned int abs_to_ns_num
;
2343 unsigned int abs_to_ns_denom
;
2344 unsigned int proc_to_abs_num
;
2345 unsigned int proc_to_abs_denom
;
2347 extern void MKGetTimeBaseInfo(unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *);
2349 MKGetTimeBaseInfo (&delta
, &abs_to_ns_num
, &abs_to_ns_denom
,
2350 &proc_to_abs_num
, &proc_to_abs_denom
);
2352 divisor
= ((double)abs_to_ns_denom
/ (double)abs_to_ns_num
) * 1000;
2356 void read_command_map()
2360 int prev_total_threads
;
2368 prev_total_threads
= total_threads
;
2369 total_threads
= bufinfo
.nkdthreads
;
2370 size
= bufinfo
.nkdthreads
* sizeof(kd_threadmap
);
2374 if ((mapptr
= (kd_threadmap
*) malloc(size
)))
2376 bzero (mapptr
, size
);
2378 /* Now read the threadmap */
2380 mib
[1] = KERN_KDEBUG
;
2381 mib
[2] = KERN_KDTHRMAP
;
2384 mib
[5] = 0; /* no flags */
2385 if (sysctl(mib
, 3, mapptr
, &size
, NULL
, 0) < 0)
2387 /* This is not fatal -- just means I cant map command strings */
2394 if (mapptr
&& (filter_mode
!= DEFAULT_DO_NOT_FILTER
))
2398 /* We accept the fact that we lose file descriptor state if the
2400 for (i
= 0; i
< prev_total_threads
; i
++)
2402 if (fdmapptr
[i
].fd_setptr
)
2403 free (fdmapptr
[i
].fd_setptr
);
2409 size
= total_threads
* sizeof(fd_threadmap
);
2410 if ((fdmapptr
= (fd_threadmap
*) malloc(size
)))
2412 bzero (fdmapptr
, size
);
2413 /* reinitialize file descriptor state map */
2414 for (i
= 0; i
< total_threads
; i
++)
2416 fdmapptr
[i
].fd_thread
= mapptr
[i
].thread
;
2417 fdmapptr
[i
].fd_valid
= mapptr
[i
].valid
;
2418 fdmapptr
[i
].fd_setsize
= 0;
2419 fdmapptr
[i
].fd_setptr
= 0;
2424 /* Resolve any LaunchCFMApp command names */
2425 if (mapptr
&& arguments
)
2427 for (i
=0; i
< total_threads
; i
++)
2431 pid
= mapptr
[i
].valid
;
2433 if (pid
== 0 || pid
== 1)
2435 else if (!strncmp(mapptr
[i
].command
,"LaunchCFMA", 10))
2437 (void)get_real_command_name(pid
, mapptr
[i
].command
, sizeof(mapptr
[i
].command
));
2444 void create_map_entry(int thread
, int pid
, char *command
)
2448 fd_threadmap
*fdmap
= 0;
2453 for (i
= 0, map
= 0; !map
&& i
< total_threads
; i
++)
2455 if ((int)mapptr
[i
].thread
== thread
)
2457 map
= &mapptr
[i
]; /* Reuse this entry, the thread has been
2459 if(filter_mode
&& fdmapptr
)
2461 fdmap
= &fdmapptr
[i
];
2462 if (fdmap
->fd_thread
!= thread
) /* This shouldn't happen */
2463 fdmap
= (fd_threadmap
*)0;
2468 if (!map
) /* look for invalid entries that I can reuse*/
2470 for (i
= 0, map
= 0; !map
&& i
< total_threads
; i
++)
2472 if (mapptr
[i
].valid
== 0 )
2473 map
= &mapptr
[i
]; /* Reuse this invalid entry */
2474 if (filter_mode
&& fdmapptr
)
2476 fdmap
= &fdmapptr
[i
];
2483 /* If reach here, then this is a new thread and
2484 * there are no invalid entries to reuse
2485 * Double the size of the thread map table.
2488 n
= total_threads
* 2;
2489 mapptr
= (kd_threadmap
*) realloc(mapptr
, n
* sizeof(kd_threadmap
));
2490 bzero(&mapptr
[total_threads
], total_threads
*sizeof(kd_threadmap
));
2491 map
= &mapptr
[total_threads
];
2493 if (filter_mode
&& fdmapptr
)
2495 fdmapptr
= (fd_threadmap
*)realloc(fdmapptr
, n
* sizeof(fd_threadmap
));
2496 bzero(&fdmapptr
[total_threads
], total_threads
*sizeof(fd_threadmap
));
2497 fdmap
= &fdmapptr
[total_threads
];
2504 map
->thread
= thread
;
2506 The trace entry that returns the command name will hold
2507 at most, MAXCOMLEN chars, and in that case, is not
2508 guaranteed to be null terminated.
2510 (void)strncpy (map
->command
, command
, MAXCOMLEN
);
2511 map
->command
[MAXCOMLEN
] = '\0';
2515 fdmap
->fd_valid
= 1;
2516 fdmap
->fd_thread
= thread
;
2517 if (fdmap
->fd_setptr
)
2519 free(fdmap
->fd_setptr
);
2520 fdmap
->fd_setptr
= (unsigned long *)0;
2522 fdmap
->fd_setsize
= 0;
2525 if (pid
== 0 || pid
== 1)
2527 else if (!strncmp(map
->command
, "LaunchCFMA", 10))
2528 (void)get_real_command_name(pid
, map
->command
, sizeof(map
->command
));
2532 kd_threadmap
*find_thread_map(int thread
)
2538 return((kd_threadmap
*)0);
2540 for (i
= 0; i
< total_threads
; i
++)
2543 if (map
->valid
&& ((int)map
->thread
== thread
))
2548 return ((kd_threadmap
*)0);
2551 fd_threadmap
*find_fd_thread_map(int thread
)
2554 fd_threadmap
*fdmap
= 0;
2557 return((fd_threadmap
*)0);
2559 for (i
= 0; i
< total_threads
; i
++)
2561 fdmap
= &fdmapptr
[i
];
2562 if (fdmap
->fd_valid
&& ((int)fdmap
->fd_thread
== thread
))
2567 return ((fd_threadmap
*)0);
2572 kill_thread_map(int thread
)
2575 fd_threadmap
*fdmap
;
2577 if ((map
= find_thread_map(thread
))) {
2580 map
->command
[0] = '\0';
2585 if ((fdmap
= find_fd_thread_map(thread
)))
2587 fdmap
->fd_valid
= 0;
2588 fdmap
->fd_thread
= 0;
2589 if (fdmap
->fd_setptr
)
2591 free (fdmap
->fd_setptr
);
2592 fdmap
->fd_setptr
= (unsigned long *)0;
2594 fdmap
->fd_setsize
= 0;
2607 ret
= (int)strtol(str
, &cp
, 10);
2608 if (cp
== str
|| *cp
) {
2609 /* Assume this is a command string and find matching pids */
2613 for (i
=0; i
< kp_nentries
&& num_of_pids
< (MAX_PIDS
- 1); i
++) {
2614 if(kp_buffer
[i
].kp_proc
.p_stat
== 0)
2617 if(!strcmp(str
, kp_buffer
[i
].kp_proc
.p_comm
))
2618 pids
[num_of_pids
++] = kp_buffer
[i
].kp_proc
.p_pid
;
2622 else if (num_of_pids
< (MAX_PIDS
- 1))
2623 pids
[num_of_pids
++] = ret
;
2630 char *lookup_name(unsigned long addr
)
2633 register int start
, last
;
2636 if (numFrameworks
== 0 || addr
< frameworkInfo
[0].address
|| addr
> frameworkInfo
[numFrameworks
].address
)
2640 last
= numFrameworks
;
2642 for (i
= numFrameworks
/ 2; i
>= 0 && i
< numFrameworks
; ) {
2644 if (addr
>= frameworkInfo
[i
].address
&& addr
< frameworkInfo
[i
+1].address
)
2645 return(frameworkInfo
[i
].name
);
2647 if (addr
>= frameworkInfo
[i
].address
) {
2649 i
= start
+ ((last
- i
) / 2);
2652 i
= start
+ ((i
- start
) / 2);
2660 * Comparison routines for sorting
2662 static int compareFrameworkAddress(const void *aa
, const void *bb
)
2664 LibraryInfo
*a
= (LibraryInfo
*)aa
;
2665 LibraryInfo
*b
= (LibraryInfo
*)bb
;
2667 if (a
->address
< b
->address
) return -1;
2668 if (a
->address
== b
->address
) return 0;
2673 int scanline(char *inputstring
,char **argv
)
2676 char **ap
= argv
, *p
, *val
;
2678 for (p
= inputstring
; p
!= NULL
; )
2680 while ((val
= strsep(&p
, " \t")) != NULL
&& *val
== '\0');
2689 int ReadSegAddrTable()
2694 unsigned long frameworkAddress
, frameworkDataAddress
, previousFrameworkAddress
;
2695 char frameworkName
[256];
2698 char *substring
,*ptr
;
2702 bzero(buf
, sizeof(buf
));
2703 bzero(tokens
, sizeof(tokens
));
2707 if ((fd
= fopen(seg_addr_table
, "r")) == 0)
2711 fgets(buf
, 1023, fd
);
2716 frameworkName
[0] = 0;
2717 previousFrameworkAddress
= 0;
2719 while (fgets(buf
, 1023, fd
) && numFrameworks
< (MAXINDEX
- 2))
2724 buf
[strlen(buf
)-1] = 0;
2726 if (strncmp(buf
, "# dyld:", 7) == 0) {
2728 * the next line in the file will contain info about dyld
2734 * This is a split library line: parse it into 3 tokens
2736 ntokens
= scanline(buf
, tokens
);
2741 frameworkAddress
= strtoul(tokens
[0], 0, 16);
2742 frameworkDataAddress
= strtoul(tokens
[1], 0, 16);
2746 * dyld entry is of a different form from the std split library
2747 * it consists of a base address and a size instead of a code
2748 * and data base address
2750 frameworkInfo
[numFrameworks
].address
= frameworkAddress
;
2751 frameworkInfo
[numFrameworks
+1].address
= frameworkAddress
+ frameworkDataAddress
;
2753 frameworkInfo
[numFrameworks
].name
= (char *)"dylib";
2754 frameworkInfo
[numFrameworks
+1].name
= (char *)0;
2763 * Make sure that we have 2 addresses and a path
2765 if (!frameworkAddress
)
2767 if (!frameworkDataAddress
)
2769 if (*tokens
[2] != '/')
2771 if (frameworkAddress
== previousFrameworkAddress
)
2773 previousFrameworkAddress
= frameworkAddress
;
2776 * Extract lib name from path name
2778 if ((substring
= strrchr(tokens
[2], '.')))
2781 * There is a ".": name is whatever is between the "/" around the "."
2783 while ( *substring
!= '/') { /* find "/" before "." */
2787 strcpy(frameworkName
, substring
); /* copy path from "/" */
2788 substring
= frameworkName
;
2790 while ( *substring
!= '/' && *substring
) /* find "/" after "." and stop string there */
2797 * No ".": take segment after last "/"
2805 substring
= ptr
+ 1;
2808 strcpy(frameworkName
, substring
);
2810 frameworkInfo
[numFrameworks
].address
= frameworkAddress
;
2811 frameworkInfo
[numFrameworks
+1].address
= frameworkDataAddress
;
2813 frameworkInfo
[numFrameworks
].name
= (char *)malloc(strlen(frameworkName
) + 1);
2814 strcpy(frameworkInfo
[numFrameworks
].name
, frameworkName
);
2815 frameworkInfo
[numFrameworks
+1].name
= frameworkInfo
[numFrameworks
].name
;
2820 frameworkInfo
[numFrameworks
].address
= frameworkInfo
[numFrameworks
- 1].address
+ 0x800000;
2821 frameworkInfo
[numFrameworks
].name
= (char *)0;
2825 qsort(frameworkInfo
, numFrameworks
, sizeof(LibraryInfo
), compareFrameworkAddress
);
2831 struct diskio
*insert_diskio(int type
, int bp
, int dev
, int blkno
, int io_size
, int thread
, double curtime
)
2833 register struct diskio
*dio
;
2834 register kd_threadmap
*map
;
2836 if ((dio
= free_diskios
))
2837 free_diskios
= dio
->next
;
2839 if ((dio
= (struct diskio
*)malloc(sizeof(struct diskio
))) == NULL
)
2848 dio
->iosize
= io_size
;
2849 dio
->issued_time
= curtime
;
2850 dio
->issuing_thread
= thread
;
2852 if ((map
= find_thread_map(thread
)))
2854 strncpy(dio
->issuing_command
, map
->command
, MAXCOMLEN
);
2855 dio
->issuing_command
[MAXCOMLEN
-1] = '\0';
2858 strcpy(dio
->issuing_command
, "");
2860 dio
->next
= busy_diskios
;
2862 dio
->next
->prev
= dio
;
2869 struct diskio
*complete_diskio(int bp
, int io_errno
, int resid
, int thread
, double curtime
)
2871 register struct diskio
*dio
;
2873 for (dio
= busy_diskios
; dio
; dio
= dio
->next
) {
2874 if (dio
->bp
== bp
) {
2876 if (dio
== busy_diskios
) {
2877 if ((busy_diskios
= dio
->next
))
2878 dio
->next
->prev
= NULL
;
2881 dio
->next
->prev
= dio
->prev
;
2882 dio
->prev
->next
= dio
->next
;
2884 dio
->iosize
-= resid
;
2885 dio
->io_errno
= io_errno
;
2886 dio
->completed_time
= curtime
;
2887 dio
->completion_thread
= thread
;
2892 return ((struct diskio
*)0);
2896 void free_diskio(struct diskio
*dio
)
2898 dio
->next
= free_diskios
;
2903 void print_diskio(struct diskio
*dio
)
2907 switch (dio
->type
) {
2928 p
= " RdMeta[async]";
2931 p
= " WrMeta[async]";
2934 p
= " RdData[async]";
2937 p
= " WrData[async]";
2943 p
= " PgOut[async]";
2949 if (check_filter_mode(NULL
, dio
->type
,0, 0))
2950 format_print(NULL
, p
, dio
->issuing_thread
, dio
->type
, 0, 0, 0, 7, dio
->completed_time
, dio
->issued_time
, 1, "", dio
);
2954 void cache_disk_names()
2959 struct diskrec
*dnp
;
2962 if ((dirp
= opendir("/dev")) == NULL
)
2965 while ((dir
= readdir(dirp
)) != NULL
) {
2966 char nbuf
[MAXPATHLEN
];
2968 if (dir
->d_namlen
< 5 || strncmp("disk", dir
->d_name
, 4))
2970 sprintf(nbuf
, "%s/%s", "/dev", dir
->d_name
);
2972 if (stat(nbuf
, &st
) < 0)
2975 if ((dnp
= (struct diskrec
*)malloc(sizeof(struct diskrec
))) == NULL
)
2978 if ((dnp
->diskname
= (char *)malloc(dir
->d_namlen
+ 1)) == NULL
) {
2982 strncpy(dnp
->diskname
, dir
->d_name
, dir
->d_namlen
);
2983 dnp
->diskname
[dir
->d_namlen
] = 0;
2984 dnp
->dev
= st
.st_rdev
;
2986 dnp
->next
= disk_list
;
2989 (void) closedir(dirp
);
2993 char *find_disk_name(int dev
)
2995 struct diskrec
*dnp
;
3000 for (dnp
= disk_list
; dnp
; dnp
= dnp
->next
) {
3001 if (dnp
->dev
== dev
)
3002 return (dnp
->diskname
);
3004 return ("NOTFOUND");
3008 fs_usage_fd_set(thread
, fd
)
3009 unsigned int thread
;
3013 fd_threadmap
*fdmap
;
3015 if(!(fdmap
= find_fd_thread_map(thread
)))
3018 /* If the map is not allocated, then now is the time */
3019 if (fdmap
->fd_setptr
== (unsigned long *)0)
3021 fdmap
->fd_setptr
= (unsigned long *)malloc(FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE
));
3022 if (fdmap
->fd_setptr
)
3024 fdmap
->fd_setsize
= FS_USAGE_FD_SETSIZE
;
3025 bzero(fdmap
->fd_setptr
,(FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE
)));
3031 /* If the map is not big enough, then reallocate it */
3032 while (fdmap
->fd_setsize
< fd
)
3034 printf("reallocating bitmap for threadid %d, fd = %d, setsize = %d\n",
3035 thread
, fd
, fdmap
->fd_setsize
);
3036 n
= fdmap
->fd_setsize
* 2;
3037 fdmap
->fd_setptr
= (unsigned long *)realloc(fdmap
->fd_setptr
, (FS_USAGE_NFDBYTES(n
)));
3038 bzero(&fdmap
->fd_setptr
[(fdmap
->fd_setsize
/FS_USAGE_NFDBITS
)], (FS_USAGE_NFDBYTES(fdmap
->fd_setsize
)));
3039 fdmap
->fd_setsize
= n
;
3043 fdmap
->fd_setptr
[fd
/FS_USAGE_NFDBITS
] |= (1 << ((fd
) % FS_USAGE_NFDBITS
));
3050 0 : File Descriptor bit is not set
3051 1 : File Descriptor bit is set
3055 fs_usage_fd_isset(thread
, fd
)
3056 unsigned int thread
;
3060 fd_threadmap
*fdmap
;
3062 if(!(fdmap
= find_fd_thread_map(thread
)))
3065 if (fdmap
->fd_setptr
== (unsigned long *)0)
3068 if (fd
< fdmap
->fd_setsize
)
3069 ret
= fdmap
->fd_setptr
[fd
/FS_USAGE_NFDBITS
] & (1 << (fd
% FS_USAGE_NFDBITS
));
3075 fs_usage_fd_clear(thread
, fd
)
3076 unsigned int thread
;
3081 if (!(map
= find_fd_thread_map(thread
)))
3084 if (map
->fd_setptr
== (unsigned long *)0)
3088 if (fd
< map
->fd_setsize
)
3089 map
->fd_setptr
[fd
/FS_USAGE_NFDBITS
] &= ~(1 << (fd
% FS_USAGE_NFDBITS
));
3096 * ret = 1 means print the entry
3097 * ret = 0 means don't print the entry
3100 check_filter_mode(struct th_info
* ti
, int type
, int error
, int retval
)
3103 int network_fd_isset
= 0;
3106 if (filter_mode
== DEFAULT_DO_NOT_FILTER
)
3109 if (ti
== (struct th_info
*)0)
3111 if(filter_mode
& FILESYS_FILTER
)
3122 network_fd_isset
= fs_usage_fd_isset(ti
->thread
, fd
);
3125 fs_usage_fd_clear(ti
->thread
,fd
);
3128 if (network_fd_isset
)
3130 if (filter_mode
& NETWORK_FILTER
)
3133 else if (filter_mode
& FILESYS_FILTER
)
3138 /* we don't care about error in this case */
3140 network_fd_isset
= fs_usage_fd_isset(ti
->thread
, fd
);
3141 if (network_fd_isset
)
3143 if (filter_mode
& NETWORK_FILTER
)
3146 else if (filter_mode
& FILESYS_FILTER
)
3153 fs_usage_fd_set(ti
->thread
, fd
);
3154 if (filter_mode
& NETWORK_FILTER
)
3166 fs_usage_fd_set(ti
->thread
, fd
);
3167 if (filter_mode
& NETWORK_FILTER
)
3171 case BSC_socketpair
:
3172 /* Cannot determine info about file descriptors */
3173 if (filter_mode
& NETWORK_FILTER
)
3178 ret
=0; /* We track these cases for fd state only */
3179 fd
= ti
->arg1
; /* oldd */
3180 network_fd_isset
= fs_usage_fd_isset(ti
->thread
, fd
);
3181 if (error
== 0 && network_fd_isset
)
3183 /* then we are duping a socket descriptor */
3184 fd
= retval
; /* the new fd */
3185 fs_usage_fd_set(ti
->thread
, fd
);
3190 if (filter_mode
& FILESYS_FILTER
)
3199 * Allocate a buffer that is large enough to hold the maximum arguments
3200 * to execve(). This is used when getting the arguments to programs
3201 * when we see LaunchCFMApps. If this fails, it is not fatal, we will
3202 * simply not resolve the command name.
3206 init_arguments_buffer()
3213 mib
[1] = KERN_ARGMAX
;
3214 size
= sizeof(argmax
);
3215 if (sysctl(mib
, 2, &argmax
, &size
, NULL
, 0) == -1)
3219 /* Hack to avoid kernel bug. */
3220 if (argmax
> 8192) {
3225 arguments
= (char *)malloc(argmax
);
3232 get_real_command_name(int pid
, char *cbuf
, int csize
)
3235 * Get command and arguments.
3239 char *command_beg
, *command
, *command_end
;
3246 bzero(arguments
, argmax
);
3251 * A sysctl() is made to find out the full path that the command
3255 mib
[1] = KERN_PROCARGS
;
3259 if (sysctl(mib
, 3, arguments
, (size_t *)&argmax
, NULL
, 0) < 0) {
3263 /* Skip the saved exec_path. */
3264 for (cp
= arguments
; cp
< &arguments
[argmax
]; cp
++) {
3266 /* End of exec_path reached. */
3270 if (cp
== &arguments
[argmax
]) {
3274 /* Skip trailing '\0' characters. */
3275 for (; cp
< &arguments
[argmax
]; cp
++) {
3277 /* Beginning of first argument reached. */
3281 if (cp
== &arguments
[argmax
]) {
3287 * Make sure that the command is '\0'-terminated. This protects
3288 * against malicious programs; under normal operation this never
3289 * ends up being a problem..
3291 for (; cp
< &arguments
[argmax
]; cp
++) {
3293 /* End of first argument reached. */
3297 if (cp
== &arguments
[argmax
]) {
3300 command_end
= command
= cp
;
3302 /* Get the basename of command. */
3303 for (command
--; command
>= command_beg
; command
--) {
3304 if (*command
== '/') {
3310 (void) strncpy(cbuf
, (char *)command
, csize
);
3311 cbuf
[csize
-1] = '\0';