Date: Sat, 2 Apr 2011 08:29:02 +0000 (UTC) From: Dmitry Chagin <dchagin@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r220267 - in stable/8/usr.bin: kdump ktrace Message-ID: <201104020829.p328T2aP075577@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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"
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104020829.p328T2aP075577>