PERFORCE change 52545 for review
Marcel Moolenaar
marcel at FreeBSD.org
Sun May 9 10:29:34 PDT 2004
http://perforce.freebsd.org/chv.cgi?CH=52545
Change 52545 by marcel at marcel_nfs on 2004/05/09 10:28:57
o We don't dummy-up SS and ESP anymore, because that doesn't
work well with multiple threads. We now read SS and ESP with
functions.
o Simplify tracing.
Affected files ...
.. //depot/projects/gdb/sys/i386/i386/db_trace.c#2 edit
Differences ...
==== //depot/projects/gdb/sys/i386/i386/db_trace.c#2 (text+ko) ====
@@ -29,6 +29,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/kdb.h>
#include <sys/proc.h>
#include <sys/sysent.h>
@@ -46,14 +47,16 @@
#include <ddb/db_sym.h>
#include <ddb/db_variables.h>
-db_varfcn_t db_dr0;
-db_varfcn_t db_dr1;
-db_varfcn_t db_dr2;
-db_varfcn_t db_dr3;
-db_varfcn_t db_dr4;
-db_varfcn_t db_dr5;
-db_varfcn_t db_dr6;
-db_varfcn_t db_dr7;
+static db_varfcn_t db_dr0;
+static db_varfcn_t db_dr1;
+static db_varfcn_t db_dr2;
+static db_varfcn_t db_dr3;
+static db_varfcn_t db_dr4;
+static db_varfcn_t db_dr5;
+static db_varfcn_t db_dr6;
+static db_varfcn_t db_dr7;
+static db_varfcn_t db_ss;
+static db_varfcn_t db_esp;
/*
* Machine register set.
@@ -66,12 +69,12 @@
#if 0
{ "gs", &ddb_regs.tf_gs, FCN_NULL },
#endif
- { "ss", &ddb_regs.tf_ss, FCN_NULL },
+ { "ss", NULL, db_ss },
{ "eax", &ddb_regs.tf_eax, FCN_NULL },
{ "ecx", &ddb_regs.tf_ecx, FCN_NULL },
{ "edx", &ddb_regs.tf_edx, FCN_NULL },
{ "ebx", &ddb_regs.tf_ebx, FCN_NULL },
- { "esp", &ddb_regs.tf_esp, FCN_NULL },
+ { "esp", NULL, db_esp },
{ "ebp", &ddb_regs.tf_ebp, FCN_NULL },
{ "esi", &ddb_regs.tf_esi, FCN_NULL },
{ "edi", &ddb_regs.tf_edi, FCN_NULL },
@@ -88,6 +91,50 @@
};
struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
+#define DB_DRX_FUNC(reg) \
+static int \
+db_ ## reg (vp, valuep, op) \
+ struct db_variable *vp; \
+ db_expr_t * valuep; \
+ int op; \
+{ \
+ if (op == DB_VAR_GET) \
+ *valuep = r ## reg (); \
+ else \
+ load_ ## reg (*valuep); \
+ return (0); \
+}
+
+DB_DRX_FUNC(dr0)
+DB_DRX_FUNC(dr1)
+DB_DRX_FUNC(dr2)
+DB_DRX_FUNC(dr3)
+DB_DRX_FUNC(dr4)
+DB_DRX_FUNC(dr5)
+DB_DRX_FUNC(dr6)
+DB_DRX_FUNC(dr7)
+
+static int
+db_esp (struct db_variable *vp, db_expr_t *valuep, int op)
+{
+ if (op == DB_VAR_GET)
+ *valuep = (ISPL(ddb_regs.tf_cs)) ? ddb_regs.tf_esp :
+ ddb_regs.tf_ebp;
+ else if (ISPL(ddb_regs.tf_cs))
+ ddb_regs.tf_esp = *valuep;
+ return (0);
+}
+
+static int
+db_ss (struct db_variable *vp, db_expr_t *valuep, int op)
+{
+ if (op == DB_VAR_GET)
+ *valuep = (ISPL(ddb_regs.tf_cs)) ? ddb_regs.tf_ss : rss();
+ else if (ISPL(ddb_regs.tf_cs))
+ ddb_regs.tf_ss = *valuep;
+ return (0);
+}
+
/*
* Stack trace.
*/
@@ -104,13 +151,10 @@
#define INTERRUPT 2
#define SYSCALL 3
-static void db_nextframe(struct i386_frame **, db_addr_t *, struct proc *);
+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 decode_syscall(int, struct proc *);
-static void db_trace_one_stack(int count, boolean_t have_addr,
- struct proc *p, struct i386_frame *frame, db_addr_t callpc);
-
+static void decode_syscall(int, struct thread *);
static char * watchtype_str(int type);
int i386_set_watch(int watchnum, unsigned int watchaddr, int size, int access,
@@ -120,7 +164,6 @@
int db_md_clr_watchpoint(db_expr_t addr, db_expr_t size);
void db_md_list_watchpoints(void);
-
/*
* Figure out how many arguments were passed into the frame at "fp".
*/
@@ -175,16 +218,16 @@
}
static void
-decode_syscall(number, p)
- int number;
+decode_syscall(int number, struct thread *td)
+{
struct proc *p;
-{
c_db_sym_t sym;
db_expr_t diff;
sy_call_t *f;
const char *symname;
db_printf(" (%d", number);
+ p = (td != NULL) ? td->td_proc : NULL;
if (p != NULL && 0 <= number && number < p->p_sysent->sv_size) {
f = p->p_sysent->sv_table[number].sy_call;
sym = db_search_symbol((db_addr_t)f, DB_STGY_ANY, &diff);
@@ -200,10 +243,7 @@
* Figure out the next frame up in the call stack.
*/
static void
-db_nextframe(fp, ip, p)
- struct i386_frame **fp; /* in/out */
- db_addr_t *ip; /* out */
- struct proc *p; /* in */
+db_nextframe(struct i386_frame **fp, db_addr_t *ip, struct thread *td)
{
struct trapframe *tf;
int frame_type;
@@ -264,7 +304,7 @@
break;
case SYSCALL:
db_printf("--- syscall");
- decode_syscall(tf->tf_eax, p);
+ decode_syscall(tf->tf_eax, td);
break;
case INTERRUPT:
db_printf("--- interrupt");
@@ -287,117 +327,43 @@
db_expr_t count;
char *modif;
{
+ struct trapframe *tf;
struct i386_frame *frame;
- struct proc *p;
- struct pcb *pcb;
struct thread *td;
+ int *argp;
db_addr_t callpc;
- pid_t pid;
+ pid_t tid;
+ boolean_t first;
if (count == -1)
count = 1024;
if (!have_addr) {
- td = curthread;
- p = td->td_proc;
- frame = (struct i386_frame *)ddb_regs.tf_ebp;
- if (frame == NULL)
- frame = (struct i386_frame *)(ddb_regs.tf_esp - 4);
- callpc = (db_addr_t)ddb_regs.tf_eip;
+ td = kdb_thread;
+ tf = kdb_frame;
+ frame = (void *)tf->tf_ebp;
+ callpc = (db_addr_t)tf->tf_eip;
} else if (!INKERNEL(addr)) {
- pid = (addr % 16) + ((addr >> 4) % 16) * 10 +
+ tid = (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;
- frame = (struct i386_frame *)ddb_regs.tf_ebp;
- if (frame == NULL)
- frame = (struct i386_frame *)
- (ddb_regs.tf_esp - 4);
- callpc = (db_addr_t)ddb_regs.tf_eip;
- } else {
-
- /* sx_slock(&allproc_lock); */
- LIST_FOREACH(p, &allproc, p_list) {
- if (p->p_pid == pid)
- break;
- }
- /* sx_sunlock(&allproc_lock); */
- if (p == NULL) {
- db_printf("pid %d not found\n", pid);
- return;
- }
- if ((p->p_sflag & PS_INMEM) == 0) {
- db_printf("pid %d swapped out\n", pid);
- return;
- }
- pcb = FIRST_THREAD_IN_PROC(p)->td_pcb; /* XXXKSE */
- frame = (struct i386_frame *)pcb->pcb_ebp;
- if (frame == NULL)
- frame = (struct i386_frame *)
- (pcb->pcb_esp - 4);
- callpc = (db_addr_t)pcb->pcb_eip;
+ td = kdb_thr_lookup(tid);
+ if (td == NULL) {
+ db_printf("Thread %d not found\n", tid);
+ return;
}
+ tf = td->td_last_frame;
+ frame = (void *)tf->tf_ebp;
+ callpc = (db_addr_t)tf->tf_eip;
} else {
- p = NULL;
+ td = NULL;
+ tf = NULL;
frame = (struct i386_frame *)addr;
- callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4, FALSE);
+ callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4,
+ FALSE);
frame = frame->f_frame;
}
- db_trace_one_stack(count, have_addr, p, frame, callpc);
-}
-
-void
-db_stack_thread(db_expr_t addr, boolean_t have_addr,
- db_expr_t count, char *modif)
-{
- struct i386_frame *frame;
- struct thread *td;
- struct proc *p;
- struct pcb *pcb;
- db_addr_t callpc;
- if (!have_addr)
- return;
- if (!INKERNEL(addr)) {
- printf("bad thread address");
- return;
- }
- td = (struct thread *)addr;
- /* quick sanity check */
- if ((p = td->td_proc) != td->td_ksegrp->kg_proc)
- return;
- if (TD_IS_SWAPPED(td)) {
- db_printf("thread at %p swapped out\n", td);
- return;
- }
- if (td == curthread) {
- frame = (struct i386_frame *)ddb_regs.tf_ebp;
- if (frame == NULL)
- frame = (struct i386_frame *)(ddb_regs.tf_esp - 4);
- callpc = (db_addr_t)ddb_regs.tf_eip;
- } else {
- pcb = td->td_pcb;
- frame = (struct i386_frame *)pcb->pcb_ebp;
- if (frame == NULL)
- frame = (struct i386_frame *) (pcb->pcb_esp - 4);
- callpc = (db_addr_t)pcb->pcb_eip;
- }
- db_trace_one_stack(count, have_addr, p, frame, callpc);
-}
-
-static void
-db_trace_one_stack(int count, boolean_t have_addr,
- struct proc *p, struct i386_frame *frame, db_addr_t callpc)
-{
- int *argp;
- boolean_t first;
-
first = TRUE;
while (count--) {
struct i386_frame *actframe;
@@ -477,7 +443,7 @@
continue;
}
- db_nextframe(&frame, &callpc, p);
+ db_nextframe(&frame, &callpc, td);
if (INKERNEL((int) callpc) && !INKERNEL((int) frame)) {
sym = db_search_symbol(callpc, DB_STGY_ANY, &offset);
@@ -500,29 +466,6 @@
db_stack_trace_cmd(ebp, 1, -1, NULL);
}
-#define DB_DRX_FUNC(reg) \
-int \
-db_ ## reg (vp, valuep, op) \
- struct db_variable *vp; \
- db_expr_t * valuep; \
- int op; \
-{ \
- if (op == DB_VAR_GET) \
- *valuep = r ## reg (); \
- else \
- load_ ## reg (*valuep); \
- return (0); \
-}
-
-DB_DRX_FUNC(dr0)
-DB_DRX_FUNC(dr1)
-DB_DRX_FUNC(dr2)
-DB_DRX_FUNC(dr3)
-DB_DRX_FUNC(dr4)
-DB_DRX_FUNC(dr5)
-DB_DRX_FUNC(dr6)
-DB_DRX_FUNC(dr7)
-
int
i386_set_watch(watchnum, watchaddr, size, access, d)
int watchnum;
More information about the p4-projects
mailing list