summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2001-11-18 03:41:12 +0000
committerjake <jake@FreeBSD.org>2001-11-18 03:41:12 +0000
commit9fd727b77f9cfa3c5bb70fa2dcf6c4c1fb957095 (patch)
tree97929a809a678c63de87e20fc313b9e2d5d2cab2 /sys
parent109c8b8676f4569760f6c2bca702cf27e44d67b9 (diff)
downloadFreeBSD-src-9fd727b77f9cfa3c5bb70fa2dcf6c4c1fb957095.zip
FreeBSD-src-9fd727b77f9cfa3c5bb70fa2dcf6c4c1fb957095.tar.gz
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)
Diffstat (limited to 'sys')
-rw-r--r--sys/sparc64/include/db_machdep.h12
-rw-r--r--sys/sparc64/include/frame.h15
-rw-r--r--sys/sparc64/sparc64/db_interface.c5
-rw-r--r--sys/sparc64/sparc64/db_trace.c81
4 files changed, 71 insertions, 42 deletions
diff --git a/sys/sparc64/include/db_machdep.h b/sys/sparc64/include/db_machdep.h
index f598dab..281f982 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 d297d4e..5d621c7 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 9d00793..7d7344b 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 9a4e4d1..2968466 100644
--- a/sys/sparc64/sparc64/db_trace.c
+++ b/sys/sparc64/sparc64/db_trace.c
@@ -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); \
OpenPOWER on IntegriCloud