Teach kdump to understand sv_flags records in the trace files.

MFC after:	1 Month.
This commit is contained in:
Dmitry Chagin 2011-02-25 22:07:23 +00:00
parent 7705d4b24a
commit 7144d36fab
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=219043
3 changed files with 128 additions and 17 deletions

View File

@ -55,7 +55,9 @@ extern int errno;
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/sysent.h>
#include <sys/un.h>
#include <sys/queue.h>
#ifdef IPX
#include <sys/types.h>
#include <netipx/ipx.h>
@ -81,15 +83,17 @@ extern int errno;
#include "ktrace.h"
#include "kdump_subr.h"
u_int abidump(struct ktr_header *);
int fetchprocinfo(struct ktr_header *, u_int *);
int fread_tail(void *, int, int);
void dumpheader(struct ktr_header *);
void ktrsyscall(struct ktr_syscall *);
void ktrsysret(struct ktr_sysret *);
void ktrsyscall(struct ktr_syscall *, u_int);
void ktrsysret(struct ktr_sysret *, u_int);
void ktrnamei(char *, int);
void hexdump(char *, int, int);
void visdump(char *, int, int);
void ktrgenio(struct ktr_genio *, int);
void ktrpsig(struct ktr_psig *);
void ktrpsig(struct ktr_psig *, u_int);
void ktrcsw(struct ktr_csw *);
void ktruser(int, unsigned char *);
void ktrsockaddr(struct sockaddr *);
@ -100,13 +104,22 @@ void sockfamilyname(int);
const char *ioctlname(u_long);
int timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata,
resolv = 0;
resolv = 0, abiflag = 0;
const char *tracefile = DEF_TRACEFILE;
struct ktr_header ktr_header;
#define TIME_FORMAT "%b %e %T %Y"
#define eqs(s1, s2) (strcmp((s1), (s2)) == 0)
struct proc_info
{
TAILQ_ENTRY(proc_info) info;
u_int sv_flags;
pid_t pid;
};
TAILQ_HEAD(trace_procs, proc_info) trace_procs;
int
main(int argc, char *argv[])
{
@ -115,11 +128,15 @@ main(int argc, char *argv[])
int trpoints = ALL_POINTS;
int drop_logged;
pid_t pid = 0;
u_int sv_flags;
(void) setlocale(LC_CTYPE, "");
while ((ch = getopt(argc,argv,"f:dElm:np:HRrsTt:")) != -1)
while ((ch = getopt(argc,argv,"f:dElm:np:AHRrsTt:")) != -1)
switch((char)ch) {
case 'A':
abiflag = 1;
break;
case 'f':
tracefile = optarg;
break;
@ -173,6 +190,7 @@ main(int argc, char *argv[])
errx(1, "%s", strerror(ENOMEM));
if (!freopen(tracefile, "r", stdin))
err(1, "%s", tracefile);
TAILQ_INIT(&trace_procs);
drop_logged = 0;
while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
if (ktr_header.ktr_type & KTR_DROP) {
@ -205,6 +223,9 @@ main(int argc, char *argv[])
}
if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
errx(1, "data too short");
if (fetchprocinfo(&ktr_header, (u_int *)m) != 0)
continue;
sv_flags = abidump(&ktr_header);
if (pid && ktr_header.ktr_pid != pid)
continue;
if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
@ -212,10 +233,10 @@ main(int argc, char *argv[])
drop_logged = 0;
switch (ktr_header.ktr_type) {
case KTR_SYSCALL:
ktrsyscall((struct ktr_syscall *)m);
ktrsyscall((struct ktr_syscall *)m, sv_flags);
break;
case KTR_SYSRET:
ktrsysret((struct ktr_sysret *)m);
ktrsysret((struct ktr_sysret *)m, sv_flags);
break;
case KTR_NAMEI:
case KTR_SYSCTL:
@ -225,7 +246,7 @@ main(int argc, char *argv[])
ktrgenio((struct ktr_genio *)m, ktrlen);
break;
case KTR_PSIG:
ktrpsig((struct ktr_psig *)m);
ktrpsig((struct ktr_psig *)m, sv_flags);
break;
case KTR_CSW:
ktrcsw((struct ktr_csw *)m);
@ -258,6 +279,84 @@ fread_tail(void *buf, int size, int num)
return (i);
}
int
fetchprocinfo(struct ktr_header *kth, u_int *flags)
{
struct proc_info *pi;
switch (kth->ktr_type) {
case KTR_PROCCTOR:
TAILQ_FOREACH(pi, &trace_procs, info) {
if (pi->pid == kth->ktr_pid) {
TAILQ_REMOVE(&trace_procs, pi, info);
break;
}
}
pi = malloc(sizeof(struct proc_info));
if (pi == NULL)
errx(1, "%s", strerror(ENOMEM));
pi->sv_flags = *flags;
pi->pid = kth->ktr_pid;
TAILQ_INSERT_TAIL(&trace_procs, pi, info);
return (1);
case KTR_PROCDTOR:
TAILQ_FOREACH(pi, &trace_procs, info) {
if (pi->pid == kth->ktr_pid) {
TAILQ_REMOVE(&trace_procs, pi, info);
free(pi);
break;
}
}
return (1);
}
return (0);
}
u_int
abidump(struct ktr_header *kth)
{
struct proc_info *pi;
const char *abi;
const char *arch;
u_int flags = 0;
TAILQ_FOREACH(pi, &trace_procs, info) {
if (pi->pid == kth->ktr_pid) {
flags = pi->sv_flags;
break;
}
}
if (abiflag == 0)
return (flags);
switch (flags & SV_ABI_MASK) {
case SV_ABI_LINUX:
abi = "L";
break;
case SV_ABI_FREEBSD:
abi = "F";
break;
default:
abi = "U";
break;
}
if (flags != 0) {
if (flags & SV_LP64)
arch = "64";
else
arch = "32";
} else
arch = "00";
printf("%s%s ", abi, arch);
return (flags);
}
void
dumpheader(struct ktr_header *kth)
{
@ -293,6 +392,10 @@ dumpheader(struct ktr_header *kth)
case KTR_SYSCTL:
type = "SCTL";
break;
case KTR_PROCCTOR:
/* FALLTHROUGH */
case KTR_PROCDTOR:
return;
default:
(void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
type = unknown;
@ -337,19 +440,21 @@ dumpheader(struct ktr_header *kth)
int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]);
void
ktrsyscall(struct ktr_syscall *ktr)
ktrsyscall(struct ktr_syscall *ktr, u_int flags)
{
int narg = ktr->ktr_narg;
register_t *ip;
if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0)
if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
(ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0))
(void)printf("[%d]", ktr->ktr_code);
else
(void)printf("%s", syscallnames[ktr->ktr_code]);
ip = &ktr->ktr_args[0];
if (narg) {
char c = '(';
if (fancy) {
if (fancy &&
(flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
#define print_number(i,n,c) do { \
if (decimal) \
@ -807,13 +912,14 @@ ktrsyscall(struct ktr_syscall *ktr)
}
void
ktrsysret(struct ktr_sysret *ktr)
ktrsysret(struct ktr_sysret *ktr, u_int flags)
{
register_t ret = ktr->ktr_retval;
int error = ktr->ktr_error;
int code = ktr->ktr_code;
if (code >= nsyscalls || code < 0)
if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
(code >= nsyscalls || code < 0))
(void)printf("[%d] ", code);
else
(void)printf("%s ", syscallnames[code]);
@ -987,9 +1093,10 @@ const char *signames[] = {
};
void
ktrpsig(struct ktr_psig *psig)
ktrpsig(struct ktr_psig *psig, u_int flags)
{
if (psig->signo > 0 && psig->signo < NSIG)
if ((flags & SV_ABI_MASK) == SV_ABI_FREEBSD &&
psig->signo > 0 && psig->signo < NSIG)
(void)printf("SIG%s ", signames[psig->signo]);
else
(void)printf("SIG %d ", psig->signo);
@ -1367,7 +1474,7 @@ ktrstruct(char *buf, size_t buflen)
void
usage(void)
{
fprintf(stderr, "usage: kdump [-dEnlHRrsT] [-f trfile] "
fprintf(stderr, "usage: kdump [-dEnlHRrsTA] [-f trfile] "
"[-m maxdata] [-p pid] [-t trstr]\n");
exit(1);
}

View File

@ -159,6 +159,8 @@ main(int argc, char *argv[])
(void)umask(omask);
(void)close(fd);
trpoints |= PROC_ABI_POINTS;
if (*argv) {
if (ktrace(tracefile, ops, trpoints, getpid()) < 0)
err(1, "%s", tracefile);

View File

@ -34,7 +34,9 @@
KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_USER | \
KTRFAC_STRUCT | KTRFAC_SYSCTL)
#define ALL_POINTS (DEF_POINTS | KTRFAC_CSW)
#define PROC_ABI_POINTS (KTRFAC_PROCCTOR | KTRFAC_PROCDTOR)
#define ALL_POINTS (DEF_POINTS | KTRFAC_CSW | PROC_ABI_POINTS)
#define DEF_TRACEFILE "ktrace.out"