aboutsummaryrefslogtreecommitdiff
path: root/gnu/usr.bin
diff options
context:
space:
mode:
authorAlexander Kabaev <kan@FreeBSD.org>2005-02-20 22:55:07 +0000
committerAlexander Kabaev <kan@FreeBSD.org>2005-02-20 22:55:07 +0000
commit325ce5d8fb22cea8ad841246ab4013efdb8413c5 (patch)
tree84cd848fd72dc0dd4c8a495c04c1925cdc3accf5 /gnu/usr.bin
parentc4691a5da9adfb1862d8327136c09f015afec180 (diff)
downloadsrc-325ce5d8fb22cea8ad841246ab4013efdb8413c5.tar.gz
src-325ce5d8fb22cea8ad841246ab4013efdb8413c5.zip
Attempt to make kgdb little more useful and easy to use. Properly initialize
it to recognise what ABI to use on amd64 (and possibly others) platform. Display PID and process name as a part of the 'info threads' output, TIDs alone are too confusing. Introduce new commmands 'tid <tid>' and 'proc <pid>' to accompany gdb's default 'thread <thread num>' to make the task of switching between different contexts easier.
Notes
Notes: svn path=/head/; revision=142151
Diffstat (limited to 'gnu/usr.bin')
-rw-r--r--gnu/usr.bin/gdb/kgdb/Makefile2
-rw-r--r--gnu/usr.bin/gdb/kgdb/kgdb.h10
-rw-r--r--gnu/usr.bin/gdb/kgdb/kthr.c59
-rw-r--r--gnu/usr.bin/gdb/kgdb/main.c46
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt.c116
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_alpha.c2
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_amd64.c2
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_i386.c2
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_ia64.c2
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_sparc64.c2
10 files changed, 218 insertions, 25 deletions
diff --git a/gnu/usr.bin/gdb/kgdb/Makefile b/gnu/usr.bin/gdb/kgdb/Makefile
index 404b960f0f08..d688bb69e750 100644
--- a/gnu/usr.bin/gdb/kgdb/Makefile
+++ b/gnu/usr.bin/gdb/kgdb/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
PROG= kgdb${GDB_SUFFIX}
-SRCS= kthr.c main.c trgt.c trgt_${TARGET_ARCH}.c
+SRCS= main.c kthr.c trgt.c trgt_${MACHINE_ARCH}.c
WARNS?= 2
BULIBS= ${OBJ_BU}/libbfd/libbfd.a ${OBJ_BU}/libopcodes/libopcodes.a \
diff --git a/gnu/usr.bin/gdb/kgdb/kgdb.h b/gnu/usr.bin/gdb/kgdb/kgdb.h
index eb380326b6ae..b545ebbe03c4 100644
--- a/gnu/usr.bin/gdb/kgdb/kgdb.h
+++ b/gnu/usr.bin/gdb/kgdb/kgdb.h
@@ -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 @@ void kgdb_trgt_store_registers(int);
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_ */
diff --git a/gnu/usr.bin/gdb/kgdb/kthr.c b/gnu/usr.bin/gdb/kgdb/kthr.c
index 25f8d4919336..505605d406a3 100644
--- a/gnu/usr.bin/gdb/kgdb/kthr.c
+++ b/gnu/usr.bin/gdb/kgdb/kthr.c
@@ -37,6 +37,8 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
+#include <defs.h>
+
#include "kgdb.h"
static uintptr_t dumppcb;
@@ -102,19 +104,21 @@ kgdb_thr_init(void)
(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 @@ kgdb_thr_lookup(int tid)
}
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 @@ kgdb_thr_select(struct kthr *kt)
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);
+}
diff --git a/gnu/usr.bin/gdb/kgdb/main.c b/gnu/usr.bin/gdb/kgdb/main.c
index 54f6a3ee5c62..3ad158b731c0 100644
--- a/gnu/usr.bin/gdb/kgdb/main.c
+++ b/gnu/usr.bin/gdb/kgdb/main.c
@@ -56,6 +56,8 @@ __FBSDID("$FreeBSD$");
#include <main.h>
#include <target.h>
#include <top.h>
+#include <bfd.h>
+#include <gdbcore.h>
extern void (*init_ui_hook)(char *);
@@ -166,18 +168,50 @@ out:
}
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_target();
- print_stack_frame(get_current_frame(), -1, 0);
+ kgdb_init_target();
+ kgdb_target();
+ print_stack_frame (get_selected_frame (),
+ frame_relative_level (get_selected_frame ()), 1);
}
command_loop();
}
diff --git a/gnu/usr.bin/gdb/kgdb/trgt.c b/gnu/usr.bin/gdb/kgdb/trgt.c
index 5c889eb3f34d..93cac1181cdb 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt.c
@@ -27,22 +27,48 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
#include <kvm.h>
-#include "kgdb.h"
-
#include <defs.h>
+#include <command.h>
#include <gdbthread.h>
#include <inferior.h>
+#include <regcache.h>
#include <target.h>
+#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 @@ kgdb_trgt_find_new_threads(void)
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 @@ kgdb_trgt_xfer_memory(CORE_ADDR memaddr, char *myaddr, int len, int write,
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 @@ kgdb_target(void)
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");
}
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_alpha.c b/gnu/usr.bin/gdb/kgdb/trgt_alpha.c
index 891b0eb63e62..336970ba2be6 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_alpha.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_alpha.c
@@ -47,7 +47,7 @@ kgdb_trgt_fetch_registers(int regno __unused)
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)) {
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c
index e193969ca5ca..0907d0db5675 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c
@@ -47,7 +47,7 @@ kgdb_trgt_fetch_registers(int regno __unused)
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)) {
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_i386.c b/gnu/usr.bin/gdb/kgdb/trgt_i386.c
index 36c1ed067546..96dad51fcffe 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_i386.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_i386.c
@@ -47,7 +47,7 @@ kgdb_trgt_fetch_registers(int regno __unused)
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)) {
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_ia64.c b/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
index 15609afe340e..bfceba4cd0aa 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
@@ -49,7 +49,7 @@ kgdb_trgt_fetch_registers(int regno __unused)
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)) {
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c b/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c
index 81f9a86940fe..8be716e8b44d 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c
@@ -49,7 +49,7 @@ kgdb_trgt_fetch_registers(int regno __unused)
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)) {