Index: contrib/gdb/gdb/frame.h =================================================================== RCS file: /home/ncvs/src/contrib/gdb/gdb/frame.h,v retrieving revision 1.1.1.4 diff -u -r1.1.1.4 frame.h --- contrib/gdb/gdb/frame.h 20 Jun 2004 18:17:03 -0000 1.1.1.4 +++ contrib/gdb/gdb/frame.h 30 Jan 2005 04:10:26 -0000 @@ -551,7 +551,7 @@ extern void show_and_print_stack_frame (struct frame_info *fi, int level, int source); -extern void print_stack_frame (struct frame_info *, int, int); +extern int print_stack_frame (struct frame_info *, int, int); extern void show_stack_frame (struct frame_info *); Index: contrib/gdb/gdb/stack.c =================================================================== RCS file: /home/ncvs/src/contrib/gdb/gdb/stack.c,v retrieving revision 1.1.1.4 diff -u -r1.1.1.4 stack.c --- contrib/gdb/gdb/stack.c 20 Jun 2004 18:20:35 -0000 1.1.1.4 +++ contrib/gdb/gdb/stack.c 30 Jan 2005 04:10:26 -0000 @@ -134,7 +134,7 @@ struct print_stack_frame_args *p = (struct print_stack_frame_args *) args; print_frame_info (p->fi, p->level, p->source, p->args); - return 0; + return 1; } /* Show or print a stack frame briefly. FRAME_INFI should be the frame info @@ -147,7 +147,7 @@ If SOURCE is 1, print the source line as well. If SOURCE is -1, print ONLY the source line. */ -void +int print_stack_frame (struct frame_info *fi, int level, int source) { struct print_stack_frame_args args; @@ -157,7 +157,7 @@ args.source = source; args.args = 1; - catch_errors (print_stack_frame_stub, (char *) &args, "", RETURN_MASK_ALL); + return catch_errors (print_stack_frame_stub, (char *) &args, "", RETURN_MASK_ALL); } struct print_args_args Index: contrib/gdb/gdb/thread.c =================================================================== RCS file: /home/ncvs/src/contrib/gdb/gdb/thread.c,v retrieving revision 1.4 diff -u -r1.4 thread.c --- contrib/gdb/gdb/thread.c 20 Jun 2004 19:47:26 -0000 1.4 +++ contrib/gdb/gdb/thread.c 30 Jan 2005 04:10:26 -0000 @@ -448,7 +448,8 @@ puts_filtered (" "); switch_to_thread (tp->ptid); - print_stack_frame (get_selected_frame (), -1, 0); + if (print_stack_frame (get_selected_frame (), -1, 0) == 0) + break; } switch_to_thread (current_ptid); Index: gnu/usr.bin/gdb/Makefile.inc =================================================================== RCS file: /home/ncvs/src/gnu/usr.bin/gdb/Makefile.inc,v retrieving revision 1.10 diff -u -r1.10 Makefile.inc --- gnu/usr.bin/gdb/Makefile.inc 6 Jul 2004 21:55:11 -0000 1.10 +++ gnu/usr.bin/gdb/Makefile.inc 30 Jan 2005 04:13:02 -0000 @@ -33,6 +33,7 @@ CFLAGS+= -I${CNTRB_GDB}/include CFLAGS+= -I${CNTRB_BU}/include CFLAGS+= -I${CNTRB_BU}/bfd +CFLAGS+= -g GENSRCS+= nm.h tm.h Index: gnu/usr.bin/gdb/kgdb/Makefile =================================================================== RCS file: /home/ncvs/src/gnu/usr.bin/gdb/kgdb/Makefile,v retrieving revision 1.1 diff -u -r1.1 Makefile --- gnu/usr.bin/gdb/kgdb/Makefile 25 Jul 2004 05:29:15 -0000 1.1 +++ gnu/usr.bin/gdb/kgdb/Makefile 30 Jan 2005 04:13:27 -0000 @@ -1,7 +1,7 @@ # $FreeBSD: src/gnu/usr.bin/gdb/kgdb/Makefile,v 1.1 2004/07/25 05:29:15 marcel Exp $ -PROG= kgdb -SRCS= kthr.c main.c trgt.c trgt_${MACHINE_ARCH}.c +PROG= kgdb${GDB_SUFFIX} +SRCS= main.c kthr.c trgt.c trgt_${MACHINE_ARCH}.c WARNS?= 2 BULIBS= ${OBJ_BU}/libbfd/libbfd.a ${OBJ_BU}/libopcodes/libopcodes.a \ Index: gnu/usr.bin/gdb/kgdb/kgdb.h =================================================================== RCS file: /home/ncvs/src/gnu/usr.bin/gdb/kgdb/kgdb.h,v retrieving revision 1.1 diff -u -r1.1 kgdb.h --- gnu/usr.bin/gdb/kgdb/kgdb.h 25 Jul 2004 05:29:15 -0000 1.1 +++ gnu/usr.bin/gdb/kgdb/kgdb.h 30 Jan 2005 04:11:14 -0000 @@ -29,15 +29,19 @@ #ifndef _KGDB_H_ #define _KGDB_H_ +struct thread_info; + extern kvm_t *kvm; extern int verbose; struct kthr { struct kthr *next; + uintptr_t paddr; uintptr_t kaddr; uintptr_t kstack; uintptr_t pcb; int tid; + int pid; }; extern struct kthr *curkthr; @@ -48,8 +52,12 @@ struct kthr *kgdb_thr_first(void); struct kthr *kgdb_thr_init(void); -struct kthr *kgdb_thr_lookup(int); +struct kthr *kgdb_thr_lookup_tid(int); +struct kthr *kgdb_thr_lookup_pid(int); +struct kthr *kgdb_thr_lookup_paddr(uintptr_t); +struct kthr *kgdb_thr_lookup_taddr(uintptr_t); struct kthr *kgdb_thr_next(struct kthr *); struct kthr *kgdb_thr_select(struct kthr *); +char *kgdb_thr_extra_thread_info(int); #endif /* _KGDB_H_ */ Index: gnu/usr.bin/gdb/kgdb/kthr.c =================================================================== RCS file: /home/ncvs/src/gnu/usr.bin/gdb/kgdb/kthr.c,v retrieving revision 1.1 diff -u -r1.1 kthr.c --- gnu/usr.bin/gdb/kgdb/kthr.c 25 Jul 2004 05:29:15 -0000 1.1 +++ gnu/usr.bin/gdb/kgdb/kthr.c 30 Jan 2005 04:11:14 -0000 @@ -37,6 +37,8 @@ #include #include +#include + #include "kgdb.h" static uintptr_t dumppcb; @@ -102,19 +104,21 @@ (uintptr_t)td.td_pcb; kt->kstack = td.td_kstack; kt->tid = td.td_tid; + kt->pid = p.p_pid; + kt->paddr = paddr; first = kt; addr = (uintptr_t)TAILQ_NEXT(&td, td_plist); } paddr = (uintptr_t)LIST_NEXT(&p, p_list); } - curkthr = kgdb_thr_lookup(dumptid); + curkthr = kgdb_thr_lookup_tid(dumptid); if (curkthr == NULL) curkthr = first; return (first); } struct kthr * -kgdb_thr_lookup(int tid) +kgdb_thr_lookup_tid(int tid) { struct kthr *kt; @@ -125,6 +129,39 @@ } struct kthr * +kgdb_thr_lookup_taddr(uintptr_t taddr) +{ + struct kthr *kt; + + kt = first; + while (kt != NULL && kt->kaddr != taddr) + kt = kt->next; + return (kt); +} + +struct kthr * +kgdb_thr_lookup_pid(int pid) +{ + struct kthr *kt; + + kt = first; + while (kt != NULL && kt->pid != pid) + kt = kt->next; + return (kt); +} + +struct kthr * +kgdb_thr_lookup_paddr(uintptr_t paddr) +{ + struct kthr *kt; + + kt = first; + while (kt != NULL && kt->paddr != paddr) + kt = kt->next; + return (kt); +} + +struct kthr * kgdb_thr_next(struct kthr *kt) { return (kt->next); @@ -139,3 +176,21 @@ curkthr = kt; return (pcur); } + +char * +kgdb_thr_extra_thread_info(int tid) +{ + struct kthr *kt; + struct proc *p; + static char comm[MAXCOMLEN + 1]; + + kt = kgdb_thr_lookup_tid(tid); + if (kt == NULL) + return (NULL); + p = (struct proc *)kt->paddr; + if (kvm_read(kvm, (uintptr_t)&p->p_comm[0], &comm, sizeof(comm)) != + sizeof(comm)) + return (NULL); + + return (comm); +} Index: gnu/usr.bin/gdb/kgdb/main.c =================================================================== RCS file: /home/ncvs/src/gnu/usr.bin/gdb/kgdb/main.c,v retrieving revision 1.2.2.1 diff -u -r1.2.2.1 main.c --- gnu/usr.bin/gdb/kgdb/main.c 7 Nov 2004 21:37:58 -0000 1.2.2.1 +++ gnu/usr.bin/gdb/kgdb/main.c 30 Jan 2005 04:13:08 -0000 @@ -56,6 +56,8 @@ #include #include #include +#include +#include extern void (*init_ui_hook)(char *); @@ -166,18 +168,50 @@ } static void +kgdb_init_target(void) +{ + bfd *kern_bfd; + int kern_desc; + + kern_desc = open(kernel, O_RDONLY); + if (kern_desc == -1) + errx(1, "couldn't open a kernel image"); + + kern_bfd = bfd_fdopenr(kernel, gnutarget, kern_desc); + if (kern_bfd == NULL) { + close(kern_desc); + errx(1, "\"%s\": can't open to probe ABI: %s.", kernel, + bfd_errmsg (bfd_get_error ())); + } + bfd_set_cacheable(kern_bfd, 1); + + if (!bfd_check_format (kern_bfd, bfd_object)) { + bfd_close(kern_bfd); + errx(1, "\"%s\": not in executable format: %s", kernel, + bfd_errmsg(bfd_get_error())); + } + + set_gdbarch_from_file (kern_bfd); + bfd_close(kern_bfd); + + symbol_file_add_main (kernel, 0); + if (remote) + push_remote_target (remote, 0); + else + kgdb_target(); +} + +static void kgdb_interp_command_loop(void *data) { static int once = 0; if (!once) { once = 1; - symbol_file_add_main (kernel, 0); - if (remote) - push_remote_target (remote, 0); - else + kgdb_init_target(); kgdb_target(); - print_stack_frame(get_current_frame(), -1, 0); + print_stack_frame (get_selected_frame (), + frame_relative_level (get_selected_frame ()), 1); } command_loop(); } Index: gnu/usr.bin/gdb/kgdb/trgt.c =================================================================== RCS file: /home/ncvs/src/gnu/usr.bin/gdb/kgdb/trgt.c,v retrieving revision 1.1 diff -u -r1.1 trgt.c --- gnu/usr.bin/gdb/kgdb/trgt.c 25 Jul 2004 05:29:15 -0000 1.1 +++ gnu/usr.bin/gdb/kgdb/trgt.c 30 Jan 2005 04:11:14 -0000 @@ -27,22 +27,48 @@ #include __FBSDID("$FreeBSD: src/gnu/usr.bin/gdb/kgdb/trgt.c,v 1.1 2004/07/25 05:29:15 marcel Exp $"); -#include +#include +#include +#include +#include #include -#include "kgdb.h" - #include +#include #include #include +#include #include +#include "kgdb.h" + static struct target_ops kgdb_trgt_ops; +#define KERNOFF (kgdb_kernbase ()) +#define INKERNEL(x) ((x) >= KERNOFF) + +static CORE_ADDR +kgdb_kernbase (void) +{ + static CORE_ADDR kernbase; + struct minimal_symbol *sym; + + if (kernbase == 0) + { + sym = lookup_minimal_symbol ("kernbase", NULL, NULL); + if (sym == NULL) { + kernbase = KERNBASE; + } else { + kernbase = SYMBOL_VALUE_ADDRESS (sym); + } + } + return kernbase; +} + static char * -kgdb_trgt_extra_thread_info(struct thread_info *ti __unused) +kgdb_trgt_extra_thread_info(struct thread_info *ti) { - return (NULL); + return (kgdb_thr_extra_thread_info(ptid_get_tid(ti->ptid))); } static void @@ -53,16 +79,17 @@ static char * kgdb_trgt_pid_to_str(ptid_t ptid) { - static char buf[16]; + static char buf[33]; - snprintf(buf, sizeof(buf), "TID %d", ptid_get_pid(ptid)); + snprintf(buf, sizeof(buf), "PID %5d TID %5ld", ptid_get_pid(ptid), + ptid_get_tid(ptid)); return (buf); } static int kgdb_trgt_thread_alive(ptid_t ptid) { - return (kgdb_thr_lookup(ptid_get_pid(ptid)) != NULL); + return (kgdb_thr_lookup_tid(ptid_get_tid(ptid)) != NULL); } static int @@ -78,6 +105,71 @@ return (kvm_write(kvm, memaddr, myaddr, len)); } +static void +kgdb_switch_to_thread(struct kthr *thr) +{ + if (thr->tid == ptid_get_tid(inferior_ptid)) + return; + + inferior_ptid = ptid_build(thr->pid, 0, thr->tid); + flush_cached_frames (); + registers_changed (); + stop_pc = read_pc (); + select_frame (get_current_frame ()); +} + +static void +kgdb_set_proc_cmd (char *arg, int from_tty) +{ + CORE_ADDR addr; + struct kthr *thr; + + if (!arg) + error_no_arg ("proc address for the new context"); + + if (kvm == NULL) + error ("no kernel core file"); + + addr = (CORE_ADDR) parse_and_eval_address (arg); + + if (!INKERNEL (addr)) { + thr = kgdb_thr_lookup_pid((int)addr); + if (thr == NULL) + error ("invalid pid"); + } else { + thr = kgdb_thr_lookup_paddr(addr); + if (thr == NULL) + error("invalid proc address"); + } + kgdb_switch_to_thread(thr); +} + +static void +kgdb_set_tid_cmd (char *arg, int from_tty) +{ + CORE_ADDR addr; + struct kthr *thr; + + if (!arg) + error_no_arg ("TID or thread address for the new context"); + + if (kvm == NULL) + error ("no kernel core file"); + + addr = (CORE_ADDR) parse_and_eval_address (arg); + + if (!INKERNEL (addr)) { + thr = kgdb_thr_lookup_tid((int)addr); + if (thr == NULL) + error ("invalid TID"); + } else { + thr = kgdb_thr_lookup_taddr(addr); + if (thr == NULL) + error("invalid thread address"); + } + kgdb_switch_to_thread(thr); +} + void kgdb_target(void) { @@ -105,8 +197,12 @@ kt = kgdb_thr_first(); while (kt != NULL) { - ti = add_thread(ptid_build(kt->tid, 0, 0)); + ti = add_thread(ptid_build(kt->pid, 0, kt->tid)); kt = kgdb_thr_next(kt); } - inferior_ptid = ptid_build(curkthr->tid, 0, 0); + inferior_ptid = ptid_build(curkthr->pid, 0, curkthr->tid); + add_com ("proc", class_obscure, kgdb_set_proc_cmd, + "Set current process context"); + add_com ("tid", class_obscure, kgdb_set_tid_cmd, + "Set current process context"); } Index: gnu/usr.bin/gdb/kgdb/trgt_alpha.c =================================================================== RCS file: /home/ncvs/src/gnu/usr.bin/gdb/kgdb/trgt_alpha.c,v retrieving revision 1.1 diff -u -r1.1 trgt_alpha.c --- gnu/usr.bin/gdb/kgdb/trgt_alpha.c 25 Jul 2004 05:29:15 -0000 1.1 +++ gnu/usr.bin/gdb/kgdb/trgt_alpha.c 30 Jan 2005 04:11:14 -0000 @@ -47,7 +47,7 @@ struct kthr *kt; struct pcb pcb; - kt = kgdb_thr_lookup(ptid_get_pid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { Index: gnu/usr.bin/gdb/kgdb/trgt_amd64.c =================================================================== RCS file: /home/ncvs/src/gnu/usr.bin/gdb/kgdb/trgt_amd64.c,v retrieving revision 1.1 diff -u -r1.1 trgt_amd64.c --- gnu/usr.bin/gdb/kgdb/trgt_amd64.c 25 Jul 2004 05:29:15 -0000 1.1 +++ gnu/usr.bin/gdb/kgdb/trgt_amd64.c 30 Jan 2005 04:11:15 -0000 @@ -47,7 +47,7 @@ struct kthr *kt; struct pcb pcb; - kt = kgdb_thr_lookup(ptid_get_pid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { Index: gnu/usr.bin/gdb/kgdb/trgt_i386.c =================================================================== RCS file: /home/ncvs/src/gnu/usr.bin/gdb/kgdb/trgt_i386.c,v retrieving revision 1.1 diff -u -r1.1 trgt_i386.c --- gnu/usr.bin/gdb/kgdb/trgt_i386.c 25 Jul 2004 05:29:15 -0000 1.1 +++ gnu/usr.bin/gdb/kgdb/trgt_i386.c 30 Jan 2005 04:11:15 -0000 @@ -47,7 +47,7 @@ struct kthr *kt; struct pcb pcb; - kt = kgdb_thr_lookup(ptid_get_pid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { Index: gnu/usr.bin/gdb/kgdb/trgt_ia64.c =================================================================== RCS file: /home/ncvs/src/gnu/usr.bin/gdb/kgdb/trgt_ia64.c,v retrieving revision 1.1 diff -u -r1.1 trgt_ia64.c --- gnu/usr.bin/gdb/kgdb/trgt_ia64.c 25 Jul 2004 05:29:15 -0000 1.1 +++ gnu/usr.bin/gdb/kgdb/trgt_ia64.c 30 Jan 2005 04:11:16 -0000 @@ -49,7 +49,7 @@ struct pcb pcb; uint64_t r; - kt = kgdb_thr_lookup(ptid_get_pid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { Index: gnu/usr.bin/gdb/kgdb/trgt_sparc64.c =================================================================== RCS file: /home/ncvs/src/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c,v retrieving revision 1.1 diff -u -r1.1 trgt_sparc64.c --- gnu/usr.bin/gdb/kgdb/trgt_sparc64.c 25 Jul 2004 05:29:15 -0000 1.1 +++ gnu/usr.bin/gdb/kgdb/trgt_sparc64.c 30 Jan 2005 04:11:16 -0000 @@ -49,7 +49,7 @@ struct pcb pcb; uint64_t r; - kt = kgdb_thr_lookup(ptid_get_pid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) {