From d5a7911f4ae617753644e34d8effcdcfe548b320 Mon Sep 17 00:00:00 2001 From: Jake Burkholder Date: Sun, 18 Nov 2001 03:41:12 +0000 Subject: [PATCH] 1. Remove kdbframe. Bad idea. 2. Add a TF_DONE macro, which fiddles a trapframe to make the retry on return from traps act like a done (advance past the trapping instruction instead of re-executing). 3. Flush the windows before entering the debugger, since it is no longer done in the breakpoint trap vector. 4. Print a warning if trace is attempted, it is not yet implemented. 5. Print traps better and decode system calls in traces. Submitted by: rwatson (4) --- sys/sparc64/include/db_machdep.h | 12 ++--- sys/sparc64/include/frame.h | 15 ++---- sys/sparc64/sparc64/db_interface.c | 5 +- sys/sparc64/sparc64/db_trace.c | 81 ++++++++++++++++++++++-------- 4 files changed, 71 insertions(+), 42 deletions(-) diff --git a/sys/sparc64/include/db_machdep.h b/sys/sparc64/include/db_machdep.h index f598dab42c0..281f982bb24 100644 --- a/sys/sparc64/include/db_machdep.h +++ b/sys/sparc64/include/db_machdep.h @@ -38,10 +38,6 @@ typedef vm_offset_t db_addr_t; typedef long db_expr_t; -struct db_regs { - u_long dr_global[8]; -}; - typedef struct trapframe db_regs_t; extern db_regs_t ddb_regs; #define DDB_REGS (&ddb_regs) @@ -52,10 +48,10 @@ extern db_regs_t ddb_regs; #define BKPT_SIZE (4) #define BKPT_SET(inst) (BKPT_INST) -#define FIXUP_PC_AFTER_BREAK do { \ - ddb_regs.tf_tpc = ddb_regs.tf_tnpc; \ - ddb_regs.tf_tnpc += BKPT_SIZE; \ -} while (0); +#define BKPT_SKIP do { \ + ddb_regs.tf_tpc = ddb_regs.tf_tnpc + 4; \ + ddb_regs.tf_tnpc += 8; \ +} while (0) #define db_clear_single_step(regs) #define db_set_single_step(regs) diff --git a/sys/sparc64/include/frame.h b/sys/sparc64/include/frame.h index d297d4e6a5a..5d621c7183a 100644 --- a/sys/sparc64/include/frame.h +++ b/sys/sparc64/include/frame.h @@ -49,22 +49,17 @@ struct trapframe { tf->tf_tnpc += 4; \ } while (0) +#define TF_DONE(tf) do { \ + tf->tf_tpc = tf->tf_tnpc; \ + tf->tf_tnpc += 4; \ +} while (0) + struct mmuframe { u_long mf_sfar; u_long mf_sfsr; u_long mf_tar; }; -struct kdbframe { - u_long kf_fp; - u_long kf_cfp; - u_long kf_canrestore; - u_long kf_cansave; - u_long kf_cleanwin; - u_long kf_cwp; - u_long kf_otherwin; -}; - struct clockframe { struct trapframe cf_tf; }; diff --git a/sys/sparc64/sparc64/db_interface.c b/sys/sparc64/sparc64/db_interface.c index 9d00793c54b..7d7344b523d 100644 --- a/sys/sparc64/sparc64/db_interface.c +++ b/sys/sparc64/sparc64/db_interface.c @@ -62,13 +62,11 @@ static int db_global_jmpbuf_valid; int kdb_trap(struct trapframe *tf) { - struct kdbframe *kf; if (db_global_jmpbuf_valid) longjmp(db_global_jmpbuf, 1); + flushw(); ddb_regs = *tf; - kf = (struct kdbframe *)ddb_regs.tf_arg; - kf->kf_cfp = kf->kf_fp; setjmp(db_global_jmpbuf); db_global_jmpbuf_valid = TRUE; db_active++; @@ -77,6 +75,7 @@ kdb_trap(struct trapframe *tf) cndbctl(FALSE); db_active--; db_global_jmpbuf_valid = FALSE; + *tf = ddb_regs; return (1); } diff --git a/sys/sparc64/sparc64/db_trace.c b/sys/sparc64/sparc64/db_trace.c index 9a4e4d1e81e..29684662342 100644 --- a/sys/sparc64/sparc64/db_trace.c +++ b/sys/sparc64/sparc64/db_trace.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -63,13 +64,10 @@ static db_varfcn_t db_show_local5; static db_varfcn_t db_show_local6; static db_varfcn_t db_show_local7; -static int db_print_trap(struct trapframe *); - -extern char _start[]; -extern char _end[]; +static int db_print_trap(struct proc *p, struct trapframe *); #define INKERNEL(va) \ - ((va) >= (u_long)_start && (va) <= (u_long)_end) + ((va) >= VM_MIN_KERNEL_ADDRESS && (va) <= VM_MAX_KERNEL_ADDRESS) struct db_variable db_regs[] = { { "g0", &ddb_regs.tf_global[0], FCN_NULL }, @@ -107,8 +105,9 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif) { struct trapframe *tf; - struct kdbframe *kfp; struct frame *fp; + struct proc *p; + struct thread *td; const char *name; c_db_sym_t sym; db_expr_t offset; @@ -118,6 +117,7 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, db_addr_t pc; int trap; int user; + pid_t pid; trap = 0; user = 0; @@ -125,10 +125,28 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, if (count == -1) count = 1024; if (!have_addr) { - kfp = (struct kdbframe *)DDB_REGS->tf_arg; - fp = (struct frame *)(kfp->kf_cfp + SPOFF); - } else - fp = (struct frame *)(addr + SPOFF); + td = curthread; + p = td->td_proc; + addr = DDB_REGS->tf_out[6]; + } else if (!INKERNEL(addr)) { + pid = (addr % 16) + ((addr >> 4) % 16) * 10 + + ((addr >> 8) % 16) * 100 + ((addr >> 12) % 16) * 1000 + + ((addr >> 16) % 16) * 10000; + /* + * The pcb for curproc is not valid at this point, + * so fall back to the default case. + */ + if (pid == curthread->td_proc->p_pid) { + td = curthread; + p = td->td_proc; + } else { + /* search for pid */ + } + db_printf("trace pid not implemented\n"); + return; + } + fp = (struct frame *)(addr + SPOFF); + while (count-- && !user) { pc = (db_addr_t)db_get_value((db_addr_t)&fp->f_pc, sizeof(db_addr_t), FALSE); @@ -153,7 +171,7 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, tf = (struct trapframe *)(nfp + sizeof(*fp)); npc = db_get_value((db_addr_t)&tf->tf_tpc, sizeof(u_long), FALSE); - user = db_print_trap(tf); + user = db_print_trap(curthread->td_proc, tf); trap = 1; } else { db_printf("%s() at ", name); @@ -166,32 +184,54 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, } static int -db_print_trap(struct trapframe *tf) +db_print_trap(struct proc *p, struct trapframe *tf) { + const char *symname; struct mmuframe *mf; + c_db_sym_t sym; + db_expr_t diff; + db_addr_t func; + db_addr_t tpc; u_long type; u_long va; + u_long code; - type = db_get_value((db_addr_t)&tf->tf_type, sizeof(u_long), FALSE); - db_printf("-- %s trap (%s) -- ", type & T_KERNEL ? "kernel" : "user", - trap_msg[type & ~T_KERNEL]); - if ((type & T_KERNEL) == 0) - db_printf("tpc=0x%lx, tnpc=0x%lx ", tf->tf_tpc, tf->tf_tnpc); + type = db_get_value((db_addr_t)&tf->tf_type, sizeof(db_addr_t), FALSE); + db_printf("-- %s", trap_msg[type & ~T_KERNEL]); switch (type & ~T_KERNEL) { case T_ALIGN: mf = (struct mmuframe *)db_get_value((db_addr_t)&tf->tf_arg, sizeof(void *), FALSE); va = (u_long)db_get_value((db_addr_t)&mf->mf_sfar, sizeof(u_long), FALSE); - db_printf("va=%#lx", va); + db_printf(" va=%#lx", va); + break; + case T_SYSCALL: + code = db_get_value((db_addr_t)&tf->tf_global[1], + sizeof(u_long), FALSE); + db_printf(" (%ld", code); + if (code >= 0 && code < p->p_sysent->sv_size) { + func = (db_addr_t)p->p_sysent->sv_table[code].sy_call; + sym = db_search_symbol(func, DB_STGY_ANY, &diff); + if (sym != DB_SYM_NULL && diff == 0) { + db_symbol_values(sym, &symname, NULL); + db_printf(", %s, %s", p->p_sysent->sv_name, + symname); + } + db_printf(")"); + } break; default: break; } + tpc = db_get_value((db_addr_t)&tf->tf_tpc, sizeof(db_addr_t), FALSE); + db_printf(" -- at "); + db_printsym(tpc, DB_STGY_PROC); db_printf("\n"); return ((type & T_KERNEL) == 0); } +#if 0 DB_COMMAND(down, db_frame_down) { struct kdbframe *kfp; @@ -231,16 +271,15 @@ DB_COMMAND(up, db_frame_up) kfp->kf_cfp = db_get_value((db_addr_t)&cfp->f_fp, sizeof(u_long), FALSE); } +#endif #define DB_SHOW_REG(name, num) \ static int \ db_show_ ## name ## num(struct db_variable *dp, db_expr_t *vp, int op) \ { \ - struct kdbframe *kfp; \ struct frame *fp; \ \ - kfp = (struct kdbframe *)DDB_REGS->tf_arg; \ - fp = (struct frame *)(kfp->kf_cfp + SPOFF); \ + fp = (struct frame *)(DDB_REGS->tf_out[6] + SPOFF); \ if (op == DB_VAR_GET) \ *vp = db_get_value((db_addr_t)&fp->f_ ## name ## [num], \ sizeof(u_long), FALSE); \