kthr.c revision 173681
1132624Smarcel/* 2132624Smarcel * Copyright (c) 2004 Marcel Moolenaar 3132624Smarcel * All rights reserved. 4132624Smarcel * 5132624Smarcel * Redistribution and use in source and binary forms, with or without 6132624Smarcel * modification, are permitted provided that the following conditions 7132624Smarcel * are met: 8132624Smarcel * 9132624Smarcel * 1. Redistributions of source code must retain the above copyright 10132624Smarcel * notice, this list of conditions and the following disclaimer. 11132624Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12132624Smarcel * notice, this list of conditions and the following disclaimer in the 13132624Smarcel * documentation and/or other materials provided with the distribution. 14132624Smarcel * 15132624Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16132624Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17132624Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18132624Smarcel * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 19132624Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20132624Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21132624Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22132624Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23132624Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24132624Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25132624Smarcel */ 26132624Smarcel 27132624Smarcel#include <sys/cdefs.h> 28132624Smarcel__FBSDID("$FreeBSD: head/gnu/usr.bin/gdb/kgdb/kthr.c 173681 2007-11-16 22:17:37Z jhb $"); 29132624Smarcel 30132624Smarcel#include <sys/param.h> 31132624Smarcel#include <sys/proc.h> 32132624Smarcel#include <sys/types.h> 33132624Smarcel#include <sys/signal.h> 34132624Smarcel#include <err.h> 35132624Smarcel#include <inttypes.h> 36132624Smarcel#include <kvm.h> 37132624Smarcel#include <stdio.h> 38132624Smarcel#include <stdlib.h> 39132624Smarcel 40142151Skan#include <defs.h> 41149954Smarcel#include <frame-unwind.h> 42142151Skan 43132624Smarcel#include "kgdb.h" 44161621Sjhb#include <machine/pcb.h> 45132624Smarcel 46132624Smarcelstatic uintptr_t dumppcb; 47132624Smarcelstatic int dumptid; 48132624Smarcel 49161621Sjhbstatic uintptr_t stoppcbs; 50161621Sjhbstatic __cpumask_t stopped_cpus; 51161621Sjhb 52132624Smarcelstatic struct kthr *first; 53132624Smarcelstruct kthr *curkthr; 54132624Smarcel 55167142Skibuintptr_t 56167142Skibkgdb_lookup(const char *sym) 57132624Smarcel{ 58132624Smarcel struct nlist nl[2]; 59132624Smarcel 60132624Smarcel nl[0].n_name = (char *)(uintptr_t)sym; 61132624Smarcel nl[1].n_name = NULL; 62132624Smarcel if (kvm_nlist(kvm, nl) != 0) { 63132624Smarcel warnx("kvm_nlist(%s): %s", sym, kvm_geterr(kvm)); 64132624Smarcel return (0); 65132624Smarcel } 66132624Smarcel return (nl[0].n_value); 67132624Smarcel} 68132624Smarcel 69132624Smarcelstruct kthr * 70132624Smarcelkgdb_thr_first(void) 71132624Smarcel{ 72132624Smarcel return (first); 73132624Smarcel} 74132624Smarcel 75132624Smarcelstruct kthr * 76132624Smarcelkgdb_thr_init(void) 77132624Smarcel{ 78132624Smarcel struct proc p; 79132624Smarcel struct thread td; 80132624Smarcel struct kthr *kt; 81132624Smarcel uintptr_t addr, paddr; 82132624Smarcel 83167142Skib addr = kgdb_lookup("_allproc"); 84132624Smarcel if (addr == 0) 85132624Smarcel return (NULL); 86132624Smarcel kvm_read(kvm, addr, &paddr, sizeof(paddr)); 87132624Smarcel 88167142Skib dumppcb = kgdb_lookup("_dumppcb"); 89132624Smarcel if (dumppcb == 0) 90132624Smarcel return (NULL); 91132624Smarcel 92167142Skib addr = kgdb_lookup("_dumptid"); 93132624Smarcel if (addr != 0) 94132624Smarcel kvm_read(kvm, addr, &dumptid, sizeof(dumptid)); 95132624Smarcel else 96132624Smarcel dumptid = -1; 97132624Smarcel 98167142Skib addr = kgdb_lookup("_stopped_cpus"); 99161621Sjhb if (addr != 0) 100161621Sjhb kvm_read(kvm, addr, &stopped_cpus, sizeof(stopped_cpus)); 101161621Sjhb else 102161621Sjhb stopped_cpus = 0; 103161621Sjhb 104167142Skib stoppcbs = kgdb_lookup("_stoppcbs"); 105163440Sjhb 106132624Smarcel while (paddr != 0) { 107166214Srodrigc if (kvm_read(kvm, paddr, &p, sizeof(p)) != sizeof(p)) { 108132624Smarcel warnx("kvm_read: %s", kvm_geterr(kvm)); 109166214Srodrigc break; 110166214Srodrigc } 111132624Smarcel addr = (uintptr_t)TAILQ_FIRST(&p.p_threads); 112132624Smarcel while (addr != 0) { 113166214Srodrigc if (kvm_read(kvm, addr, &td, sizeof(td)) != 114166214Srodrigc sizeof(td)) { 115132624Smarcel warnx("kvm_read: %s", kvm_geterr(kvm)); 116166214Srodrigc break; 117166214Srodrigc } 118132624Smarcel kt = malloc(sizeof(*kt)); 119132624Smarcel kt->next = first; 120132624Smarcel kt->kaddr = addr; 121161621Sjhb if (td.td_tid == dumptid) 122161621Sjhb kt->pcb = dumppcb; 123161621Sjhb else if (td.td_state == TDS_RUNNING && ((1 << td.td_oncpu) & stopped_cpus) 124161621Sjhb && stoppcbs != 0) 125161621Sjhb kt->pcb = (uintptr_t) stoppcbs + sizeof(struct pcb) * td.td_oncpu; 126163440Sjhb else 127161621Sjhb kt->pcb = (uintptr_t)td.td_pcb; 128132624Smarcel kt->kstack = td.td_kstack; 129132624Smarcel kt->tid = td.td_tid; 130142151Skan kt->pid = p.p_pid; 131142151Skan kt->paddr = paddr; 132173681Sjhb kt->cpu = td.td_oncpu; 133132624Smarcel first = kt; 134132624Smarcel addr = (uintptr_t)TAILQ_NEXT(&td, td_plist); 135132624Smarcel } 136132624Smarcel paddr = (uintptr_t)LIST_NEXT(&p, p_list); 137132624Smarcel } 138142151Skan curkthr = kgdb_thr_lookup_tid(dumptid); 139132624Smarcel if (curkthr == NULL) 140132624Smarcel curkthr = first; 141132624Smarcel return (first); 142132624Smarcel} 143132624Smarcel 144132624Smarcelstruct kthr * 145142151Skankgdb_thr_lookup_tid(int tid) 146132624Smarcel{ 147132624Smarcel struct kthr *kt; 148132624Smarcel 149132624Smarcel kt = first; 150132624Smarcel while (kt != NULL && kt->tid != tid) 151132624Smarcel kt = kt->next; 152132624Smarcel return (kt); 153132624Smarcel} 154132624Smarcel 155132624Smarcelstruct kthr * 156142151Skankgdb_thr_lookup_taddr(uintptr_t taddr) 157142151Skan{ 158142151Skan struct kthr *kt; 159142151Skan 160142151Skan kt = first; 161142151Skan while (kt != NULL && kt->kaddr != taddr) 162142151Skan kt = kt->next; 163142151Skan return (kt); 164142151Skan} 165142151Skan 166142151Skanstruct kthr * 167142151Skankgdb_thr_lookup_pid(int pid) 168142151Skan{ 169142151Skan struct kthr *kt; 170142151Skan 171142151Skan kt = first; 172142151Skan while (kt != NULL && kt->pid != pid) 173142151Skan kt = kt->next; 174142151Skan return (kt); 175142151Skan} 176142151Skan 177142151Skanstruct kthr * 178142151Skankgdb_thr_lookup_paddr(uintptr_t paddr) 179142151Skan{ 180142151Skan struct kthr *kt; 181142151Skan 182142151Skan kt = first; 183142151Skan while (kt != NULL && kt->paddr != paddr) 184142151Skan kt = kt->next; 185142151Skan return (kt); 186142151Skan} 187142151Skan 188142151Skanstruct kthr * 189132624Smarcelkgdb_thr_next(struct kthr *kt) 190132624Smarcel{ 191132624Smarcel return (kt->next); 192132624Smarcel} 193132624Smarcel 194132624Smarcelstruct kthr * 195132624Smarcelkgdb_thr_select(struct kthr *kt) 196132624Smarcel{ 197132624Smarcel struct kthr *pcur; 198132624Smarcel 199132624Smarcel pcur = curkthr; 200132624Smarcel curkthr = kt; 201132624Smarcel return (pcur); 202132624Smarcel} 203142151Skan 204142151Skanchar * 205142151Skankgdb_thr_extra_thread_info(int tid) 206142151Skan{ 207142151Skan struct kthr *kt; 208142151Skan struct proc *p; 209142151Skan static char comm[MAXCOMLEN + 1]; 210142151Skan 211142151Skan kt = kgdb_thr_lookup_tid(tid); 212142151Skan if (kt == NULL) 213142151Skan return (NULL); 214142151Skan p = (struct proc *)kt->paddr; 215142151Skan if (kvm_read(kvm, (uintptr_t)&p->p_comm[0], &comm, sizeof(comm)) != 216142151Skan sizeof(comm)) 217142151Skan return (NULL); 218142151Skan 219142151Skan return (comm); 220142151Skan} 221