diff options
author | dchagin <dchagin@FreeBSD.org> | 2011-02-25 22:07:23 +0000 |
---|---|---|
committer | dchagin <dchagin@FreeBSD.org> | 2011-02-25 22:07:23 +0000 |
commit | d247142d62d5744afdae37205c0bac42f8b11d65 (patch) | |
tree | ac8ecd0ba0f9a7208a4a9a3a30c6a6e63b8cd4f0 | |
parent | 44c082b543392a3ffec8854bf2fcbb71a398e243 (diff) | |
download | FreeBSD-src-d247142d62d5744afdae37205c0bac42f8b11d65.zip FreeBSD-src-d247142d62d5744afdae37205c0bac42f8b11d65.tar.gz |
Teach kdump to understand sv_flags records in the trace files.
MFC after: 1 Month.
-rw-r--r-- | usr.bin/kdump/kdump.c | 139 | ||||
-rw-r--r-- | usr.bin/ktrace/ktrace.c | 2 | ||||
-rw-r--r-- | usr.bin/ktrace/ktrace.h | 4 |
3 files changed, 128 insertions, 17 deletions
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c index 852660b..3b61f02 100644 --- a/usr.bin/kdump/kdump.c +++ b/usr.bin/kdump/kdump.c @@ -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 @@ invalid: 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); } diff --git a/usr.bin/ktrace/ktrace.c b/usr.bin/ktrace/ktrace.c index 962dad3..fa2fa1a 100644 --- a/usr.bin/ktrace/ktrace.c +++ b/usr.bin/ktrace/ktrace.c @@ -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); diff --git a/usr.bin/ktrace/ktrace.h b/usr.bin/ktrace/ktrace.h index a5bfcad..5e38d68 100644 --- a/usr.bin/ktrace/ktrace.h +++ b/usr.bin/ktrace/ktrace.h @@ -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" |