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