Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Nov 2012 01:29:44 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        sig6247 <sig6247@gmail.com>
Cc:        freebsd-current@freebsd.org, fs@freebsd.org, Bruce Evans <brde@optusnet.com.au>
Subject:   Re: clang compiled kernel panic when mounting zfs root on i386
Message-ID:  <20121129232944.GQ3013@kib.kiev.ua>
In-Reply-To: <20121127071243.D1255@besplex.bde.org>
References:  <50b37d46.8584440a.735c.ffffb4e6@mx.google.com> <20121126171658.GD3013@kib.kiev.ua> <20121127071243.D1255@besplex.bde.org>

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

--KI6XeYrntNhU1GwB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Tue, Nov 27, 2012 at 08:21:05AM +1100, Bruce Evans wrote:
> On Mon, 26 Nov 2012, Konstantin Belousov wrote:
>=20
> > On Mon, Nov 26, 2012 at 06:31:34AM -0800, sig6247 wrote:
> >>
> >> Just checked out r243529, this only happens when the kernel is compiled
> >> by clang, and only on i386, either recompiling the kernel with gcc or
> >> booting from a UFS root works fine. Is it a known problem?
> > It looks like that clang uses more stack than gcc, and zfs makes quite
> > deep call chains.
=2E..
> It would be useful if the stack trace printed the the stack pointer
> on every function call, so that you could see how much stack each
> function used.

Please apply the patch below and obtain the backtrace of the double fault
panic again. I will commit the patch later.

diff --git a/sys/amd64/amd64/db_trace.c b/sys/amd64/amd64/db_trace.c
index cba90f2..2c81f87 100644
--- a/sys/amd64/amd64/db_trace.c
+++ b/sys/amd64/amd64/db_trace.c
@@ -186,7 +186,8 @@ db_ss(struct db_variable *vp, db_expr_t *valuep, int op)
=20
 static void db_nextframe(struct amd64_frame **, db_addr_t *, struct thread=
 *);
 static int db_numargs(struct amd64_frame *);
-static void db_print_stack_entry(const char *, int, char **, long *, db_ad=
dr_t);
+static void db_print_stack_entry(const char *, int, char **, long *, db_ad=
dr_t,
+    void *);
 static void decode_syscall(int, struct thread *);
=20
 static const char * watchtype_str(int type);
@@ -230,12 +231,13 @@ db_numargs(fp)
 }
=20
 static void
-db_print_stack_entry(name, narg, argnp, argp, callpc)
+db_print_stack_entry(name, narg, argnp, argp, callpc, frame)
 	const char *name;
 	int narg;
 	char **argnp;
 	long *argp;
 	db_addr_t callpc;
+	void *frame;
 {
 	db_printf("%s(", name);
 #if 0
@@ -250,6 +252,8 @@ db_print_stack_entry(name, narg, argnp, argp, callpc)
 #endif
 	db_printf(") at ");
 	db_printsym(callpc, DB_STGY_PROC);
+	if (frame !=3D NULL)
+		db_printf("/frame 0x%lx", (register_t)frame);
 	db_printf("\n");
 }
=20
@@ -341,7 +345,7 @@ db_nextframe(struct amd64_frame **fp, db_addr_t *ip, st=
ruct thread *td)
 		return;
 	}
=20
-	db_print_stack_entry(name, 0, 0, 0, rip);
+	db_print_stack_entry(name, 0, 0, 0, rip, &(*fp)->f_frame);
=20
 	/*
 	 * Point to base of trapframe which is just above the
@@ -437,7 +441,8 @@ db_backtrace(struct thread *td, struct trapframe *tf,
 				 * Don't try to walk back on a stack for a
 				 * process that hasn't actually been run yet.
 				 */
-				db_print_stack_entry(name, 0, 0, 0, pc);
+				db_print_stack_entry(name, 0, 0, 0, pc,
+				    actframe);
 				break;
 			}
 			first =3D FALSE;
@@ -451,7 +456,7 @@ db_backtrace(struct thread *td, struct trapframe *tf,
 			narg =3D db_numargs(frame);
 		}
=20
-		db_print_stack_entry(name, narg, argnp, argp, pc);
+		db_print_stack_entry(name, narg, argnp, argp, pc, actframe);
=20
 		if (actframe !=3D frame) {
 			/* `frame' belongs to caller. */
@@ -465,7 +470,7 @@ db_backtrace(struct thread *td, struct trapframe *tf,
 		if (INKERNEL((long)pc) && !INKERNEL((long)frame)) {
 			sym =3D db_search_symbol(pc, DB_STGY_ANY, &offset);
 			db_symbol_values(sym, &name, NULL);
-			db_print_stack_entry(name, 0, 0, 0, pc);
+			db_print_stack_entry(name, 0, 0, 0, pc, frame);
 			break;
 		}
 		if (!INKERNEL((long) frame)) {
diff --git a/sys/i386/i386/db_trace.c b/sys/i386/i386/db_trace.c
index 445d9c5..822cc56 100644
--- a/sys/i386/i386/db_trace.c
+++ b/sys/i386/i386/db_trace.c
@@ -176,7 +176,8 @@ db_ss(struct db_variable *vp, db_expr_t *valuep, int op)
=20
 static void db_nextframe(struct i386_frame **, db_addr_t *, struct thread =
*);
 static int db_numargs(struct i386_frame *);
-static void db_print_stack_entry(const char *, int, char **, int *, db_add=
r_t);
+static void db_print_stack_entry(const char *, int, char **, int *, db_add=
r_t,
+    void *);
 static void decode_syscall(int, struct thread *);
=20
 static const char * watchtype_str(int type);
@@ -220,12 +221,13 @@ retry:
 }
=20
 static void
-db_print_stack_entry(name, narg, argnp, argp, callpc)
+db_print_stack_entry(name, narg, argnp, argp, callpc, frame)
 	const char *name;
 	int narg;
 	char **argnp;
 	int *argp;
 	db_addr_t callpc;
+	void *frame;
 {
 	int n =3D narg >=3D 0 ? narg : 5;
=20
@@ -242,6 +244,8 @@ db_print_stack_entry(name, narg, argnp, argp, callpc)
 		db_printf(",...");
 	db_printf(") at ");
 	db_printsym(callpc, DB_STGY_PROC);
+	if (frame !=3D NULL)
+		db_printf("/frame 0x%r", (register_t)frame);
 	db_printf("\n");
 }
=20
@@ -326,7 +330,7 @@ db_nextframe(struct i386_frame **fp, db_addr_t *ip, str=
uct thread *td)
 		return;
 	}
=20
-	db_print_stack_entry(name, 0, 0, 0, eip);
+	db_print_stack_entry(name, 0, 0, 0, eip, &(*fp)->f_frame);
=20
 	/*
 	 * For a double fault, we have to snag the values from the
@@ -467,7 +471,8 @@ db_backtrace(struct thread *td, struct trapframe *tf, s=
truct i386_frame *frame,
 				 * Don't try to walk back on a stack for a
 				 * process that hasn't actually been run yet.
 				 */
-				db_print_stack_entry(name, 0, 0, 0, pc);
+				db_print_stack_entry(name, 0, 0, 0, pc,
+				    actframe);
 				break;
 			}
 			first =3D FALSE;
@@ -481,7 +486,7 @@ db_backtrace(struct thread *td, struct trapframe *tf, s=
truct i386_frame *frame,
 			narg =3D db_numargs(frame);
 		}
=20
-		db_print_stack_entry(name, narg, argnp, argp, pc);
+		db_print_stack_entry(name, narg, argnp, argp, pc, actframe);
=20
 		if (actframe !=3D frame) {
 			/* `frame' belongs to caller. */
@@ -495,7 +500,7 @@ db_backtrace(struct thread *td, struct trapframe *tf, s=
truct i386_frame *frame,
 		if (INKERNEL((int)pc) && !INKERNEL((int) frame)) {
 			sym =3D db_search_symbol(pc, DB_STGY_ANY, &offset);
 			db_symbol_values(sym, &name, NULL);
-			db_print_stack_entry(name, 0, 0, 0, pc);
+			db_print_stack_entry(name, 0, 0, 0, pc, frame);
 			break;
 		}
 		if (!INKERNEL((int) frame)) {

--KI6XeYrntNhU1GwB
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (FreeBSD)

iQIcBAEBAgAGBQJQt+/nAAoJEJDCuSvBvK1BXUIP/jOiC4stZJ9EEWRosY4ELMDI
WJnPA/mukK/tGNY/WXYm3Ro+6tkfe8rbrUoolkIuo3D/dmtunA8JYXA0bkGW3Rbq
GsJNfi6Rie4e7I+VkUI5cRzEZ0Atcz5Mw+Vy0ix6UQzGC9TvWvCQI0khfWBVbeyX
v1hLx/McVn9iRBCftFtQj0JfGvQmVxLVCMdMQJ59Ds7IwHyPtWbPLtq5f0AEjSfz
fCxksMI8sKfvzBHjZA5Cxux5k2Hf97gppXUTAsnHOau2M8oQFNyNNWf7SPnF6iKS
Qw5JAhpNePHy6x1VjdiecUjziC4jBeMONWPGRVVwSdYyDNTuzd8kg8bkzPhYaywJ
T7+1hjdzvV5fCTVIj53GFnMP60g0cnfyQoEt9nDXW7d6AZofeZWPVtusJUD4bmTz
42btYYzCzMWG/UViGzc3eoYX9kqmi8mut+/0UbaZErLtSlzTb86SXZfmnC/n2OE7
GrnyFXpia1To1YluGWsDV6BrNzhgWZhGmy9C+GyV60alO0MVF18mMRn5OSP1aBIe
y2WJhMDTIdL+gnbWnKK0J+AV17BptApVzTfU/3KM2avH7Z83LVngLQDyfSyMtTN0
m3qS7bGMKQXf5oUh+jcGPjGimW4SJYjL75OuyvkWxmXn9IC+RWFhzDR3PyzMf+zc
kRpA9qMuQM81N4BSbYjI
=Jtls
-----END PGP SIGNATURE-----

--KI6XeYrntNhU1GwB--



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