o Remove the obscure tid command, because it does what the thread

command does, but worse.
o  Remove the obscure proc command, because it does what the thread
   command does, but not unambigously.
o  Move the PID to the extra thread info, where it makes sense and
   where it doesn't confuse users. The extra thread info holds some
   process information, to which the PID belongs.
o  Implement the to_find_new_threads target method by having it call
   the target beneath us if we're not using KVM. This makes sure that
   new threads are found when using the remote target.

o  Fix various core dump scenarios:
   -  Implement the to_files_info target method. Previously the
      'info target' command would cause a NULL pointer dereference.
   -  Don't assume there's a current thread. We're not initialized
      in all cases. This prevents a NULL pointer dereference.
   -  When we're not ussing KVM, have the to_xfer_memory target
      method call the target beneath us. This avoids calling into
      KVM with a NULL pointer.

MFC after: 1 week
This commit is contained in:
Marcel Moolenaar 2005-08-06 19:22:27 +00:00
parent 9ca14a4113
commit 688deacdfa

View File

@ -44,36 +44,40 @@ __FBSDID("$FreeBSD$");
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)
{
return (kgdb_thr_extra_thread_info(ptid_get_tid(ti->ptid)));
static char buf[64];
char *p, *s;
p = buf + snprintf(buf, sizeof(buf), "PID=%d", ptid_get_pid(ti->ptid));
s = kgdb_thr_extra_thread_info(ptid_get_tid(ti->ptid));
if (s != NULL)
snprintf(p, sizeof(buf) - (p - buf), ": %s", s);
return (buf);
}
static void
kgdb_trgt_files_info(struct target_ops *target)
{
struct target_ops *tb;
tb = find_target_beneath(target);
if (tb->to_files_info != NULL)
tb->to_files_info(tb);
}
static void
kgdb_trgt_find_new_threads(void)
{
struct target_ops *tb;
if (kvm != NULL)
return;
tb = find_target_beneath(&kgdb_trgt_ops);
if (tb->to_find_new_threads != NULL)
tb->to_find_new_threads();
}
static char *
@ -81,8 +85,7 @@ kgdb_trgt_pid_to_str(ptid_t ptid)
{
static char buf[33];
snprintf(buf, sizeof(buf), "PID %5d TID %5ld", ptid_get_pid(ptid),
ptid_get_tid(ptid));
snprintf(buf, sizeof(buf), "Thread %ld", ptid_get_tid(ptid));
return (buf);
}
@ -94,80 +97,20 @@ kgdb_trgt_thread_alive(ptid_t ptid)
static int
kgdb_trgt_xfer_memory(CORE_ADDR memaddr, char *myaddr, int len, int write,
struct mem_attrib *attrib __unused, struct target_ops *target __unused)
struct mem_attrib *attrib, struct target_ops *target)
{
if (len == 0)
return (0);
struct target_ops *tb;
if (!write)
return (kvm_read(kvm, memaddr, myaddr, len));
else
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");
if (kvm != NULL) {
if (len == 0)
return (0);
if (!write)
return (kvm_read(kvm, memaddr, myaddr, len));
else
return (kvm_write(kvm, memaddr, myaddr, len));
}
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);
tb = find_target_beneath(target);
return (tb->to_xfer_memory(memaddr, myaddr, len, write, attrib, tb));
}
void
@ -187,6 +130,7 @@ kgdb_target(void)
kgdb_trgt_ops.to_extra_thread_info = kgdb_trgt_extra_thread_info;
kgdb_trgt_ops.to_fetch_registers = kgdb_trgt_fetch_registers;
kgdb_trgt_ops.to_files_info = kgdb_trgt_files_info;
kgdb_trgt_ops.to_find_new_threads = kgdb_trgt_find_new_threads;
kgdb_trgt_ops.to_pid_to_str = kgdb_trgt_pid_to_str;
kgdb_trgt_ops.to_store_registers = kgdb_trgt_store_registers;
@ -200,9 +144,6 @@ kgdb_target(void)
ti = add_thread(ptid_build(kt->pid, 0, kt->tid));
kt = kgdb_thr_next(kt);
}
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");
if (curkthr != 0)
inferior_ptid = ptid_build(curkthr->pid, 0, curkthr->tid);
}