Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 30 May 2004 20:46:41 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 53843 for review
Message-ID:  <200405310346.i4V3kfhK075055@repoman.freebsd.org>

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

Change 53843 by marcel@marcel_sledge on 2004/05/30 20:45:40

	MFi386

Affected files ...

.. //depot/projects/gdb/sys/amd64/amd64/db_trace.c#3 edit

Differences ...

==== //depot/projects/gdb/sys/amd64/amd64/db_trace.c#3 (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,23 @@
 #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_rsp;
+
+static __inline long
+get_rsp(struct trapframe *tf)
+{
+	return ((ISPL(tf->tf_cs)) ? tf->tf_rsp :
+	    (db_expr_t)tf + offsetof(struct trapframe, tf_rsp));
+}
 
 /*
  * Machine register set.
@@ -66,12 +76,12 @@
 	{ "fs",		&ddb_regs.tf_fs,     FCN_NULL },
 	{ "gs",		&ddb_regs.tf_gs,     FCN_NULL },
 #endif
-	{ "ss",		&ddb_regs.tf_ss,     FCN_NULL },
+	{ "ss",		NULL,		     db_ss },
 	{ "rax",	&ddb_regs.tf_rax,    FCN_NULL },
 	{ "rcx",	&ddb_regs.tf_rcx,    FCN_NULL },
 	{ "rdx",	&ddb_regs.tf_rdx,    FCN_NULL },
 	{ "rbx",	&ddb_regs.tf_rbx,    FCN_NULL },
-	{ "rsp",	&ddb_regs.tf_rsp,    FCN_NULL },
+	{ "rsp",	NULL,		     db_rsp },
 	{ "rbp",	&ddb_regs.tf_rbp,    FCN_NULL },
 	{ "rsi",	&ddb_regs.tf_rsi,    FCN_NULL },
 	{ "rdi",	&ddb_regs.tf_rdi,    FCN_NULL },
@@ -96,6 +106,49 @@
 };
 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_rsp (struct db_variable *vp, db_expr_t *valuep, int op)
+{
+	if (op == DB_VAR_GET)
+		*valuep = get_rsp(kdb_frame);
+	else if (ISPL(ddb_regs.tf_cs))
+		ddb_regs.tf_rsp = *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.
  */
@@ -112,13 +165,10 @@
 #define	INTERRUPT	2
 #define	SYSCALL		3
 
-static void db_nextframe(struct amd64_frame **, db_addr_t *, struct proc *);
+static void db_nextframe(struct amd64_frame **, db_addr_t *, struct thread *);
 static int db_numargs(struct amd64_frame *);
 static void db_print_stack_entry(const char *, int, char **, long *, 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 amd64_frame *frame, db_addr_t callpc);
-
+static void decode_syscall(int, struct thread *);
 
 static char * watchtype_str(int type);
 int  amd64_set_watch(int watchnum, unsigned int watchaddr, int size, int access,
@@ -189,16 +239,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);
@@ -214,10 +264,7 @@
  * Figure out the next frame up in the call stack.
  */
 static void
-db_nextframe(fp, ip, p)
-	struct amd64_frame **fp;	/* in/out */
-	db_addr_t	*ip;		/* out */
-	struct proc	*p;		/* in */
+db_nextframe(struct amd64_frame **fp, db_addr_t *ip, struct thread *td)
 {
 	struct trapframe *tf;
 	int frame_type;
@@ -265,8 +312,7 @@
 	tf = (struct trapframe *)((long)*fp + 16);
 
 	if (INKERNEL((long) tf)) {
-		rsp = (ISPL(tf->tf_cs) == SEL_UPL) ?
-		    tf->tf_rsp : (long)&tf->tf_rsp;
+		rsp = get_rsp(tf);
 		rip = tf->tf_rip;
 		rbp = tf->tf_rbp;
 		switch (frame_type) {
@@ -275,7 +321,7 @@
 			break;
 		case SYSCALL:
 			db_printf("--- syscall");
-			decode_syscall(tf->tf_rax, p);
+			decode_syscall(tf->tf_rax, td);
 			break;
 		case INTERRUPT:
 			db_printf("--- interrupt");
@@ -291,135 +337,26 @@
 	*fp = (struct amd64_frame *) rbp;
 }
 
-void
-db_stack_trace_cmd(addr, have_addr, count, modif)
-	db_expr_t addr;
-	boolean_t have_addr;
-	db_expr_t count;
-	char *modif;
+static int
+db_backtrace(struct thread *td, struct trapframe *tf,
+    struct amd64_frame *frame, db_addr_t pc, int count)
 {
-	struct amd64_frame *frame;
-	struct proc *p;
-	struct pcb *pcb;
-	struct thread *td;
-	db_addr_t callpc;
-	pid_t pid;
+	struct amd64_frame *actframe;
+#define MAXNARG	16
+	char *argnames[MAXNARG], **argnp = NULL;
+	const char *name;
+	long *argp;
+	db_expr_t offset;
+	c_db_sym_t sym;
+	int narg;
+	boolean_t first;
 
 	if (count == -1)
 		count = 1024;
 
-	if (!have_addr) {
-		td = curthread;
-		p = td->td_proc;
-		frame = (struct amd64_frame *)ddb_regs.tf_rbp;
-		if (frame == NULL)
-			frame = (struct amd64_frame *)(ddb_regs.tf_rsp - 8);
-		callpc = (db_addr_t)ddb_regs.tf_rip;
-	} 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;
-			frame = (struct amd64_frame *)ddb_regs.tf_rbp;
-			if (frame == NULL)
-				frame = (struct amd64_frame *)
-				    (ddb_regs.tf_rsp - 8);
-			callpc = (db_addr_t)ddb_regs.tf_rip;
-		} 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 amd64_frame *)pcb->pcb_rbp;
-			if (frame == NULL)
-				frame = (struct amd64_frame *)
-				    (pcb->pcb_rsp - 8);
-			callpc = (db_addr_t)pcb->pcb_rip;
-		}
-	} else {
-		p = NULL;
-		frame = (struct amd64_frame *)addr;
-		callpc = (db_addr_t)db_get_value((long)&frame->f_retaddr, 8, 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 amd64_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 amd64_frame *)ddb_regs.tf_rbp;
-		if (frame == NULL)
-			frame = (struct amd64_frame *)(ddb_regs.tf_rsp - 8);
-		callpc = (db_addr_t)ddb_regs.tf_rip;
-	} else {
-		pcb = td->td_pcb;
-		frame = (struct amd64_frame *)pcb->pcb_rbp;
-		if (frame == NULL)
-			frame = (struct amd64_frame *) (pcb->pcb_rsp - 8);
-		callpc = (db_addr_t)pcb->pcb_rip;
-	}
-	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 amd64_frame *frame, db_addr_t callpc)
-{
-	long *argp;
-	boolean_t first;
-
 	first = TRUE;
 	while (count--) {
-		struct amd64_frame *actframe;
-		int		narg;
-		const char *	name;
-		db_expr_t	offset;
-		c_db_sym_t	sym;
-#define MAXNARG	16
-		char	*argnames[MAXNARG], **argnp = NULL;
-
-		sym = db_search_symbol(callpc, DB_STGY_ANY, &offset);
+		sym = db_search_symbol(pc, DB_STGY_ANY, &offset);
 		db_symbol_values(sym, &name, NULL);
 
 		/*
@@ -435,37 +372,33 @@
 		 */
 		actframe = frame;
 		if (first) {
-			if (!have_addr) {
+			if (tf != NULL) {
 				int instr;
 
-				instr = db_get_value(callpc, 4, FALSE);
+				instr = db_get_value(pc, 4, FALSE);
 				if ((instr & 0xffffffff) == 0xe5894855) {
 					/* pushq %rbp; movq %rsp, %rbp */
-					actframe = (struct amd64_frame *)
-					    (ddb_regs.tf_rsp - 8);
-				} else if ((instr & 0x00ffffff) == 0x00e58948) {
+					actframe = (void *)(get_rsp(tf) - 8);
+				} else if ((instr & 0xffffff) == 0xe58948) {
 					/* movq %rsp, %rbp */
-					actframe = (struct amd64_frame *)
-					    ddb_regs.tf_rsp;
-					if (ddb_regs.tf_rbp == 0) {
-						/* Fake caller's frame better. */
+					actframe = (void *)get_rsp(tf);
+					if (tf->tf_rbp == 0) {
+						/* Fake frame better. */
 						frame = actframe;
 					}
-				} else if ((instr & 0x000000ff) == 0x000000c3) {
+				} else if ((instr & 0xff) == 0xc3) {
 					/* ret */
-					actframe = (struct amd64_frame *)
-					    (ddb_regs.tf_rsp - 8);
+					actframe = (void *)(get_rsp(tf) - 8);
 				} else if (offset == 0) {
-					/* Probably a symbol in assembler code. */
-					actframe = (struct amd64_frame *)
-					    (ddb_regs.tf_rsp - 8);
+					/* Probably an assembler symbol. */
+					actframe = (void *)(get_rsp(tf) - 8);
 				}
 			} else if (strcmp(name, "fork_trampoline") == 0) {
 				/*
 				 * Don't try to walk back on a stack for a
 				 * process that hasn't actually been run yet.
 				 */
-				db_print_stack_entry(name, 0, 0, 0, callpc);
+				db_print_stack_entry(name, 0, 0, 0, pc);
 				break;
 			}
 			first = FALSE;
@@ -479,60 +412,71 @@
 			narg = db_numargs(frame);
 		}
 
-		db_print_stack_entry(name, narg, argnp, argp, callpc);
+		db_print_stack_entry(name, narg, argnp, argp, pc);
 
 		if (actframe != frame) {
 			/* `frame' belongs to caller. */
-			callpc = (db_addr_t)
+			pc = (db_addr_t)
 			    db_get_value((long)&actframe->f_retaddr, 8, FALSE);
 			continue;
 		}
 
-		db_nextframe(&frame, &callpc, p);
+		db_nextframe(&frame, &pc, td);
 
-		if (INKERNEL((long) callpc) && !INKERNEL((long) frame)) {
-			sym = db_search_symbol(callpc, DB_STGY_ANY, &offset);
+		if (INKERNEL((long)pc) && !INKERNEL((long)frame)) {
+			sym = db_search_symbol(pc, DB_STGY_ANY, &offset);
 			db_symbol_values(sym, &name, NULL);
-			db_print_stack_entry(name, 0, 0, 0, callpc);
+			db_print_stack_entry(name, 0, 0, 0, pc);
 			break;
 		}
 		if (!INKERNEL((long) frame)) {
 			break;
 		}
 	}
+
+	return (0);
 }
 
 void
-db_print_backtrace(void)
+db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count,
+    char *modif)
+{
+	struct trapframe *tf;
+	struct thread *td;
+
+	td = (have_addr) ? kdb_thr_lookup(addr) : kdb_thread;
+	if (td == NULL) {
+		db_printf("Thread %ld not found\n", addr);
+		return;
+	}
+	tf = td->td_last_frame;
+	db_backtrace(td, tf, (struct amd64_frame *)tf->tf_rbp,
+	    (db_addr_t)tf->tf_rip, count);
+}
+
+void
+db_trace_self(void)
 {
-	register_t ebp;
+	struct amd64_frame *frame;
+	db_addr_t callpc;
+	register_t rbp;
 
-	__asm __volatile("movq %%rbp,%0" : "=r" (ebp));
-	db_stack_trace_cmd(ebp, 1, -1, NULL);
+	__asm __volatile("movq %%rbp,%0" : "=r" (rbp));
+	frame = (struct amd64_frame *)rbp;
+	callpc = (db_addr_t)db_get_value((long)&frame->f_retaddr, 8, FALSE);
+	frame = frame->f_frame;
+	db_backtrace(curthread, NULL, frame, callpc, -1);
 }
 
-#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);			\
-} 
+int
+db_trace_thread(struct thread *thr, int count)
+{
+	struct trapframe *tf;
 
-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)
+	tf = thr->td_last_frame;
+	return (db_backtrace(thr, tf, (struct amd64_frame *)tf->tf_rbp,
+		(db_addr_t)tf->tf_rip, count));
+}
 
 int
 amd64_set_watch(watchnum, watchaddr, size, access, d)



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