* Copyright (c) 1989 The Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* @(#)kern_ktrace.c 1.3 (Berkeley) %G%
extern char *syscallnames
[];
register struct ktr_header
*kth
;
MALLOC(kth
, struct ktr_header
*, sizeof (struct ktr_header
),
microtime(&kth
->ktr_time
);
kth
->ktr_pid
= u
.u_procp
->p_pid
;
bcopy(u
.u_comm
, kth
->ktr_comm
, MAXCOMLEN
);
printf("ktrgetheader: can't malloc header for %d\n", type
);
ktrsyscall(ip
, code
, narg
)
struct ktr_header
*kth
= ktrgetheader(KTR_SYSCALL
);
register len
= sizeof(struct ktr_syscall
) + (narg
* sizeof(int));
MALLOC(ktp
, struct ktr_syscall
*, len
, M_TEMP
, M_WAITOK
);
printf("lost syscall trace - no buffer\n"); /* DEBUG */
argp
= (int *)((char *)ktp
+ sizeof(struct ktr_syscall
));
for (i
= 0; i
< narg
; i
++)
kth
->ktr_buf
= (caddr_t
)ktp
;
struct ktr_header
*kth
= ktrgetheader(KTR_SYSRET
);
MALLOC(ktp
, struct ktr_sysret
*, sizeof(struct ktr_sysret
),
printf("lost syscall ret - no buffer\n"); /* DEBUG */
ktp
->ktr_eosys
= u
.u_eosys
;
ktp
->ktr_error
= u
.u_error
;
ktp
->ktr_retval
= u
.u_r
.r_val1
; /* what about val2 ? */
kth
->ktr_buf
= (caddr_t
)ktp
;
kth
->ktr_len
= sizeof(struct ktr_sysret
);
struct ktr_header
*kth
= ktrgetheader(KTR_NAMEI
);
kth
->ktr_len
= strlen(path
);
ktrgenio(ip
, fd
, rw
, iov
, len
)
register struct iovec
*iov
;
struct ktr_header
*kth
= ktrgetheader(KTR_GENIO
);
register struct ktr_genio
*ktp
;
register int resid
= len
, cnt
;
if (kth
== NULL
|| u
.u_error
)
MALLOC(ktp
, struct ktr_genio
*, sizeof(struct ktr_genio
) + len
,
printf("lost ktr_genio data buffer\n");
cp
= (caddr_t
)((char *)ktp
+ sizeof (struct ktr_genio
));
if ((cnt
= iov
->iov_len
) > resid
)
if (copyin(iov
->iov_base
, cp
, cnt
))
kth
->ktr_buf
= (caddr_t
)ktp
;
kth
->ktr_len
= sizeof (struct ktr_genio
) + len
;
register struct inode
*ip
= NULL
;
} *uap
= (struct a
*)u
.u_ap
;
register struct nameidata
*ndp
= &u
.u_nd
;
register int ops
= uap
->ops
&0x3;
register int facs
= uap
->facs
;
* Until security implications are thought through,
* limit tracing to root (unless ktrace_nocheck is set).
if (!ktrace_nocheck
&& (u
.u_error
= suser(u
.u_cred
, &u
.u_acflag
)))
if (ops
!= KTROP_CLEAR
) {
* an operation which requires a file argument.
ndp
->ni_nameiop
= LOOKUP
| FOLLOW
;
ndp
->ni_segflg
= UIO_USERSPACE
;
ndp
->ni_dirp
= uap
->fname
;
if (access(ip
, IWRITE
)) {
if ((ip
->i_mode
&IFMT
) != IFREG
) {
if (ip
->i_fs
->fs_ronly
) {
* Clear all uses of the tracefile
if (ops
== KTROP_CLEARFILE
) {
for (p
= allproc
; p
!= NULL
; p
= p
->p_nxt
) {
* need something to (un)trace
for (p
= pg
->pg_mem
; p
!= NULL
; p
= p
->p_pgrpnxt
)
if (uap
->ops
&KTROP_INHERITFLAG
)
ret
|= ktrsetchildren(p
, ops
, facs
, ip
);
ret
|= ktrops(p
, ops
, facs
, ip
);
if (uap
->ops
&KTROP_INHERITFLAG
)
ret
|= ktrsetchildren(p
, ops
, facs
, ip
);
ret
|= ktrops(p
, ops
, facs
, ip
);
if (u
.u_uid
&& u
.u_uid
!= p
->p_uid
)
* if trace file already in use, relinquish
if ((p
->p_traceflag
&= ~facs
) == 0) {
if (p
->p_tracep
!= NULL
) {
ktrsetchildren(top
, ops
, facs
, ip
)
if ((ret
|= ktrops(p
, ops
, facs
, ip
)) && ops
== KTROP_SET
)
* If this process has children, descend to them next,
* otherwise do any siblings, and if done with this level,
* follow back up the tree (but not past top).
register struct inode
*ip
;
u
.u_error
= rdwri(UIO_WRITE
, ip
, (caddr_t
)kth
,
sizeof(struct ktr_header
), ip
->i_size
, 1, (int *)0);
itrunc(ip
, (u_long
)osize
);
u
.u_error
= rdwri(UIO_WRITE
, ip
, kth
->ktr_buf
,
kth
->ktr_len
, ip
->i_size
, 1, (int *)0);
itrunc(ip
, (u_long
)osize
);