From owner-p4-projects@FreeBSD.ORG Sun May 30 20:46:42 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 5E8FD16A4D0; Sun, 30 May 2004 20:46:42 -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 19F7A16A4CE for ; Sun, 30 May 2004 20:46:42 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 126C143D45 for ; Sun, 30 May 2004 20:46:42 -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 i4V3kftv075058 for ; Sun, 30 May 2004 20:46:41 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.11/8.12.11/Submit) id i4V3kfhK075055 for perforce@freebsd.org; Sun, 30 May 2004 20:46:41 -0700 (PDT) (envelope-from marcel@freebsd.org) Date: Sun, 30 May 2004 20:46:41 -0700 (PDT) Message-Id: <200405310346.i4V3kfhK075055@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 53843 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: Mon, 31 May 2004 03:46:43 -0000 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 #include +#include #include #include @@ -46,14 +47,23 @@ #include #include -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)