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 <pid> is attempted, it is not yet implemented.
5. Print traps better and decode system calls in traces.

Submitted by:	rwatson (4)
This commit is contained in:
Jake Burkholder 2001-11-18 03:41:12 +00:00
parent bc40966754
commit d5a7911f4a
4 changed files with 71 additions and 42 deletions

View File

@ -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)

View File

@ -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;
};

View File

@ -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);
}

View File

@ -30,6 +30,7 @@
#include <sys/systm.h>
#include <sys/linker_set.h>
#include <sys/proc.h>
#include <sys/sysent.h>
#include <sys/user.h>
#include <vm/vm.h>
@ -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); \