Date: Tue, 23 Mar 2004 21:33:40 -0800 (PST) From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 49608 for review Message-ID: <200403240533.i2O5XeMV049506@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=49608 Change 49608 by marcel@marcel_nfs on 2004/03/23 21:32:58 Make "info thread" work (basicly). Much has changed: o Register context is now based on struct thread, not on struct trapframe. A global variable, kdb_thread, is used to hold the current thread. This means that we don't pass struct trapframe around anymore. o A start has been made to unify the MD functions for the gdb backend and the ddb backend. Common MD functions have been implemented as inline functions in <machine/kdb.h> o Move the prototypes for the MD functions for the gdb backend to <machine/gdb_machdep.h> where they can be implemented as inlines. Only i386 and ia64 have been changed for now. Affected files ... .. //depot/projects/gdb/sys/ddb/db_main.c#2 edit .. //depot/projects/gdb/sys/gdb/gdb.h#7 edit .. //depot/projects/gdb/sys/gdb/gdb_int.h#4 edit .. //depot/projects/gdb/sys/gdb/gdb_main.c#8 edit .. //depot/projects/gdb/sys/gdb/gdb_packet.c#4 edit .. //depot/projects/gdb/sys/i386/i386/gdb_machdep.c#4 edit .. //depot/projects/gdb/sys/i386/include/gdb_machdep.h#3 edit .. //depot/projects/gdb/sys/i386/include/kdb.h#1 add .. //depot/projects/gdb/sys/ia64/ia64/gdb_machdep.c#4 edit .. //depot/projects/gdb/sys/ia64/include/gdb_machdep.h#3 edit .. //depot/projects/gdb/sys/ia64/include/kdb.h#1 add .. //depot/projects/gdb/sys/kern/subr_kdb.c#8 edit .. //depot/projects/gdb/sys/sys/kdb.h#6 edit Differences ... ==== //depot/projects/gdb/sys/ddb/db_main.c#2 (text+ko) ==== @@ -37,6 +37,7 @@ #include <sys/proc.h> #include <sys/reboot.h> +#include <machine/kdb.h> #include <machine/setjmp.h> #include <ddb/ddb.h> @@ -117,7 +118,7 @@ } static int -db_trap(int type, int code, struct trapframe *tf) +db_trap(int type, int code) { boolean_t bkpt, watchpt; @@ -128,10 +129,8 @@ if (cnunavailable()) return (0); - db_cpu_trap(type, code, tf); + ddb_regs = *kdb_thread->td_frame; - ddb_regs = *tf; - bkpt = IS_BREAKPOINT_TRAP(type, code); watchpt = IS_WATCHPOINT_TRAP(type, code); @@ -154,7 +153,7 @@ db_restart_at_pc(watchpt); - *tf = ddb_regs; + *kdb_thread->td_frame = ddb_regs; return (1); } ==== //depot/projects/gdb/sys/gdb/gdb.h#7 (text+ko) ==== @@ -59,14 +59,4 @@ }; \ DATA_SET(gdb_dbgport_set, name##_gdb_dbgport) -struct trapframe; - -uintmax_t gdb_cpu_getreg(int, struct trapframe *); -ssize_t gdb_cpu_getregs(struct trapframe *, void *, size_t); -int gdb_cpu_regsz(int); -void gdb_cpu_setreg(int, struct trapframe *, uintmax_t); -int gdb_cpu_signal(int, int); -void gdb_cpu_singlestep(int, struct trapframe *); -void gdb_cpu_trap(int, int, struct trapframe *); - #endif /* !_GDB_GDB_H_ */ ==== //depot/projects/gdb/sys/gdb/gdb_int.h#4 (text+ko) ==== @@ -36,6 +36,7 @@ extern char *gdb_txp; int gdb_rx_begin(void); +int gdb_rx_equal(const char *); int gdb_rx_varhex(uintmax_t *); static __inline int @@ -54,8 +55,8 @@ void gdb_tx_begin(char); int gdb_tx_end(void); int gdb_tx_memory(const unsigned char *, size_t); -void gdb_tx_reg(int, struct trapframe *); -int gdb_tx_regs(struct trapframe *); +void gdb_tx_reg(int); +int gdb_tx_regs(void); static __inline void gdb_tx_char(char c) @@ -84,6 +85,14 @@ return (gdb_tx_end()); } +static __inline int +gdb_tx_ok(void) +{ + gdb_tx_begin('O'); + gdb_tx_char('K'); + return (gdb_tx_end()); +} + static __inline void gdb_tx_str(const char *s) { ==== //depot/projects/gdb/sys/gdb/gdb_main.c#8 (text+ko) ==== @@ -36,6 +36,7 @@ #include <sys/reboot.h> #include <machine/gdb_machdep.h> +#include <machine/kdb.h> #include <gdb/gdb.h> #include <gdb/gdb_int.h> @@ -89,36 +90,29 @@ } static int -gdb_trap(int type, int code, struct trapframe *tf) +gdb_trap(int type, int code) { - struct proc *p; uintmax_t addr, size; - int tid_cont, tid_gen; + struct proc *thr_iter; - p = curthread->td_proc; - tid_cont = -1; - tid_gen = (p != NULL) ? p->p_pid : 0; - - /* Give MD code a change to set things up. */ - gdb_cpu_trap(type, code, tf); - /* * Send a T packet. We currently do not support watchpoints (the * awatch, rwatch or watch elements). */ gdb_tx_begin('T'); gdb_tx_hex(gdb_cpu_signal(type, code), 2); - gdb_tx_reg(GDB_REG_PC, tf); + gdb_tx_reg(GDB_REG_PC); gdb_tx_char(';'); - gdb_tx_reg(GDB_REG_FP, tf); + gdb_tx_reg(GDB_REG_FP); gdb_tx_char(';'); - gdb_tx_reg(GDB_REG_SP, tf); + gdb_tx_reg(GDB_REG_SP); gdb_tx_char(';'); gdb_tx_str("thread:"); - gdb_tx_varhex(tid_gen); + gdb_tx_varhex(kdb_thread->td_tid); gdb_tx_char(';'); gdb_tx_end(); /* XXX check error condition. */ + thr_iter = NULL; while (gdb_rx_begin() == 0) { printf("GDB: got '%s'\n", gdb_rxp); switch (gdb_rx_char()) { @@ -129,15 +123,27 @@ break; case 'c': /* continue */ if (!gdb_rx_varhex(&addr)) - gdb_cpu_setreg(GDB_REG_PC, tf, addr); - gdb_cpu_singlestep(0, tf); + gdb_cpu_setreg(GDB_REG_PC, addr); + kdb_cpu_clear_singlestep(); return (1); case 'g': - gdb_tx_regs(tf); + gdb_tx_regs(); break; case 'G': gdb_tx_err(0); break; + case 'H': { + intmax_t tid; + gdb_rx_char(); + gdb_rx_varhex(&tid); + if (tid > 0) + kdb_set_thread(tid); + gdb_tx_ok(); + break; + } + case 'k': + kdb_cpu_clear_singlestep(); + return (1); case 'm': if (gdb_rx_varhex(&addr) || gdb_rx_char() != ',' || gdb_rx_varhex(&size)) @@ -148,10 +154,33 @@ case 'M': gdb_tx_err(0); break; + case 'q': + if (gdb_rx_equal("fThreadInfo")) { + thr_iter = LIST_FIRST(&allproc); + gdb_tx_begin('m'); + gdb_tx_hex(thr_iter->p_pid, 8); + gdb_tx_end(); + } else if (gdb_rx_equal("sThreadInfo")) { + if (thr_iter == NULL) { + gdb_tx_err(ENXIO); + break; + } + thr_iter = LIST_NEXT(thr_iter, p_list); + if (thr_iter != NULL) { + gdb_tx_begin('m'); + gdb_tx_hex(thr_iter->p_pid, 8); + gdb_tx_end(); + } else { + gdb_tx_begin('l'); + gdb_tx_end(); + } + } else + gdb_tx_empty(); + break; case 's': /* single step */ if (!gdb_rx_varhex(&addr)) - gdb_cpu_setreg(GDB_REG_PC, tf, addr); - gdb_cpu_singlestep(1, tf); + gdb_cpu_setreg(GDB_REG_PC, addr); + kdb_cpu_set_singlestep(); return (1); case -1: /* Empty command. Treat as unknown command. */ ==== //depot/projects/gdb/sys/gdb/gdb_packet.c#4 (text+ko) ==== @@ -98,6 +98,19 @@ } int +gdb_rx_equal(const char *str) +{ + int len; + + len = strlen(str); + if (len > gdb_rxsz || strncmp(str, gdb_rxp, len) != 0) + return (0); + gdb_rxp += len; + gdb_rxsz -= len; + return (1); +} + +int gdb_rx_varhex(uintmax_t *vp) { uintmax_t v; @@ -142,6 +155,34 @@ } int +gdb_tx_end(void) +{ + const char *p; + unsigned char c, cksum; + + do { + gdb_cur->gdb_putc('$'); + + cksum = 0; + p = gdb_txbuf; + while (p < gdb_txp) { + gdb_cur->gdb_putc(*p); + cksum += *p++; + } + + gdb_cur->gdb_putc('#'); + c = cksum >> 4; + gdb_cur->gdb_putc(N2C(c)); + c = cksum & 0x0f; + gdb_cur->gdb_putc(N2C(c)); + + c = gdb_cur->gdb_getc(); + } while (c != '+'); + + return (0); +} + +int gdb_tx_memory(const unsigned char *addr, size_t size) { @@ -159,49 +200,21 @@ } void -gdb_tx_reg(int regnum, struct trapframe *tf) +gdb_tx_reg(int regnum) { gdb_tx_varhex(regnum); gdb_tx_char(':'); - gdb_tx_hex(gdb_cpu_getreg(regnum, tf), gdb_cpu_regsz(regnum) << 1); + gdb_tx_hex(gdb_cpu_getreg(regnum), gdb_cpu_regsz(regnum) << 1); } int -gdb_tx_regs(struct trapframe *tf) +gdb_tx_regs(void) { ssize_t regsz; - regsz = gdb_cpu_getregs(tf, gdb_rxbuf, sizeof(gdb_rxbuf)); + regsz = gdb_cpu_getregs(gdb_rxbuf, sizeof(gdb_rxbuf)); if (regsz < 0) return (gdb_tx_err(ENOSPC)); return (gdb_tx_memory(gdb_rxbuf, regsz)); } - -int -gdb_tx_end(void) -{ - const char *p; - unsigned char c, cksum; - - do { - gdb_cur->gdb_putc('$'); - - cksum = 0; - p = gdb_txbuf; - while (p < gdb_txp) { - gdb_cur->gdb_putc(*p); - cksum += *p++; - } - - gdb_cur->gdb_putc('#'); - c = cksum >> 4; - gdb_cur->gdb_putc(N2C(c)); - c = cksum & 0x0f; - gdb_cur->gdb_putc(N2C(c)); - - c = gdb_cur->gdb_getc(); - } while (c != '+'); - - return (0); -} ==== //depot/projects/gdb/sys/i386/i386/gdb_machdep.c#4 (text+ko) ==== @@ -29,7 +29,9 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/kdb.h> #include <sys/kernel.h> +#include <sys/proc.h> #include <sys/signal.h> #include <machine/frame.h> @@ -40,20 +42,23 @@ #include <gdb/gdb.h> -uintmax_t -gdb_cpu_getreg(int regnum, struct trapframe *tf) +register_t +gdb_cpu_getreg(int regnum) { + struct trapframe *tf = kdb_thread->td_frame; + switch (regnum) { - case GDB_REG_FP: return ((unsigned int)tf->tf_ebp); - case GDB_REG_PC: return ((unsigned int)tf->tf_eip); - case GDB_REG_SP: return ((unsigned int)tf->tf_esp); + case GDB_REG_FP: return (tf->tf_ebp); + case GDB_REG_PC: return (tf->tf_eip); + case GDB_REG_SP: return (tf->tf_esp); } return (0); } ssize_t -gdb_cpu_getregs(struct trapframe *tf, void *buf, size_t bufsz) +gdb_cpu_getregs(void *buf, size_t bufsz) { + struct trapframe *tf = kdb_thread->td_frame; struct reg *r = buf; if (sizeof(*r) > bufsz) @@ -77,15 +82,11 @@ return (sizeof(*r)); } -int -gdb_cpu_regsz(int regnum) +void +gdb_cpu_setreg(int regnum, register_t val) { - return (4); /* XXX not really. */ -} + struct trapframe *tf = kdb_thread->td_frame; -void -gdb_cpu_setreg(int regnum, struct trapframe *tf, uintmax_t val) -{ switch (regnum) { case GDB_REG_FP: tf->tf_ebp = val; break; case GDB_REG_PC: tf->tf_eip = val; break; @@ -116,15 +117,3 @@ } return (SIGEMT); } - -void -gdb_cpu_singlestep(int on, struct trapframe *tf) -{ - tf->tf_eflags &= ~PSL_T; - tf->tf_eflags |= (on) ? PSL_T : 0; -} - -void -gdb_cpu_trap(int type, int code, struct trapframe *tf) -{ -} ==== //depot/projects/gdb/sys/i386/include/gdb_machdep.h#3 (text+ko) ==== @@ -35,4 +35,15 @@ #define GDB_REG_PC 8 #define GDB_REG_SP 4 +static __inline int +gdb_cpu_regsz(int regnum) +{ + return (4); /* XXX not really. */ +} + +register_t gdb_cpu_getreg(int); +ssize_t gdb_cpu_getregs(void *, size_t); +void gdb_cpu_setreg(int, register_t); +int gdb_cpu_signal(int, int); + #endif /* !_MACHINE_GDB_MACHDEP_H_ */ ==== //depot/projects/gdb/sys/ia64/ia64/gdb_machdep.c#4 (text+ko) ==== @@ -29,7 +29,9 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/kdb.h> #include <sys/kernel.h> +#include <sys/proc.h> #include <sys/signal.h> #include <machine/frame.h> @@ -38,9 +40,11 @@ #include <gdb/gdb.h> -uintmax_t -gdb_cpu_getreg(int regnum, struct trapframe *tf) +register_t +gdb_cpu_getreg(int regnum) { + struct trapframe *tf = kdb_thread->td_frame; + switch (regnum) { case GDB_REG_FP: return (tf->tf_special.bspstore + tf->tf_special.ndirty); @@ -53,8 +57,9 @@ } ssize_t -gdb_cpu_getregs(struct trapframe *tf, void *buf, size_t bufsz) +gdb_cpu_getregs(void *buf, size_t bufsz) { + struct trapframe *tf = kdb_thread->td_frame; struct reg *r = buf; if (sizeof(*r) > bufsz) @@ -65,37 +70,13 @@ return (sizeof(*r)); } -int -gdb_cpu_regsz(int regnum) +void +gdb_cpu_setreg(int regnum, register_t val) { - return (8); /* XXX not really. */ -} -void -gdb_cpu_setreg(int regnum, struct trapframe *tf, uintmax_t val) -{ switch (regnum) { case GDB_REG_FP: break; case GDB_REG_PC: break; case GDB_REG_SP: break; } } - -int -gdb_cpu_signal(int vector, int dummy) -{ - return (vector); -} - -void -gdb_cpu_singlestep(int on, struct trapframe *tf) -{ -} - -void -gdb_cpu_trap(int vector, int dummy, struct trapframe *tf) -{ - __asm __volatile("flushrs;;"); - if (vector == IA64_VEC_BREAK && tf->tf_special.ifa == IA64_FIXED_BREAK) - tf->tf_special.psr += IA64_PSR_RI_1; -} ==== //depot/projects/gdb/sys/ia64/include/gdb_machdep.h#3 (text+ko) ==== @@ -35,4 +35,20 @@ #define GDB_REG_PC 331 #define GDB_REG_SP 12 +static __inline int +gdb_cpu_regsz(int regnum) +{ + return (8); /* XXX not really. */ +} + +static __inline int +gdb_cpu_signal(int vector, int _) +{ + return (vector); +} + +register_t gdb_cpu_getreg(int); +ssize_t gdb_cpu_getregs(void *, size_t); +void gdb_cpu_setreg(int, register_t); + #endif /* !_MACHINE_GDB_MACHDEP_H_ */ ==== //depot/projects/gdb/sys/kern/subr_kdb.c#8 (text+ko) ==== @@ -32,10 +32,14 @@ #include <sys/kdb.h> #include <sys/kernel.h> #include <sys/pcpu.h> +#include <sys/proc.h> #include <sys/smp.h> +#include <machine/kdb.h> + int kdb_active = 0; struct kdb_dbbe *kdb_dbbe = NULL; +struct thread *kdb_thread = NULL; KDB_BACKEND(null, NULL, NULL, NULL); SET_DECLARE(kdb_dbbe_set, struct kdb_dbbe); @@ -150,7 +154,24 @@ } /* - * + * Switch the current thread. + */ + +int +kdb_set_thread(pid_t tid) +{ + struct proc *p; + + p = LIST_FIRST(&allproc); + while (p != NULL && p->p_pid != tid) + p = LIST_NEXT(p, p_list); + if (p != NULL) + kdb_thread = FIRST_THREAD_IN_PROC(p); + return ((p != NULL) ? 1 : 0); +} + +/* + * Enter the debugger due to a trap. */ int @@ -163,18 +184,25 @@ critical_enter(); + kdb_active++; + kdb_thread = curthread; + kdb_thread->td_frame = tf; + #ifdef SMP stop_cpus(PCPU_GET(other_cpus)); #endif - kdb_active++; - handled = kdb_dbbe->dbbe_trap(type, code, tf); - kdb_active--; + /* Let MD code do its thing first... */ + kdb_cpu_trap(type, code); + + handled = kdb_dbbe->dbbe_trap(type, code); #ifdef SMP restart_cpus(stopped_cpus); #endif + kdb_active--; + critical_exit(); return (handled); ==== //depot/projects/gdb/sys/sys/kdb.h#6 (text+ko) ==== @@ -29,11 +29,9 @@ #ifndef _SYS_KDB_H_ #define _SYS_KDB_H_ -struct trapframe; - typedef int dbbe_init_f(void); typedef void dbbe_trace_f(void); -typedef int dbbe_trap_f(int, int, struct trapframe *); +typedef int dbbe_trap_f(int, int); struct kdb_dbbe { const char *dbbe_name; @@ -52,13 +50,18 @@ }; \ DATA_SET(kdb_dbbe_set, name##_dbbe) +struct thread; +struct trapframe; + extern int kdb_active; /* Non-zero while in debugger. */ extern struct kdb_dbbe *kdb_dbbe; /* Default debugger backend or NULL. */ +extern struct thread *kdb_thread; /* Current thread. */ int kdb_alt_break(int, int *); void kdb_backtrace(void); void kdb_enter(const char *); void kdb_init(void); +int kdb_set_thread(pid_t); int kdb_trap(int, int, struct trapframe *); #endif /* !_SYS_KDB_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200403240533.i2O5XeMV049506>