PERFORCE change 53266 for review

Marcel Moolenaar marcel at FreeBSD.org
Sat May 22 19:04:03 PDT 2004


http://perforce.freebsd.org/chv.cgi?CH=53266

Change 53266 by marcel at marcel_nfs on 2004/05/22 19:02:57

	Add db_trace_thread() for producing backtraces given a
	struct thread. Add db_trace_self() to replace
	db_print_backtrace(). Move the actual backtrace logic
	out of db_stack_trace_cmd().
	
	Protect db_read_bytes() and db_write_bytes() with a
	jmpbuf.

Affected files ...

.. //depot/projects/gdb/sys/alpha/alpha/db_interface.c#6 edit
.. //depot/projects/gdb/sys/alpha/alpha/db_trace.c#2 edit
.. //depot/projects/gdb/sys/ddb/db_access.c#2 edit
.. //depot/projects/gdb/sys/ddb/db_main.c#7 edit
.. //depot/projects/gdb/sys/ddb/db_thread.c#4 edit
.. //depot/projects/gdb/sys/ddb/ddb.h#7 edit
.. //depot/projects/gdb/sys/i386/i386/db_interface.c#8 edit
.. //depot/projects/gdb/sys/i386/i386/db_trace.c#4 edit
.. //depot/projects/gdb/sys/i386/include/frame.h#4 edit
.. //depot/projects/gdb/sys/i386/isa/clock.c#9 edit
.. //depot/projects/gdb/sys/ia64/ia64/db_interface.c#7 edit
.. //depot/projects/gdb/sys/ia64/ia64/db_trace.c#2 edit
.. //depot/projects/gdb/sys/ia64/ia64/unwind.c#3 edit
.. //depot/projects/gdb/sys/sparc64/sparc64/db_interface.c#6 edit
.. //depot/projects/gdb/sys/sparc64/sparc64/db_trace.c#2 edit

Differences ...

==== //depot/projects/gdb/sys/alpha/alpha/db_interface.c#6 (text+ko) ====

@@ -50,14 +50,12 @@
 __FBSDID("$FreeBSD: src/sys/alpha/alpha/db_interface.c,v 1.28 2003/08/22 07:20:25 imp Exp $");
 
 #include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/reboot.h>
 #include <sys/systm.h>
+#include <sys/cons.h>
+#include <sys/kdb.h>
 #include <sys/kernel.h>
-#include <sys/cons.h>
-#include <sys/ktr.h>
-#include <sys/lock.h>
 #include <sys/pcpu.h>
+#include <sys/proc.h>
 #include <sys/smp.h>
 
 #include <vm/vm.h>
@@ -73,11 +71,7 @@
 #include <ddb/db_access.h>
 #include <ddb/db_sym.h>
 #include <ddb/db_variables.h>
-#include <machine/setjmp.h>
 
-static jmp_buf *db_nofault = 0;
-extern jmp_buf	db_jmpbuf;
-
 struct db_variable db_regs[] = {
 	{	"v0",	&ddb_regs.tf_regs[FRAME_V0],	FCN_NULL	},
 	{	"t0",	&ddb_regs.tf_regs[FRAME_T0],	FCN_NULL	},
@@ -120,42 +114,46 @@
 /*
  * Read bytes from kernel address space for debugger.
  */
-void
-db_read_bytes(addr, size, data)
-	vm_offset_t	addr;
-	register size_t	size;
-	register char	*data;
+int
+db_read_bytes(vm_offset_t addr, size_t size, char *data)
 {
-	register char	*src;
+	jmp_buf jb;
+	void *prev_jb;
+	char *src;
+	int ret;
 
-	db_nofault = &db_jmpbuf;
-
-	src = (char *)addr;
-	while (size-- > 0)
-		*data++ = *src++;
-
-	db_nofault = 0;
+	prev_jb = kdb_jmpbuf(jb);
+	ret = setjmp(jb);
+	if (ret == 0) {
+		src = (char *)addr;
+		while (size-- > 0)
+			*data++ = *src++;
+	}
+	(void)kdb_jmpbuf(prev_jb);
+	return (ret);
 }
 
 /*
  * Write bytes to kernel address space for debugger.
  */
-void
-db_write_bytes(addr, size, data)
-	vm_offset_t	addr;
-	register size_t	size;
-	register char	*data;
+int
+db_write_bytes(vm_offset_t addr, size_t size, char *data)
 {
-	register char	*dst;
+	jmp_buf jb;
+	void *prev_jb;
+	char *dst;
+	int ret;
 
-	db_nofault = &db_jmpbuf;
-
-	dst = (char *)addr;
-	while (size-- > 0)
-		*dst++ = *data++;
-	alpha_pal_imb();
-
-	db_nofault = 0;
+	prev_jb = kdb_jmpbuf(jb);
+	ret = setjmp(jb);
+	if (ret == 0) {
+		dst = (char *)addr;
+		while (size-- > 0)
+			*dst++ = *data++;
+		alpha_pal_imb();
+	}
+	(void)kdb_jmpbuf(prev_jb);
+	return (ret);
 }
 
 /*

==== //depot/projects/gdb/sys/alpha/alpha/db_trace.c#2 (text+ko) ====

@@ -46,6 +46,7 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/kdb.h>
 #include <sys/proc.h>
 #include <sys/user.h>
 #include <sys/sysent.h>
@@ -60,11 +61,6 @@
 #include <ddb/db_output.h>
 #include <alpha/alpha/db_instruction.h>
 
-struct trace_request {
-	register_t ksp;
-	register_t pc;
-};
-
 /*
  * Information about the `standard' Alpha function prologue.
  */
@@ -186,13 +182,15 @@
 }
 
 static void
-decode_syscall(int number, struct proc *p)
+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;
 
+	p = (td != NULL) ? td->td_proc : NULL;
 	db_printf(" (%d", number);
 	if (p != NULL && 0 <= number && number < p->p_sysent->sv_size) {
 		f = p->p_sysent->sv_table[number].sy_call;
@@ -205,99 +203,33 @@
 	db_printf(")");	
 }
 
-void
-db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif)
+static int
+db_backtrace(struct thread *td, struct trapframe *tf, db_addr_t frame,
+    db_addr_t pc, int count)
 {
-	db_addr_t callpc = 0, frame = 0, symval;
 	struct prologue_info pi;
+	const char *symname;
+	c_db_sym_t sym;
 	db_expr_t diff;
-	c_db_sym_t sym;
+	db_addr_t symval;
+	u_long last_ipl, tfps;
 	int i;
-	u_long tfps;
-	const char *symname;
-	struct pcb *pcbp;
-	struct trapframe *tf = NULL;
-	boolean_t ra_from_tf = FALSE;
-	boolean_t ra_from_pcb;
-	u_long last_ipl = ~0L;
-	struct proc *p = NULL;
-	struct thread *td = NULL;
-	boolean_t have_trapframe = FALSE;
-	pid_t pid;
 
 	if (count == -1)
-		count = 65535;
+		count = 1024;
 
-	if (!have_addr) {
-		td = curthread;
-		p = td->td_proc;
-		addr = DDB_REGS->tf_regs[FRAME_SP] - FRAME_SIZE * 8;
-		tf = (struct trapframe *)addr;
-		have_trapframe = 1;
-	} else if (addr < KERNBASE) {
-		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;
-			addr = DDB_REGS->tf_regs[FRAME_SP] - FRAME_SIZE * 8;
-			tf = (struct trapframe *)addr;
-			have_trapframe = 1;
-		} 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;
-			}
-			pcbp = FIRST_THREAD_IN_PROC(p)->td_pcb;	/* XXXKSE */
-			addr = (db_expr_t)pcbp->pcb_hw.apcb_ksp;
-			callpc = pcbp->pcb_context[7];
-			frame = addr;
-		}
-	} else {
-		struct trace_request *tr;
-
-		tr = (struct trace_request *)addr;
-		if (tr->ksp < KERNBASE || tr->pc < KERNBASE) {
-			db_printf("alpha trace requires known PC =eject=\n");
-			return;
-		}
-		callpc = tr->pc;
-		addr = tr->ksp;
-		frame = addr;
-	}
-
+	last_ipl = ~0L;
 	while (count--) {
-		if (have_trapframe) {
-			frame = (db_addr_t)tf + FRAME_SIZE * 8;
-			callpc = tf->tf_regs[FRAME_PC];
-			ra_from_tf = TRUE;
-			have_trapframe = 0;
-		}
-		sym = db_search_symbol(callpc, DB_STGY_ANY, &diff);
+		sym = db_search_symbol(pc, DB_STGY_ANY, &diff);
 		if (sym == DB_SYM_NULL)
-			break;
+			return (ENOENT);
 
 		db_symbol_values(sym, &symname, (db_expr_t *)&symval);
 
-		if (callpc < symval) {
-			db_printf("symbol botch: callpc 0x%lx < "
-			    "func 0x%lx (%s)\n", callpc, symval, symname);
-			return;
+		if (pc < symval) {
+			db_printf("symbol botch: pc 0x%lx < "
+			    "func 0x%lx (%s)\n", pc, symval, symname);
+			return (0);
 		}
 
 		/*
@@ -328,7 +260,7 @@
 		 * debugger (for serious debugging).
 		 */
 		db_printf("%s() at ", symname);
-		db_printsym(callpc, DB_STGY_PROC);
+		db_printsym(pc, DB_STGY_PROC);
 		db_printf("\n");
 
 		/*
@@ -337,7 +269,6 @@
 		 */
 		if (sym_is_trapsymbol(symval)) {
 			tf = (struct trapframe *)frame;
-
 			for (i = 0; special_symbols[i].ss_val != 0; ++i)
 				if (symval == special_symbols[i].ss_val)
 					db_printf("--- %s",
@@ -345,7 +276,7 @@
 
 			tfps = tf->tf_regs[FRAME_PS];
 			if (symval == (uintptr_t)&XentSys)
-				decode_syscall(tf->tf_regs[FRAME_V0], p);
+				decode_syscall(tf->tf_regs[FRAME_V0], td);
 			if ((tfps & ALPHA_PSL_IPL_MASK) != last_ipl) {
 				last_ipl = tfps & ALPHA_PSL_IPL_MASK;
 				if (symval != (uintptr_t)&XentSys)
@@ -356,7 +287,8 @@
 				db_printf("--- user mode ---\n");
 				break;	/* Terminate search.  */
 			}
-			have_trapframe = 1;
+			frame = (db_addr_t)(tf + 1);
+			pc = tf->tf_regs[FRAME_PC];
 			continue;
 		}
 
@@ -366,8 +298,8 @@
 		 *
 		 * XXX How does this interact w/ alloca()?!
 		 */
-		if (decode_prologue(callpc, symval, &pi))
-			return;
+		if (decode_prologue(pc, symval, &pi))
+			return (0);
 		if ((pi.pi_regmask & (1 << 26)) == 0) {
 			/*
 			 * No saved RA found.  We might have RA from
@@ -375,37 +307,59 @@
 			 * in a leaf call).  If not, we've found the
 			 * root of the call graph.
 			 */
-			if (ra_from_tf)
-				callpc = tf->tf_regs[FRAME_RA];
+			if (tf)
+				pc = tf->tf_regs[FRAME_RA];
 			else {
 				db_printf("--- root of call graph ---\n");
 				break;
 			}
 		} else
-			callpc = *(u_long *)(frame + pi.pi_reg_offset[26]);
-		ra_from_tf = ra_from_pcb = FALSE;
-#if 0
-		/*
-		 * The call was actually made at RA - 4; the PC is
-		 * updated before being stored in RA.
-		 */
-		callpc -= 4;
-#endif
+			pc = *(u_long *)(frame + pi.pi_reg_offset[26]);
 		frame += pi.pi_frame_size;
+		tf = NULL;
+	}
+
+	return (0);
+}
+
+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 %d not found\n", (int)addr);
+		return;
 	}
+	tf = td->td_last_frame;
+	db_backtrace(td, tf, (db_addr_t)(tf + 1), tf->tf_regs[FRAME_PC],
+	    count);
 }
 
 void
-db_print_backtrace(void)
+db_trace_self(void)
 {
-	struct trace_request tr;
+	register_t pc, sp;
 
 	__asm __volatile(
 		"	mov $30,%0 \n"
 		"	lda %1,1f \n"
 		"1:\n"
-		: "=r" (tr.ksp), "=r" (tr.pc));
-	db_stack_trace_cmd((db_addr_t)&tr, 1, -1, NULL);
+		: "=r" (sp), "=r" (pc));
+	db_backtrace(curthread, NULL, sp, pc, -1);
+}
+
+int
+db_trace_thread(struct thread *thr, int count)
+{
+	struct trapframe *tf;
+
+	tf = thr->td_last_frame;
+	return (db_backtrace(thr, tf, (db_addr_t)(tf + 1),
+		tf->tf_regs[FRAME_PC], count));
 }
 
 int

==== //depot/projects/gdb/sys/ddb/db_access.c#2 (text+ko) ====

@@ -32,6 +32,7 @@
 __FBSDID("$FreeBSD: src/sys/ddb/db_access.c,v 1.17 2003/08/12 13:24:21 harti Exp $");
 
 #include <sys/param.h>
+#include <sys/kdb.h>
 
 #include <ddb/ddb.h>
 #include <ddb/db_access.h>
@@ -58,7 +59,11 @@
 	register db_expr_t value;
 	register int	i;
 
-	db_read_bytes(addr, size, data);
+	if (db_read_bytes(addr, size, data) != 0) {
+		db_printf("*** error reading from address %llx ***\n",
+		    (long long)addr);
+		kdb_reenter();
+	}
 
 	value = 0;
 #if	BYTE_MSF
@@ -96,6 +101,9 @@
 	    value >>= 8;
 	}
 
-	db_write_bytes(addr, size, data);
+	if (db_write_bytes(addr, size, data) != 0) {
+		db_printf("*** error writing to address %llx ***\n",
+		    (long long)addr);
+		kdb_reenter();
+	}
 }
-

==== //depot/projects/gdb/sys/ddb/db_main.c#7 (text+ko) ====

@@ -45,10 +45,9 @@
 #include <ddb/db_sym.h>
 
 static dbbe_init_f db_init;
-static dbbe_trace_f db_trace;
 static dbbe_trap_f db_trap;
 
-KDB_BACKEND(ddb, db_init, db_trace, db_trap);
+KDB_BACKEND(ddb, db_init, db_trace_self, db_trap);
 
 db_regs_t ddb_regs;
 vm_offset_t ksym_start, ksym_end;
@@ -183,12 +182,6 @@
 	return (1);	/* We're the default debugger. */
 }
 
-static void
-db_trace(void)
-{
-	db_print_backtrace();
-}
-
 static int
 db_trap(int type, int code)
 {

==== //depot/projects/gdb/sys/ddb/db_thread.c#4 (text+ko) ====

@@ -84,6 +84,8 @@
 void
 db_show_threads(db_expr_t addr, boolean_t hasaddr, db_expr_t cnt, char *mod)
 {
+	jmp_buf jb;
+	void *prev_jb;
 	struct thread *thr;
 	int pager_quit;
 
@@ -92,9 +94,11 @@
 	pager_quit = 0;
 	thr = kdb_thr_first();
 	while (!pager_quit && thr != NULL) {
-		db_printf("  %6d (%p) ", (int)thr->td_tid, thr);
-		db_printsym(PC_REGS(thr->td_last_frame), DB_STGY_PROC);
-		db_printf("\n");
+		db_printf("  %6d (%p)  ", (int)thr->td_tid, thr);
+		prev_jb = kdb_jmpbuf(jb);
+		if (setjmp(jb) == 0)
+			db_trace_thread(thr, 1);
+		kdb_jmpbuf(prev_jb);
 		thr = kdb_thr_next(thr);
 	}
 }

==== //depot/projects/gdb/sys/ddb/ddb.h#7 (text+ko) ====

@@ -79,6 +79,7 @@
 extern db_expr_t db_max_width;
 extern db_expr_t db_tab_stop_width;
 
+struct thread;
 struct vm_map;
 
 void		db_check_interrupt(void);
@@ -95,7 +96,7 @@
 void		db_print_loc_and_inst(db_addr_t loc);
 void		db_print_thread(void);
 void		db_printf(const char *fmt, ...) __printflike(1, 2);
-void		db_read_bytes(vm_offset_t addr, size_t size, char *data);
+int		db_read_bytes(vm_offset_t addr, size_t size, char *data);
 				/* machine-dependent */
 int		db_readline(char *lstart, int lsize);
 void		db_restart_at_pc(boolean_t watchpt);
@@ -105,8 +106,10 @@
 void		db_skip_to_eol(void);
 boolean_t	db_stop_at_pc(boolean_t *is_breakpoint);
 #define		db_strcpy	strcpy
+void		db_trace_self(void);
+int		db_trace_thread(struct thread *, int);
 int		db_value_of_name(const char *name, db_expr_t *valuep);
-void		db_write_bytes(vm_offset_t addr, size_t size, char *data);
+int		db_write_bytes(vm_offset_t addr, size_t size, char *data);
 
 db_cmdfcn_t	db_breakpoint_cmd;
 db_cmdfcn_t	db_continue_cmd;
@@ -132,9 +135,6 @@
 
 db_page_calloutfcn_t db_simple_pager;
 
-/* Scare the user with backtrace of curthread to console. */
-void		db_print_backtrace(void);
-
 /*
  * Command table.
  */

==== //depot/projects/gdb/sys/i386/i386/db_interface.c#8 (text+ko) ====

@@ -32,16 +32,12 @@
  */
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/reboot.h>
 #include <sys/cons.h>
+#include <sys/kdb.h>
 #include <sys/pcpu.h>
 #include <sys/proc.h>
-#include <sys/smp.h>
 
 #include <machine/cpu.h>
-#ifdef SMP
-#include <machine/smptests.h>	/** CPUSTOP_ON_DDBBREAK */
-#endif
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
@@ -51,78 +47,92 @@
 /*
  * Read bytes from kernel address space for debugger.
  */
-void
+int
 db_read_bytes(vm_offset_t addr, size_t size, char *data)
 {
-	char	*src;
+	jmp_buf jb;
+	void *prev_jb;
+	char *src;
+	int ret;
 
-	/* db_nofault = &db_jmpbuf; */
-
-	src = (char *)addr;
-	while (size-- > 0)
-	    *data++ = *src++;
-
-	/* db_nofault = 0; */
+	prev_jb = kdb_jmpbuf(jb);
+	ret = setjmp(jb);
+	if (ret == 0) {
+		src = (char *)addr;
+		while (size-- > 0)
+			*data++ = *src++;
+	}
+	(void)kdb_jmpbuf(prev_jb);
+	return (ret);
 }
 
 /*
  * Write bytes to kernel address space for debugger.
  */
-void
+int
 db_write_bytes(vm_offset_t addr, size_t size, char *data)
 {
-	char	*dst;
+	jmp_buf jb;
+	void *prev_jb;
+	char *dst;
+	pt_entry_t *ptep0 = NULL;
+	pt_entry_t oldmap0 = 0;
+	vm_offset_t addr1;
+	pt_entry_t *ptep1 = NULL;
+	pt_entry_t oldmap1 = 0;
+	int ret;
 
-	pt_entry_t	*ptep0 = NULL;
-	pt_entry_t	oldmap0 = 0;
-	vm_offset_t	addr1;
-	pt_entry_t	*ptep1 = NULL;
-	pt_entry_t	oldmap1 = 0;
+	prev_jb = kdb_jmpbuf(jb);
+	ret = setjmp(jb);
+	if (ret == 0) {
+		if (addr > trunc_page((vm_offset_t)btext) - size &&
+		    addr < round_page((vm_offset_t)etext)) {
 
-	/* db_nofault = &db_jmpbuf; */
+			ptep0 = pmap_pte(kernel_pmap, addr);
+			oldmap0 = *ptep0;
+			*ptep0 |= PG_RW;
 
-	if (addr > trunc_page((vm_offset_t)btext) - size &&
-	    addr < round_page((vm_offset_t)etext)) {
+			/*
+			 * Map another page if the data crosses a page
+			 * boundary.
+			 */
+			if ((*ptep0 & PG_PS) == 0) {
+				addr1 = trunc_page(addr + size - 1);
+				if (trunc_page(addr) != addr1) {
+					ptep1 = pmap_pte(kernel_pmap, addr1);
+					oldmap1 = *ptep1;
+					*ptep1 |= PG_RW;
+				}
+			} else {
+				addr1 = trunc_4mpage(addr + size - 1);
+				if (trunc_4mpage(addr) != addr1) {
+					ptep1 = pmap_pte(kernel_pmap, addr1);
+					oldmap1 = *ptep1;
+					*ptep1 |= PG_RW;
+				}
+			}
 
-	    ptep0 = pmap_pte(kernel_pmap, addr);
-	    oldmap0 = *ptep0;
-	    *ptep0 |= PG_RW;
+			invltlb();
+		}
 
-	    /* Map another page if the data crosses a page boundary. */
-	    if ((*ptep0 & PG_PS) == 0) {
-	    	addr1 = trunc_page(addr + size - 1);
-	    	if (trunc_page(addr) != addr1) {
-		    ptep1 = pmap_pte(kernel_pmap, addr1);
-		    oldmap1 = *ptep1;
-		    *ptep1 |= PG_RW;
-	    	}
-	    } else {
-		addr1 = trunc_4mpage(addr + size - 1);
-		if (trunc_4mpage(addr) != addr1) {
-		    ptep1 = pmap_pte(kernel_pmap, addr1);
-		    oldmap1 = *ptep1;
-		    *ptep1 |= PG_RW;
-		}
-	    }
+		dst = (char *)addr;
 
-	    invltlb();
+		while (size-- > 0)
+			*dst++ = *data++;
 	}
 
-	dst = (char *)addr;
+	(void)kdb_jmpbuf(prev_jb);
 
-	while (size-- > 0)
-	    *dst++ = *data++;
-
-	/* db_nofault = 0; */
-
 	if (ptep0) {
-	    *ptep0 = oldmap0;
+		*ptep0 = oldmap0;
 
-	    if (ptep1)
-		*ptep1 = oldmap1;
+		if (ptep1)
+			*ptep1 = oldmap1;
 
-	    invltlb();
+		invltlb();
 	}
+
+	return (ret);
 }
 
 void

==== //depot/projects/gdb/sys/i386/i386/db_trace.c#4 (text+ko) ====

@@ -325,61 +325,26 @@
 	*fp = (struct i386_frame *) ebp;
 }
 
-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 i386_frame *frame,
+    db_addr_t pc, int count)
 {
-	struct trapframe *tf;
-	struct i386_frame *frame;
-	struct thread *td;
+	struct i386_frame *actframe;
+#define MAXNARG	16
+	char *argnames[MAXNARG], **argnp = NULL;
+	const char *name;
 	int *argp;
-	db_addr_t callpc;
-	pid_t tid;
+	db_expr_t offset;
+	c_db_sym_t sym;
+	int narg;
 	boolean_t first;
 
 	if (count == -1)
 		count = 1024;
 
-	if (!have_addr) {
-		td = kdb_thread;
-		tf = kdb_frame;
-		frame = (void *)tf->tf_ebp;
-		callpc = (db_addr_t)tf->tf_eip;
-	} else if (!INKERNEL(addr)) {
-		tid = (addr % 16) + ((addr >> 4) % 16) * 10 +
-		    ((addr >> 8) % 16) * 100 + ((addr >> 12) % 16) * 1000 +
-		    ((addr >> 16) % 16) * 10000;
-		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 {
-		td = NULL;
-		tf = NULL;
-		frame = (struct i386_frame *)addr;
-		callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4,
-		    FALSE);
-		frame = frame->f_frame;
-	}
-
 	first = TRUE;
 	while (count--) {
-		struct i386_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);
 
 		/*
@@ -395,10 +360,10 @@
 		 */
 		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 & 0xffffff) == 0x00e58955) {
 					/* pushl %ebp; movl %esp, %ebp */
 					actframe = (void *)(get_esp() - 4);
@@ -421,7 +386,7 @@
 				 * 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;
@@ -435,36 +400,70 @@
 			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((int)&actframe->f_retaddr, 4, FALSE);
 			continue;
 		}
 
-		db_nextframe(&frame, &callpc, td);
+		db_nextframe(&frame, &pc, td);
 
-		if (INKERNEL((int) callpc) && !INKERNEL((int) frame)) {
-			sym = db_search_symbol(callpc, DB_STGY_ANY, &offset);
+		if (INKERNEL((int)pc) && !INKERNEL((int) 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((int) frame)) {
 			break;
 		}
 	}
+
+	return (0);
+}
+
+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 %d not found\n", addr);
+		return;
+	}
+	tf = td->td_last_frame;
+	db_backtrace(td, tf, (struct i386_frame *)tf->tf_ebp,
+	    (db_addr_t)tf->tf_eip, count);
 }
 
 void
-db_print_backtrace(void)
+db_trace_self(void)
 {
+	struct i386_frame *frame;
+	db_addr_t callpc;
 	register_t ebp;
 
 	__asm __volatile("movl %%ebp,%0" : "=r" (ebp));
-	db_stack_trace_cmd(ebp, 1, -1, NULL);
+	frame = (struct i386_frame *)ebp;
+	callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4, FALSE);
+	frame = frame->f_frame;
+	db_backtrace(curthread, NULL, frame, callpc, -1);
+}
+
+int
+db_trace_thread(struct thread *thr, int count)
+{
+	struct trapframe *tf;
+
+	tf = thr->td_last_frame;
+	return (db_backtrace(thr, tf, (struct i386_frame *)tf->tf_ebp,
+		(db_addr_t)tf->tf_eip, count));
 }
 
 int

==== //depot/projects/gdb/sys/i386/include/frame.h#4 (text+ko) ====

@@ -149,6 +149,7 @@
 	int	cf_ss;
 };
 
+#define	CLOCK_TO_TRAPFRAME(frame) ((struct trapframe *)&(frame)->cf_fs)
 #define	INTR_TO_TRAPFRAME(frame) ((struct trapframe *)&(frame)->if_fs)
 
 #endif /* _MACHINE_FRAME_H_ */

==== //depot/projects/gdb/sys/i386/isa/clock.c#9 (text+ko) ====

@@ -176,6 +176,8 @@
 clkintr(struct clockframe *frame)
 {
 
+	curthread->td_last_frame = CLOCK_TO_TRAPFRAME(frame);
+
 	if (timecounter->tc_get_timecount == i8254_get_timecount) {
 		mtx_lock_spin(&clock_lock);
 		if (i8254_ticked)
@@ -367,6 +369,9 @@
 static void
 rtcintr(struct clockframe *frame)
 {
+
+	curthread->td_last_frame = CLOCK_TO_TRAPFRAME(frame);
+
 	while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
 		if (profprocs != 0) {
 			if (--pscnt == 0)

==== //depot/projects/gdb/sys/ia64/ia64/db_interface.c#7 (text+ko) ====

@@ -33,13 +33,14 @@
  * Interface to DDB.
  */
 #include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/cons.h>
+#include <sys/kdb.h>
+#include <sys/ktr.h>
+#include <sys/kernel.h>
 #include <sys/proc.h>
 #include <sys/reboot.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
 #include <sys/smp.h>
-#include <sys/cons.h>
-#include <sys/ktr.h>
 
 #include <vm/vm.h>
 
@@ -61,9 +62,6 @@
 #define	SLOT_MASK	((1ULL << SLOT_BITS) - 1ULL)
 #define	SLOT_SHIFT(i)	(TMPL_BITS+((i)<<3)+(i))
 
-static jmp_buf *db_nofault = 0;
-extern jmp_buf	db_jmpbuf;
-
 static int db_get_rse_reg(struct db_variable *vp, db_expr_t *valuep, int op);
 static int db_get_ip_reg(struct db_variable *vp, db_expr_t *valuep, int op);
 
@@ -259,35 +257,45 @@
 /*
  * Read bytes from kernel address space for debugger.
  */
-void
+int
 db_read_bytes(vm_offset_t addr, size_t size, char *data)
 {
+	jmp_buf jb;
+	void *prev_jb;
+	char *src;
+	int ret;
 
-	db_nofault = &db_jmpbuf;
-
-	if (addr < VM_MAX_ADDRESS)
-		copyin((char *)addr, data, size);
-	else
-		bcopy((char *)addr, data, size);
-
-	db_nofault = 0;
+	prev_jb = kdb_jmpbuf(jb);
+	ret = setjmp(jb);
+	if (ret == 0) {
+		src = (char *)addr;
+		while (size-- > 0)
+			*data++ = *src++;
+	}
+	(void)kdb_jmpbuf(prev_jb);
+	return (ret);
 }
 
 /*
  * Write bytes to kernel address space for debugger.
  */
-void
+int
 db_write_bytes(vm_offset_t addr, size_t size, char *data)
 {
+	jmp_buf jb;
+	void *prev_jb;
+	char *dst;
+	int ret;
 
-	db_nofault = &db_jmpbuf;
-
-	if (addr < VM_MAX_ADDRESS)
-		copyout(data, (char *)addr, size);
-	else

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list