diff options
author | Dmitry Chagin <dchagin@FreeBSD.org> | 2011-02-25 22:07:23 +0000 |
---|---|---|
committer | Dmitry Chagin <dchagin@FreeBSD.org> | 2011-02-25 22:07:23 +0000 |
commit | 7144d36faba30670276f646f414e4d0c52c9ffd3 (patch) | |
tree | ac8ecd0ba0f9a7208a4a9a3a30c6a6e63b8cd4f0 /usr.bin/kdump | |
parent | 7705d4b24a262d1a0fb4017808b65e3b11bfa869 (diff) | |
download | src-7144d36faba30670276f646f414e4d0c52c9ffd3.tar.gz src-7144d36faba30670276f646f414e4d0c52c9ffd3.zip |
Teach kdump to understand sv_flags records in the trace files.
MFC after: 1 Month.
Notes
Notes:
svn path=/head/; revision=219043
Diffstat (limited to 'usr.bin/kdump')
-rw-r--r-- | usr.bin/kdump/kdump.c | 139 |
1 files changed, 123 insertions, 16 deletions
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c index 852660b1c758..3b61f022eb03 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); } |