On Tue, Nov 27, 2012 at 08:21:05AM +1100, Bruce Evans wrote: > On Mon, 26 Nov 2012, Konstantin Belousov wrote: > > > 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. ... > 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 _at__at_ -186,7 +186,8 _at__at_ db_ss(struct db_variable *vp, db_expr_t *valuep, int op) 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_addr_t); +static void db_print_stack_entry(const char *, int, char **, long *, db_addr_t, + void *); static void decode_syscall(int, struct thread *); static const char * watchtype_str(int type); _at__at_ -230,12 +231,13 _at__at_ db_numargs(fp) } 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 _at__at_ -250,6 +252,8 _at__at_ db_print_stack_entry(name, narg, argnp, argp, callpc) #endif db_printf(") at "); db_printsym(callpc, DB_STGY_PROC); + if (frame != NULL) + db_printf("/frame 0x%lx", (register_t)frame); db_printf("\n"); } _at__at_ -341,7 +345,7 _at__at_ db_nextframe(struct amd64_frame **fp, db_addr_t *ip, struct thread *td) return; } - db_print_stack_entry(name, 0, 0, 0, rip); + db_print_stack_entry(name, 0, 0, 0, rip, &(*fp)->f_frame); /* * Point to base of trapframe which is just above the _at__at_ -437,7 +441,8 _at__at_ 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 = FALSE; _at__at_ -451,7 +456,7 _at__at_ db_backtrace(struct thread *td, struct trapframe *tf, narg = db_numargs(frame); } - db_print_stack_entry(name, narg, argnp, argp, pc); + db_print_stack_entry(name, narg, argnp, argp, pc, actframe); if (actframe != frame) { /* `frame' belongs to caller. */ _at__at_ -465,7 +470,7 _at__at_ db_backtrace(struct thread *td, struct trapframe *tf, if (INKERNEL((long)pc) && !INKERNEL((long)frame)) { sym = 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 _at__at_ -176,7 +176,8 _at__at_ db_ss(struct db_variable *vp, db_expr_t *valuep, int op) 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_addr_t); +static void db_print_stack_entry(const char *, int, char **, int *, db_addr_t, + void *); static void decode_syscall(int, struct thread *); static const char * watchtype_str(int type); _at__at_ -220,12 +221,13 _at__at_ retry: } 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 = narg >= 0 ? narg : 5; _at__at_ -242,6 +244,8 _at__at_ db_print_stack_entry(name, narg, argnp, argp, callpc) db_printf(",..."); db_printf(") at "); db_printsym(callpc, DB_STGY_PROC); + if (frame != NULL) + db_printf("/frame 0x%r", (register_t)frame); db_printf("\n"); } _at__at_ -326,7 +330,7 _at__at_ db_nextframe(struct i386_frame **fp, db_addr_t *ip, struct thread *td) return; } - db_print_stack_entry(name, 0, 0, 0, eip); + db_print_stack_entry(name, 0, 0, 0, eip, &(*fp)->f_frame); /* * For a double fault, we have to snag the values from the _at__at_ -467,7 +471,8 _at__at_ db_backtrace(struct thread *td, struct trapframe *tf, struct 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 = FALSE; _at__at_ -481,7 +486,7 _at__at_ db_backtrace(struct thread *td, struct trapframe *tf, struct i386_frame *frame, narg = db_numargs(frame); } - db_print_stack_entry(name, narg, argnp, argp, pc); + db_print_stack_entry(name, narg, argnp, argp, pc, actframe); if (actframe != frame) { /* `frame' belongs to caller. */ _at__at_ -495,7 +500,7 _at__at_ db_backtrace(struct thread *td, struct trapframe *tf, struct i386_frame *frame, if (INKERNEL((int)pc) && !INKERNEL((int) frame)) { sym = 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)) {
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:32 UTC