Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Mar 2011 11:14:59 +0000 (GMT)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Dmitry Chagin <dchagin@FreeBSD.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r219138 - head/usr.bin/kdump
Message-ID:  <alpine.BSF.2.00.1103031112230.91619@fledge.watson.org>
In-Reply-To: <201103011642.p21GgTaH041022@svn.freebsd.org>
References:  <201103011642.p21GgTaH041022@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

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"
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?alpine.BSF.2.00.1103031112230.91619>