svn commit: r219138 - head/usr.bin/kdump
Robert Watson
rwatson at FreeBSD.org
Thu Mar 3 11:15:01 UTC 2011
On Tue, 1 Mar 2011, Dmitry Chagin wrote:
> Teach kdump to decode linux syscalls names too.
>
> Fix bug introduced in my previous commit: the kernel always dump native
> signal numbers, so no need to check the ABI in ktrpsig().
Does this mean that we're eliminating the need for the long-broken
linux_kdump?
Is there any ABI record in ktrace files, and/or should we add one somehow?
I'd love to be able to process a kdump file generated from a blend of ABIs:
i.e., if I do ktrace -di tcsh, and then run a bunch of commands from different
ABIs (FreeBSD/32-bit Intel, FreeBSD/64-bit Intel, Linux/32-bit Intel, and
possible FreeBSD/64 MIPS so that a distributed ktracing tool gathers the
results across hosts for a single action), have kdump Just Work. This
suggests that a per-record ABI indicator might be useful.
Robert
>
> Suggested by: jhb
> MFC after: 1 Month.
>
> Added:
> head/usr.bin/kdump/linux_syscalls.conf (contents, props changed)
> Modified:
> head/usr.bin/kdump/Makefile
> head/usr.bin/kdump/kdump.c
>
> Modified: head/usr.bin/kdump/Makefile
> ==============================================================================
> --- head/usr.bin/kdump/Makefile Tue Mar 1 14:54:14 2011 (r219137)
> +++ head/usr.bin/kdump/Makefile Tue Mar 1 16:42:28 2011 (r219138)
> @@ -1,15 +1,23 @@
> # @(#)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}/../..
>
> +.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386"
> +SRCS+= linux_syscalls.c
> +.endif
> +
> WARNS?= 0
>
> -CLEANFILES= ioctl.c kdump_subr.c
> +CLEANFILES= ioctl.c kdump_subr.c linux_syscalls.c
>
> ioctl.c: mkioctls
> sh ${.CURDIR}/mkioctls ${DESTDIR}/usr/include > ${.TARGET}
> @@ -17,4 +25,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: head/usr.bin/kdump/kdump.c
> ==============================================================================
> --- head/usr.bin/kdump/kdump.c Tue Mar 1 14:54:14 2011 (r219137)
> +++ head/usr.bin/kdump/kdump.c Tue Mar 1 16:42:28 2011 (r219138)
> @@ -93,7 +93,7 @@ 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 *, u_int);
> +void ktrpsig(struct ktr_psig *);
> void ktrcsw(struct ktr_csw *);
> void ktruser(int, unsigned char *);
> void ktrsockaddr(struct sockaddr *);
> @@ -111,6 +111,41 @@ 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;
> @@ -233,10 +268,20 @@ main(int argc, char *argv[])
> drop_logged = 0;
> switch (ktr_header.ktr_type) {
> case KTR_SYSCALL:
> - ktrsyscall((struct ktr_syscall *)m, sv_flags);
> +#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, sv_flags);
> +#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:
> @@ -246,7 +291,7 @@ main(int argc, char *argv[])
> ktrgenio((struct ktr_genio *)m, ktrlen);
> break;
> case KTR_PSIG:
> - ktrpsig((struct ktr_psig *)m, sv_flags);
> + ktrpsig((struct ktr_psig *)m);
> break;
> case KTR_CSW:
> ktrcsw((struct ktr_csw *)m);
> @@ -455,17 +500,6 @@ ktrsyscall(struct ktr_syscall *ktr, u_in
> char c = '(';
> if (fancy &&
> (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
> -
> -#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 (ktr->ktr_code == SYS_ioctl) {
> const char *cp;
> print_number(ip,narg,c);
> @@ -1093,10 +1127,9 @@ const char *signames[] = {
> };
>
> void
> -ktrpsig(struct ktr_psig *psig, u_int flags)
> +ktrpsig(struct ktr_psig *psig)
> {
> - if ((flags & SV_ABI_MASK) == SV_ABI_FREEBSD &&
> - psig->signo > 0 && psig->signo < NSIG)
> + if (psig->signo > 0 && psig->signo < NSIG)
> (void)printf("SIG%s ", signames[psig->signo]);
> else
> (void)printf("SIG %d ", psig->signo);
> @@ -1471,6 +1504,67 @@ 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)
> {
>
> Added: head/usr.bin/kdump/linux_syscalls.conf
> ==============================================================================
> --- /dev/null 00:00:00 1970 (empty, because file is newly added)
> +++ head/usr.bin/kdump/linux_syscalls.conf Tue Mar 1 16:42:28 2011 (r219138)
> @@ -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"
>
More information about the svn-src-head
mailing list