svn commit: r220267 - in stable/8/usr.bin: kdump ktrace
Dmitry Chagin
dchagin at FreeBSD.org
Sat Apr 2 08:29:03 UTC 2011
Author: dchagin
Date: Sat Apr 2 08:29:02 2011
New Revision: 220267
URL: http://svn.freebsd.org/changeset/base/220267
Log:
MFC r219043:
Teach kdump to understand sv_flags records in the trace files.
MFC r219044:
Update manual page to reflect latest changes of ABI description support.
MFC r219138:
Teach kdump to understand linux syscalls names too.
Fix bug introduced in r219043: the kernel always dump native
signal numbers, so no need to check the ABI in ktrpsig().
Added:
stable/8/usr.bin/kdump/linux_syscalls.conf
- copied unchanged from r219138, head/usr.bin/kdump/linux_syscalls.conf
Modified:
stable/8/usr.bin/kdump/Makefile
stable/8/usr.bin/kdump/kdump.1
stable/8/usr.bin/kdump/kdump.c
stable/8/usr.bin/ktrace/ktrace.c
stable/8/usr.bin/ktrace/ktrace.h
Directory Properties:
stable/8/usr.bin/kdump/ (props changed)
stable/8/usr.bin/ktrace/ (props changed)
Modified: stable/8/usr.bin/kdump/Makefile
==============================================================================
--- stable/8/usr.bin/kdump/Makefile Sat Apr 2 07:01:09 2011 (r220266)
+++ stable/8/usr.bin/kdump/Makefile Sat Apr 2 08:29:02 2011 (r220267)
@@ -1,13 +1,21 @@
# @(#)Makefile 8.1 (Berkeley) 6/6/93
# $FreeBSD$
+.if (${MACHINE_ARCH} == "amd64")
+SFX= 32
+.endif
+
.PATH: ${.CURDIR}/../ktrace
PROG= kdump
SRCS= kdump.c ioctl.c kdump_subr.c subr.c
CFLAGS+= -I${.CURDIR}/../ktrace -I${.CURDIR} -I${.CURDIR}/../..
-CLEANFILES= ioctl.c kdump_subr.c
+.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386"
+SRCS+= linux_syscalls.c
+.endif
+
+CLEANFILES= ioctl.c kdump_subr.c linux_syscalls.c
ioctl.c: mkioctls
sh ${.CURDIR}/mkioctls ${DESTDIR}/usr/include > ${.TARGET}
@@ -15,4 +23,10 @@ ioctl.c: mkioctls
kdump_subr.c: mksubr
sh ${.CURDIR}/mksubr ${DESTDIR}/usr/include > ${.TARGET}
+linux_syscalls.c:
+ /bin/sh ${.CURDIR}/../../sys/kern/makesyscalls.sh \
+ ${.CURDIR}/../../sys/${MACHINE_ARCH}/linux${SFX}/syscalls.master ${.CURDIR}/linux_syscalls.conf
+ echo "int nlinux_syscalls = sizeof(linux_syscallnames) / sizeof(linux_syscallnames[0]);" \
+ >> linux_syscalls.c
+
.include <bsd.prog.mk>
Modified: stable/8/usr.bin/kdump/kdump.1
==============================================================================
--- stable/8/usr.bin/kdump/kdump.1 Sat Apr 2 07:01:09 2011 (r220266)
+++ stable/8/usr.bin/kdump/kdump.1 Sat Apr 2 08:29:02 2011 (r220267)
@@ -40,7 +40,7 @@
.Nd display kernel trace data
.Sh SYNOPSIS
.Nm
-.Op Fl dEnlHRsT
+.Op Fl dEnlHRsTA
.Op Fl f Ar trfile
.Op Fl m Ar maxdata
.Op Fl p Ar pid
@@ -103,6 +103,8 @@ GIDs, dates etc. symbolically instead of
Suppress display of I/O data.
.It Fl T
Display absolute timestamps for each entry (seconds since epoch).
+.It Fl A
+Display description of the ABI of traced process.
.It Fl t Ar trstr
See the
.Fl t
Modified: stable/8/usr.bin/kdump/kdump.c
==============================================================================
--- stable/8/usr.bin/kdump/kdump.c Sat Apr 2 07:01:09 2011 (r220266)
+++ stable/8/usr.bin/kdump/kdump.c Sat Apr 2 08:29:02 2011 (r220267)
@@ -59,7 +59,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>
@@ -85,10 +87,12 @@ 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);
@@ -104,13 +108,57 @@ 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)
+#define print_number(i,n,c) do { \
+ if (decimal) \
+ printf("%c%ld", c, (long)*i); \
+ else \
+ printf("%c%#lx", c, (long)*i); \
+ i++; \
+ n--; \
+ c = ','; \
+ } while (0);
+
+#if defined(__amd64__) || defined(__i386__)
+
+void linux_ktrsyscall(struct ktr_syscall *);
+void linux_ktrsysret(struct ktr_sysret *);
+extern char *linux_syscallnames[];
+extern int nlinux_syscalls;
+
+/*
+ * from linux.h
+ * Linux syscalls return negative errno's, we do positive and map them
+ */
+static int bsd_to_linux_errno[ELAST + 1] = {
+ -0, -1, -2, -3, -4, -5, -6, -7, -8, -9,
+ -10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
+ -20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
+ -30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
+ -90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
+ -100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
+ -110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
+ -116, -66, -6, -6, -6, -6, -6, -37, -38, -9,
+ -6, -6, -43, -42, -75,-125, -84, -95, -16, -74,
+ -72, -67, -71
+};
+#endif
+
+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[])
{
@@ -119,11 +167,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;
@@ -177,6 +229,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) {
@@ -209,6 +262,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)
@@ -216,10 +272,20 @@ main(int argc, char *argv[])
drop_logged = 0;
switch (ktr_header.ktr_type) {
case KTR_SYSCALL:
- ktrsyscall((struct ktr_syscall *)m);
+#if defined(__amd64__) || defined(__i386__)
+ if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
+ linux_ktrsyscall((struct ktr_syscall *)m);
+ else
+#endif
+ ktrsyscall((struct ktr_syscall *)m, sv_flags);
break;
case KTR_SYSRET:
- ktrsysret((struct ktr_sysret *)m);
+#if defined(__amd64__) || defined(__i386__)
+ if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
+ linux_ktrsysret((struct ktr_sysret *)m);
+ else
+#endif
+ ktrsysret((struct ktr_sysret *)m, sv_flags);
break;
case KTR_NAMEI:
case KTR_SYSCTL:
@@ -262,6 +328,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)
{
@@ -297,6 +441,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;
@@ -341,30 +489,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) {
-
-#define print_number(i,n,c) do { \
- if (decimal) \
- (void)printf("%c%ld", c, (long)*i); \
- else \
- (void)printf("%c%#lx", c, (long)*i); \
- i++; \
- n--; \
- c = ','; \
- } while (0);
-
+ if (fancy &&
+ (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
if (ktr->ktr_code == SYS_ioctl) {
const char *cp;
print_number(ip,narg,c);
@@ -811,13 +950,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]);
@@ -1365,10 +1505,71 @@ invalid:
printf("invalid record\n");
}
+#if defined(__amd64__) || defined(__i386__)
+void
+linux_ktrsyscall(struct ktr_syscall *ktr)
+{
+ int narg = ktr->ktr_narg;
+ register_t *ip;
+
+ if (ktr->ktr_code >= nlinux_syscalls || ktr->ktr_code < 0)
+ printf("[%d]", ktr->ktr_code);
+ else
+ printf("%s", linux_syscallnames[ktr->ktr_code]);
+ ip = &ktr->ktr_args[0];
+ if (narg) {
+ char c = '(';
+ while (narg > 0)
+ print_number(ip, narg, c);
+ putchar(')');
+ }
+ putchar('\n');
+}
+
+void
+linux_ktrsysret(struct ktr_sysret *ktr)
+{
+ register_t ret = ktr->ktr_retval;
+ int error = ktr->ktr_error;
+ int code = ktr->ktr_code;
+
+ if (code >= nlinux_syscalls || code < 0)
+ printf("[%d] ", code);
+ else
+ printf("%s ", linux_syscallnames[code]);
+
+ if (error == 0) {
+ if (fancy) {
+ printf("%ld", (long)ret);
+ if (ret < 0 || ret > 9)
+ printf("/%#lx", (long)ret);
+ } else {
+ if (decimal)
+ printf("%ld", (long)ret);
+ else
+ printf("%#lx", (long)ret);
+ }
+ } else if (error == ERESTART)
+ printf("RESTART");
+ else if (error == EJUSTRETURN)
+ printf("JUSTRETURN");
+ else {
+ if (ktr->ktr_error <= ELAST + 1)
+ error = abs(bsd_to_linux_errno[ktr->ktr_error]);
+ else
+ error = 999;
+ printf("-1 errno %d", error);
+ if (fancy)
+ printf(" %s", strerror(ktr->ktr_error));
+ }
+ putchar('\n');
+}
+#endif
+
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);
}
Copied: stable/8/usr.bin/kdump/linux_syscalls.conf (from r219138, head/usr.bin/kdump/linux_syscalls.conf)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ stable/8/usr.bin/kdump/linux_syscalls.conf Sat Apr 2 08:29:02 2011 (r220267, copy of r219138, head/usr.bin/kdump/linux_syscalls.conf)
@@ -0,0 +1,11 @@
+# $FreeBSD$
+sysnames="linux_syscalls.c"
+sysproto="/dev/null"
+sysproto_h=_LINUX_SYSPROTO_H_
+syshdr="/dev/null"
+syssw="/dev/null"
+sysmk="/dev/null"
+syscallprefix="LINUX_SYS_"
+switchname="/dev/null"
+namesname="linux_syscallnames"
+systrace="/dev/null"
Modified: stable/8/usr.bin/ktrace/ktrace.c
==============================================================================
--- stable/8/usr.bin/ktrace/ktrace.c Sat Apr 2 07:01:09 2011 (r220266)
+++ stable/8/usr.bin/ktrace/ktrace.c Sat Apr 2 08:29:02 2011 (r220267)
@@ -163,6 +163,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);
Modified: stable/8/usr.bin/ktrace/ktrace.h
==============================================================================
--- stable/8/usr.bin/ktrace/ktrace.h Sat Apr 2 07:01:09 2011 (r220266)
+++ stable/8/usr.bin/ktrace/ktrace.h Sat Apr 2 08:29:02 2011 (r220267)
@@ -38,7 +38,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"
More information about the svn-src-stable
mailing list