Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 May 2004 10:29:31 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 52545 for review
Message-ID:  <200405091729.i49HTVLm092546@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=52545

Change 52545 by marcel@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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200405091729.i49HTVLm092546>