summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordchagin <dchagin@FreeBSD.org>2011-02-25 22:07:23 +0000
committerdchagin <dchagin@FreeBSD.org>2011-02-25 22:07:23 +0000
commitd247142d62d5744afdae37205c0bac42f8b11d65 (patch)
treeac8ecd0ba0f9a7208a4a9a3a30c6a6e63b8cd4f0
parent44c082b543392a3ffec8854bf2fcbb71a398e243 (diff)
downloadFreeBSD-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.c139
-rw-r--r--usr.bin/ktrace/ktrace.c2
-rw-r--r--usr.bin/ktrace/ktrace.h4
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"
OpenPOWER on IntegriCloud