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>