From owner-p4-projects@FreeBSD.ORG Sat May 22 19:04:03 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id DF2A016A4D0; Sat, 22 May 2004 19:04:02 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A798616A4CE for ; Sat, 22 May 2004 19:04:02 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 83BFE43D41 for ; Sat, 22 May 2004 19:04:02 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.11/8.12.11) with ESMTP id i4N23RmM097280 for ; Sat, 22 May 2004 19:03:27 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.11/8.12.11/Submit) id i4N23REm097277 for perforce@freebsd.org; Sat, 22 May 2004 19:03:27 -0700 (PDT) (envelope-from marcel@freebsd.org) Date: Sat, 22 May 2004 19:03:27 -0700 (PDT) Message-Id: <200405230203.i4N23REm097277@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Subject: PERFORCE change 53266 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 23 May 2004 02:04:03 -0000 http://perforce.freebsd.org/chv.cgi?CH=53266 Change 53266 by marcel@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 -#include -#include #include +#include +#include #include -#include -#include -#include #include +#include #include #include @@ -73,11 +71,7 @@ #include #include #include -#include -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 #include +#include #include #include #include @@ -60,11 +61,6 @@ #include #include -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 +#include #include #include @@ -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 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 #include -#include #include +#include #include #include -#include #include -#ifdef SMP -#include /** CPUSTOP_ON_DDBBREAK */ -#endif #include #include @@ -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 +#include +#include +#include +#include +#include #include #include -#include -#include #include -#include -#include #include @@ -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) <<<