/** * tanprof * * Utility to trace system calls, signals and faults in a running process. * Given a pid, attaches to the process and prints the requested information. * At the end (after the traced process terminates or this process terminates) * prints a summary of the CPU times taken by the process and its children. * * This utility was written for Digital UNIX running on an Alpha machine. But * the code can be easily modified to suit other operating systems and * platforms. * * Compile: make tanprof * Usage: tanprof pid [-nosys] [-nosysent] [-nosysext] [-nosig] [-noflt] * Where * pid: pid of the process to trace * -nosys: do not trace entry/exit to system calls * -nosysent: do not trace entry to system calls * -nosysext: do not trace exit to system calls * -nosig: do not trace signals * -nosflt: do not trace faults * Example * tanprof 12345 : trace the process with pid 12345 for all * tanprof 12345 -nosys -nosig -noflt : trace for time information only. * Kill tanprof with sigterm to get time information. * * File: tanprof.c * Author: Tanmay K. Mohapatra * HTTP: http://tanmaykm.tripod.com/ */ #include #include #include #include #include #include #include #include #include #include #include /* Function prototypes */ static int setFlagsOnProc(int iFd, int iSysEnt, int iSysExt, int iSignal, int iFault); static int printSysCallInfo(long lWhatCall); static int printTimeInfo(prstatus_t *prstat); static int printSignalInfo(short iWhatSig, struct sigaction *ppr_action); static int printFaultInfo(long lWhatFault); void handleSig(int iSignal); /* Global used to store the last status. After the process exits, this info * is used to show the process statistics. */ prstatus_t prevstat; int main(int argc, char *argv[]) { int pid, fd, iRet, iSysEnt, iSysExt, iSig, iFlt; char sPidFile[256]; prstatus_t prstat; if (argc < 2) { printf("Usage: %s pid [-nosys] [-nosysent] [-nosysext] [-nosig] [-noflt]\n", argv[0]); return 1; } pid=atoi(argv[1]); for(iSysEnt=iSysExt=iSig=iFlt=1, iRet=argc; iRet > 2; iRet--) { if (!strcmp(argv[iRet-1], "-nosys")) iSysEnt = iSysExt = 0; if (!strcmp(argv[iRet-1], "-nosysent")) iSysEnt = 0; if (!strcmp(argv[iRet-1], "-nosysext")) iSysExt = 0; if (!strcmp(argv[iRet-1], "-nosig")) iSig = 0; if (!strcmp(argv[iRet-1], "-noflt")) iFlt = 0; } /* open the proc file */ sprintf(sPidFile, "/proc/%d", pid); if(0 > (fd = open(sPidFile, O_RDWR, 0))) { perror("Unable to open process"); exit(1); } /* set all flags */ if(0 != setFlagsOnProc(fd, iSysEnt, iSysExt, iSig, iFlt)) { perror("Unable to set some flags"); exit(1); } /* set the signal handler for yourself */ signal(SIGHUP, handleSig); signal(SIGKILL, handleSig); signal(SIGINT, handleSig); signal(SIGQUIT, handleSig); if (iSysEnt || iSysExt || iSig || iFlt) { /* wait for requested events only */ while((memset((char *)&prstat, 0, sizeof(prstatus_t))) && (-1 != (iRet=ioctl(fd, PIOCWSTOP, &prstat)))) { prevstat = prstat; if(PR_ISTOP == (prstat.pr_flags & PR_ISTOP)) { if(PR_SYSEXIT == prstat.pr_why) { printf("< "); printSysCallInfo(prstat.pr_what); } else if(PR_SYSENTRY == prstat.pr_why) { printf("> "); printSysCallInfo(prstat.pr_what); } else if(PR_FAULTED == prstat.pr_why) { printFaultInfo(prstat.pr_what); } else if(PR_SIGNALLED == prstat.pr_why) { printSignalInfo(prstat.pr_cursig ? prstat.pr_cursig : prstat.pr_what, &(prstat.pr_action)); } /* run the program again */ if(-1 == ioctl(fd, PIOCRUN, NULL)) { perror("Error returned on ioctl PIOCRUN"); exit(4); } } else if (PR_DEAD == prstat.pr_why) { printTimeInfo(&prstat); printf("\n"); break; } else { printf("unknown flag %d\n", prstat.pr_flags); } } } else { /* just do getstatus at regular intervals */ while((memset((char *)&prstat, 0, sizeof(prstatus_t))) && (-1 != (iRet=ioctl(fd, PIOCSTATUS, &prstat)))) { prevstat = prstat; usleep(1000*250); /* sleep for 250ms */ } } close(fd); if(-1 == iRet) { printf("Process probably exited.\n"); printTimeInfo(&prevstat); } return 0; } /** * sets the requested flags for the process. Apart from that, it sets the * run-on-last-close flag on so that this process can be killed without * affecting the traced process. * Returns 0 on success, -1 on failure */ static int setFlagsOnProc(int iFd, int iSysEnt, int iSysExt, int iSignal, int iFault) { int iRet; sysset_t sflags; sigset_t sigset; fltset_t fltset; iRet=0; prfillset(&sflags); if (iSysExt) { /* turn on all syscall flags */ if(-1 == (iRet=ioctl(iFd, PIOCSEXIT, &sflags))) { goto ERROR_HANDLER; } } if (iSysEnt) { if(-1 == (iRet=ioctl(iFd, PIOCSENTRY, &sflags))) { goto ERROR_HANDLER; } } if (iSignal) { /* turn on all the signal flags */ prfillset(&sigset); iRet=0; if(-1 == (iRet=ioctl(iFd, PIOCSTRACE, &sigset))) { goto ERROR_HANDLER; } } if(iFault) { /* turn on all the fault flags */ prfillset(&fltset); iRet=0; if(-1 == (iRet=ioctl(iFd, PIOCSFAULT, &fltset))) { goto ERROR_HANDLER; } } /* set the run-on-last-close flag on */ if(-1 == ioctl(iFd, PIOCSRLC, NULL)) { goto ERROR_HANDLER; } return 0; ERROR_HANDLER: return -1; } /** * prints the text representation of the fault. * This is a system dependent function. * For a new system add/remove the appropriate faults to the case statement. * returns 0 on success */ static int printFaultInfo(long lWhatFault) { printf("Fault "); switch(lWhatFault) { case FLTIOVF: printf("FLTARITH/FLTFPE/FLTIOVF\n"); break; case FLTBOUNDS: printf("FLTBOUNDS/FLTSTACK\n"); break; case FLTACCESS: printf("FLTACCESS\n"); break; case FLTPAGE: printf("FLTPAGE\n"); break; case FLTALIGN: printf("FLTALIGN\n"); break; case FLTTRACE: printf("FLTTRACE/FLTBPT\n"); break; case FLTBUGCK: printf("FLTBUGCK\n"); break; case FLTIZDIV: printf("FLTIZDEV/FLTGENT\n"); break; case FLTILL : printf("FLTILL/FLTPRIV/FLTOPDEC\n"); break; default: printf("unknown\n"); break; } return 0; } /** * prints the text representation of the signal. * If there is a signal handler registered for the signal, prints the address. * This is a system dependent function. * For a new system add/remove the appropriate signal to the case statement. * returns 0 on success */ static int printSignalInfo(short iWhatSig, struct sigaction *ppr_action) { printf("Signal "); switch(iWhatSig) { case SIGHUP: printf("SIGHUP"); break; case SIGINT: printf("SIGINT"); break; case SIGQUIT: printf("SIGQUIT"); break; case SIGILL: printf("SIGILL"); break; case SIGTRAP: printf("SIGTRAP"); break; case SIGABRT: printf("SIGABRT"); break; case SIGEMT: printf("SIGEMT"); break; case SIGFPE: printf("SIGFPE"); break; case SIGKILL: printf("SIGKILL"); break; case SIGBUS: printf("SIGBUS"); break; case SIGSEGV: printf("SIGSEGV"); break; case SIGSYS: printf("SIGSYS"); break; case SIGPIPE: printf("SIGPIPE"); break; case SIGALRM: printf("SIGALRM"); break; case SIGTERM: printf("SIGTERM"); break; case SIGURG: printf("SIGURG"); break; case SIGSTOP: printf("SIGSTOP"); break; case SIGTSTP: printf("SIGSTP"); break; case SIGCONT: printf("SIGCONT"); break; case SIGCHLD: printf("SIGCHLD"); break; case SIGTTIN: printf("SIGTTIN"); break; case SIGTTOU: printf("SIGTTOU"); break; case SIGPOLL: printf("SIGPOLL"); break; case SIGXCPU: printf("SIGSCPU"); break; case SIGXFSZ: printf("SIGXFSZ"); break; case SIGVTALRM: printf("SIGVTALRM"); break; case SIGPROF: printf("SIGPROF"); break; case SIGWINCH: printf("SIGWINCH"); break; case SIGINFO: printf("SIGINFO"); break; case SIGUSR1: printf("SIGUSR1"); break; case SIGUSR2: printf("SIGUSR2"); break; case SIGRESV: printf("SIGRESV"); break; default: printf("unknown %d", iWhatSig); break; } printf(" Handler %p\n", ppr_action ? ppr_action->sa_handler : 0); return 0; } /** * prints the text representation of the systemcall. * This is a system dependent function. * For a new system add/remove the appropriate systemcall to the case statement. * returns 0 on success */ static int printSysCallInfo(long lWhatCall) { switch(lWhatCall) { case SYS_syscall: printf("syscall\n"); break; case SYS_exit: printf("exit\n"); break; case SYS_fork: printf("fork\n"); break; case SYS_read: printf("read\n"); break; case SYS_write: printf("write\n"); break; case SYS_old_open: printf("old_open\n"); break; case SYS_close: printf("close\n"); break; case SYS_wait4: printf("wait4\n"); break; case SYS_old_creat: printf("old_creat\n"); break; case SYS_link: printf("link\n"); break; case SYS_unlink: printf("unlink\n"); break; case SYS_execv: printf("execv\n"); break; case SYS_chdir: printf("chdir\n"); break; case SYS_fchdir: printf("fchdir\n"); break; case SYS_mknod: printf("mknod\n"); break; case SYS_chmod: printf("chmod\n"); break; case SYS_chown: printf("chown\n"); break; case SYS_obreak: printf("obreak\n"); break; case SYS_getfsstat: printf("getfsstat\n"); break; case SYS_lseek: printf("lseek\n"); break; case SYS_getpid: printf("getpid\n"); break; case SYS_mount: printf("mount\n"); break; case SYS_unmount: printf("unmount\n"); break; case SYS_setuid: printf("setuid\n"); break; case SYS_getuid: printf("getuid\n"); break; case SYS_exec_with_loader: printf("exec_with_loader\n"); break; case SYS_ptrace: printf("ptrace\n"); break; #ifdef COMPAT_43 case SYS_nrecvmsg: printf("nrecvmsg\n"); break; case SYS_nsendmsg: printf("nsendmsg\n"); break; case SYS_nrecvfrom: printf("nrecvfrom\n"); break; case SYS_naccept: printf("naccept\n"); break; case SYS_ngetpeername: printf("ngetpeername\n"); break; case SYS_ngetsockname: printf("ngetsockname\n"); break; #else case SYS_recvmsg: printf("recvmsg\n"); break; case SYS_sendmsg: printf("sendmsg\n"); break; case SYS_recvfrom: printf("recvfrom\n"); break; case SYS_accept: printf("accept\n"); break; case SYS_getpeername: printf("getpeername\n"); break; case SYS_getsockname: printf("getsockname\n"); break; #endif case SYS_access: printf("access\n"); break; case SYS_chflags: printf("chflags\n"); break; case SYS_fchflags: printf("fchflags\n"); break; case SYS_sync: printf("sync\n"); break; case SYS_kill: printf("kill\n"); break; case SYS_old_stat: printf("old_stat\n"); break; case SYS_setpgid: printf("setpgid\n"); break; case SYS_old_lstat: printf("lstst\n"); break; case SYS_dup: printf("dup\n"); break; case SYS_pipe: printf("pipe\n"); break; case SYS_set_program_attributes: printf("set_program_attributes\n"); break; case SYS_profil: printf("profil\n"); break; case SYS_open: printf("open\n"); break; case SYS_getgid: printf("getgid\n"); break; case SYS_sigprocmask: printf("sigprocmask\n"); break; case SYS_getlogin: printf("getlogin\n"); break; case SYS_setlogin: printf("setlogin\n"); break; case SYS_acct: printf("acct\n"); break; case SYS_sigpending: printf("sigpending\n"); break; case SYS_classcntl: printf("classcntl\n"); break; case SYS_ioctl: printf("ioctl\n"); break; case SYS_reboot: printf("reboot\n"); break; case SYS_revoke: printf("revoke\n"); break; case SYS_symlink: printf("symlink\n"); break; case SYS_readlink: printf("readlink\n"); break; case SYS_execve: printf("execve\n"); break; case SYS_umask: printf("umask\n"); break; case SYS_chroot: printf("chroot\n"); break; case SYS_old_fstat: printf("old_fstat\n"); break; case SYS_getpgrp: printf("getpgrp\n"); break; case SYS_getpagesize: printf("getpagesize\n"); break; case SYS_mremap: printf("mremap\n"); break; case SYS_vfork: printf("vfork\n"); break; case SYS_stat: printf("stat\n"); break; case SYS_lstat: printf("lstat\n"); break; case SYS_sbrk: printf("sbrk\n"); break; case SYS_sstk: printf("sstk\n"); break; case SYS_mmap: printf("mmap\n"); break; case SYS_ovadvise: printf("ovadvise\n"); break; case SYS_munmap: printf("munmap\n"); break; case SYS_mprotect: printf("mprotect\n"); break; case SYS_madvise: printf("madvise\n"); break; case SYS_old_vhangup: printf("vhangup\n"); break; case SYS_kmodcall: printf("kmodcall\n"); break; case SYS_mincore: printf("mincore\n"); break; case SYS_getgroups: printf("getgroups\n"); break; case SYS_setgroups: printf("setgroups\n"); break; case SYS_old_getpgrp: printf("getpgrp\n"); break; case SYS_setpgrp: printf("setpgrp\n"); break; case SYS_setitimer: printf("setitimer\n"); break; case SYS_old_wait: printf("oldwait\n"); break; case SYS_table: printf("table\n"); break; case SYS_getitimer: printf("getitimer\n"); break; case SYS_gethostname: printf("gethostname\n"); break; case SYS_sethostname: printf("sethostname\n"); break; case SYS_getdtablesize: printf("getdtablesize\n"); break; case SYS_dup2: printf("dup2\n"); break; case SYS_fstat: printf("fstat\n"); break; case SYS_fcntl: printf("fcntl\n"); break; case SYS_select: printf("select\n"); break; case SYS_poll: printf("poll\n"); break; case SYS_fsync: printf("fsync\n"); break; case SYS_setpriority: printf("setpriority\n"); break; case SYS_socket: printf("socket\n"); break; case SYS_connect: printf("connect\n"); break; #ifdef COMPAT_43 case SYS_accept: printf("accept\n"); break; #else case SYS_old_accept: printf("old_accept\n"); break; #endif case SYS_getpriority: printf("getpriority\n"); break; #ifdef COMPAT_43 case SYS_send: printf("send\n"); break; case SYS_recv: printf("recv\n"); break; #else case SYS_old_send: printf("old_send\n"); break; case SYS_old_recv: printf("old_recv\n"); break; #endif case SYS_sigreturn: printf("sigreturn\n"); break; case SYS_bind: printf("bind\n"); break; case SYS_setsockopt: printf("setsockopt\n"); break; case SYS_listen: printf("listen\n"); break; case SYS_plock: printf("plock\n"); break; case SYS_old_sigvec: printf("sigvec\n"); break; case SYS_old_sigblock: printf("sigblock\n"); break; case SYS_old_sigsetmask: printf("sigsetmask\n"); break; case SYS_sigsuspend: printf("sigsuspend\n"); break; case SYS_sigstack: printf("sigstack\n"); break; #ifdef COMPAT_43 case SYS_recvmsg: printf("recvmsg\n"); break; case SYS_sendmsg: printf("sendmsg\n"); break; #else case SYS_old_recvmsg: printf("old_recvmsg\n"); break; case SYS_old_sendmsg: printf("old_sendmsg\n"); break; #endif case SYS_gettimeofday: printf("gettimeofday\n"); break; case SYS_getrusage: printf("getrusage\n"); break; case SYS_getsockopt: printf("getsockopt\n"); break; case SYS_readv: printf("readv\n"); break; case SYS_writev: printf("writev\n"); break; case SYS_settimeofday: printf("settimeofday\n"); break; case SYS_fchown: printf("fchown\n"); break; case SYS_fchmod: printf("fchmod\n"); break; #ifdef COMPAT_43 case SYS_recvfrom: printf("recvfrom\n"); break; #else case SYS_old_recvfrom: printf("old_recvfrom\n"); break; #endif case SYS_setreuid: printf("setreuid\n"); break; case SYS_setregid: printf("setregid\n"); break; case SYS_rename: printf("rename\n"); break; case SYS_truncate: printf("truncate\n"); break; case SYS_ftruncate: printf("ftruncate\n"); break; case SYS_flock: printf("flock\n"); break; case SYS_setgid: printf("setgid\n"); break; case SYS_sendto: printf("sendto\n"); break; case SYS_shutdown: printf("shutdown\n"); break; case SYS_socketpair: printf("socketpair\n"); break; case SYS_mkdir: printf("mkdir\n"); break; case SYS_rmdir: printf("rmdir\n"); break; case SYS_utimes: printf("utimes\n"); break; case SYS_adjtime: printf("adjtime\n"); break; #ifdef COMPAT_43 case SYS_getpeername: printf("getpeername\n"); break; #else case SYS_old_getpeername: printf("old_getpeername\n"); break; #endif case SYS_gethostid: printf("gethostid\n"); break; case SYS_sethostid: printf("sethostid\n"); break; case SYS_getrlimit: printf("getrlimit\n"); break; case SYS_setrlimit: printf("setrlimit\n"); break; case SYS_old_killpg: printf("old_killpg\n"); break; case SYS_setsid: printf("setsid\n"); break; case SYS_quotactl: printf("quotactl\n"); break; case SYS_oldquota: printf("oldquota\n"); break; #ifdef COMPAT_43 case SYS_getsockname: printf("getsockname\n"); break; #else case SYS_old_getsockname: printf("old_getsockname\n"); break; #endif case SYS_pread: printf("pread\n"); break; case SYS_pwrite : printf("pwrite\n"); break; case SYS_pid_block : printf("pid_block\n"); break; case SYS_pid_unblock: printf("pid_unblock\n"); break; case SYS_signal_urti: printf("signal_urti\n"); break; case SYS_sigaction: printf("sigaction\n"); break; case SYS_sigwaitprim: printf("sigwaitprim\n"); break; case SYS_nfssvc: printf("nfssvc\n"); break; case SYS_getdirentries: printf("getdirentries\n"); break; case SYS_statfs: printf("statfs\n"); break; case SYS_fstatfs: printf("fstatfs\n"); break; case SYS_async_daemon: printf("async_daemon\n"); break; case SYS_getfh: printf("getfh\n"); break; case SYS_getdomainname: printf("getdomainname\n"); break; case SYS_setdomainname: printf("setdomainname\n"); break; case SYS_exportfs: printf("exportfs\n"); break; case SYS_alt_plock: printf("alt_plock\n"); break; case SYS_getmnt: printf("getmnt\n"); break; case SYS_alt_sigpending: printf("alt_sigpending\n"); break; case SYS_alt_setsid: printf("alt_setsid\n"); break; case SYS_swapon: printf("swapon\n"); break; #ifdef SYS_msgsys case SYS_msgsys: printf("msgsys\n"); break; #else case SYS_msgctl: printf("msgctl\n"); break; case SYS_msgget: printf("msgget\n"); break; case SYS_msgrcv: printf("msgrcv\n"); break; case SYS_msgsnd: printf("msgsnd\n"); break; #endif case SYS_semctl: printf("semctl\n"); break; case SYS_semget: printf("semget\n"); break; case SYS_semop: printf("semop\n"); break; case SYS_uname: printf("uname\n"); break; case SYS_lchown: printf("lchown\n"); break; #ifdef SYS_shmsys case SYS_shmsys: printf("shmsys\n"); break; #else case SYS_shmat: printf("shmat\n"); break; case SYS_shmctl: printf("shmctl\n"); break; case SYS_shmdt: printf("shmdt\n"); break; case SYS_shmget: printf("shmget\n"); break; #endif #ifdef SYS_mvalid case SYS_mvalid: printf("mvalid\n"); break; #endif #ifdef SYS_getaddressconf case SYS_getaddressconf: printf("getaddressconf\n"); break; #endif #ifdef SYS_msleep case SYS_msleep: printf("msleep\n"); break; #endif #ifdef SYS_mwakeup case SYS_mwakeup: printf("mwakeup\n"); break; #endif #ifdef SYS_msync case SYS_msync: printf("msync\n"); break; #endif case SYS_signal: printf("signal\n"); break; case SYS_utc_gettime: printf("utc_gettime\n"); break; #ifdef SYS_utc_adjtime case SYS_utc_adjtime: printf("utc_adjtime\n"); break; #endif #ifdef SYS_security case SYS_security: printf("security\n"); break; #endif #ifdef SYS_kloadcall case SYS_kloadcall: printf("kloadcall\n"); break; #endif #ifdef SYS_getpid case SYS_getpgid: printf("getpgid\n"); break; #endif #ifdef SYS_getsid case SYS_getsid: printf("getsid\n"); break; #endif case SYS_sigaltstack: printf("sigaltstack\n"); break; #ifdef SYS_waitid case SYS_waitid: printf("waitid\n"); break; #endif #ifdef SYS_priocntlset case SYS_priocntlset: printf("priocntlset\n"); break; #endif #ifdef SYS_sigsendset case SYS_sigsendset: printf("sigsendset\n"); break; #endif #ifdef SYS_set_speculative case SYS_set_speculative: printf("set_speculative\n"); break; #endif #ifdef SYS_msfs_syscall case SYS_msfs_syscall: printf("msfs_syscall\n"); break; #endif #ifdef SYS_sysinfo case SYS_sysinfo: printf("sysinfo\n"); break; #endif case SYS_uadmin: printf("uadmin\n"); break; #ifdef SYS_fuser case SYS_fuser: printf("fuser\n"); break; #endif #ifdef SYS_proplist_syscall case SYS_proplist_syscall: printf("proplist_syscall\n"); break; #endif case SYS_ntp_adjtime: printf("ntp_adjtime\n"); break; case SYS_ntp_gettime: printf("ntp_gettime\n"); break; case SYS_pathconf: printf("pathconv\n"); break; case SYS_fpathconf: printf("fpathconv\n"); break; #ifdef SYS_uswitch case SYS_uswitch: printf("uswitch\n"); break; #endif #ifdef SYS_usleep_thread case SYS_usleep_thread: printf("usleep_thread\n"); break; #endif #ifdef SYS_audcntl case SYS_audcntl: printf("audcntl\n"); break; #endif #ifdef SYS_audgen case SYS_audgen: printf("audgen\n"); break; #endif case SYS_sysfs: printf("sysfs\n"); break; #ifdef SYS_subsys_info case SYS_subsys_info: printf("subsys_info\n"); break; #endif #ifdef SYS_getsysinfo case SYS_getsysinfo: printf("getsysinfo\n"); break; #endif #ifdef SYS_setsysinfo case SYS_setsysinfo: printf("setsysinfo\n"); break; #endif #ifdef SYS_afs_syscall case SYS_afs_syscall: printf("afs_syscall\n"); break; #endif #ifdef SYS_swapctl case SYS_swapctl: printf("swapctl\n"); break; #endif #ifdef SYS_memcntl case SYS_memcntl: printf("memcntl\n"); break; #endif #ifdef SYS_fdatasync case SYS_fdatasync: printf("fdatasync\n"); break; #endif default: printf("unknown system call\n"); break; } return 0; } /** * Signal handler for this process. * If terminated by the user, this routine prints the process statistics * before going down. */ void handleSig(int iSignal) { printf("Stopped by "); printSignalInfo(iSignal , 0); printTimeInfo(&prevstat); exit(0); } /** * Prints the CPU times for the traced process and its children */ static int printTimeInfo(prstatus_t *prstat) { printf("CPU Times(sec.milli.micro)\n"); printf("Process : User[%d.%.3d.%.3d] System[%d.%.3d.%.3d]\n", prstat->pr_utime.tv_sec, prstat->pr_utime.tv_nsec/1000000, (prstat->pr_utime.tv_nsec-(prstat->pr_utime.tv_nsec/1000000)*1000000)/1000, prstat->pr_stime.tv_sec, prstat->pr_stime.tv_nsec/1000000, (prstat->pr_stime.tv_nsec-(prstat->pr_stime.tv_nsec/1000000)*1000000)/1000); printf("Children: User[%d.%.3d.%.3d] System[%d.%.3d.%.3d]\n", prstat->pr_cutime.tv_sec, prstat->pr_cutime.tv_nsec/1000000, (prstat->pr_cutime.tv_nsec-(prstat->pr_cutime.tv_nsec/1000000)*1000000)/1000, prstat->pr_cstime.tv_sec, prstat->pr_cstime.tv_nsec/1000000, (prstat->pr_cstime.tv_nsec-(prstat->pr_cstime.tv_nsec/1000000)*1000000)/1000); return 0; }