kthr.c revision 178713
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 178713 2008-05-01 20:36:48Z 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> 39175452Semaste#include <string.h> 40132624Smarcel 41142151Skan#include <defs.h> 42149954Smarcel#include <frame-unwind.h> 43142151Skan 44132624Smarcel#include "kgdb.h" 45161621Sjhb#include <machine/pcb.h> 46132624Smarcel 47132624Smarcelstatic uintptr_t dumppcb; 48132624Smarcelstatic int dumptid; 49132624Smarcel 50161621Sjhbstatic uintptr_t stoppcbs; 51161621Sjhbstatic __cpumask_t stopped_cpus; 52161621Sjhb 53132624Smarcelstatic struct kthr *first; 54132624Smarcelstruct kthr *curkthr; 55132624Smarcel 56167142Skibuintptr_t 57167142Skibkgdb_lookup(const char *sym) 58132624Smarcel{ 59132624Smarcel struct nlist nl[2]; 60132624Smarcel 61132624Smarcel nl[0].n_name = (char *)(uintptr_t)sym; 62132624Smarcel nl[1].n_name = NULL; 63175771Sjhb if (kvm_nlist(kvm, nl) != 0) 64132624Smarcel return (0); 65132624Smarcel return (nl[0].n_value); 66132624Smarcel} 67132624Smarcel 68132624Smarcelstruct kthr * 69132624Smarcelkgdb_thr_first(void) 70132624Smarcel{ 71132624Smarcel return (first); 72132624Smarcel} 73132624Smarcel 74132624Smarcelstruct kthr * 75132624Smarcelkgdb_thr_init(void) 76132624Smarcel{ 77132624Smarcel struct proc p; 78132624Smarcel struct thread td; 79132624Smarcel struct kthr *kt; 80132624Smarcel uintptr_t addr, paddr; 81178670Sjhb 82178670Sjhb while (first != NULL) { 83178670Sjhb kt = first; 84178670Sjhb first = kt->next; 85178670Sjhb free(kt); 86178670Sjhb } 87132624Smarcel 88167142Skib addr = kgdb_lookup("_allproc"); 89175771Sjhb if (addr == 0) { 90175771Sjhb warnx("kvm_nlist(_allproc): %s", kvm_geterr(kvm)); 91132624Smarcel return (NULL); 92175771Sjhb } 93132624Smarcel kvm_read(kvm, addr, &paddr, sizeof(paddr)); 94132624Smarcel 95167142Skib dumppcb = kgdb_lookup("_dumppcb"); 96175771Sjhb if (dumppcb == 0) { 97175771Sjhb warnx("kvm_nlist(_dumppcb): %s", kvm_geterr(kvm)); 98132624Smarcel return (NULL); 99175771Sjhb } 100132624Smarcel 101167142Skib addr = kgdb_lookup("_dumptid"); 102132624Smarcel if (addr != 0) 103132624Smarcel kvm_read(kvm, addr, &dumptid, sizeof(dumptid)); 104132624Smarcel else 105132624Smarcel dumptid = -1; 106132624Smarcel 107167142Skib addr = kgdb_lookup("_stopped_cpus"); 108161621Sjhb if (addr != 0) 109161621Sjhb kvm_read(kvm, addr, &stopped_cpus, sizeof(stopped_cpus)); 110161621Sjhb else 111161621Sjhb stopped_cpus = 0; 112161621Sjhb 113167142Skib stoppcbs = kgdb_lookup("_stoppcbs"); 114163440Sjhb 115132624Smarcel while (paddr != 0) { 116166214Srodrigc if (kvm_read(kvm, paddr, &p, sizeof(p)) != sizeof(p)) { 117132624Smarcel warnx("kvm_read: %s", kvm_geterr(kvm)); 118166214Srodrigc break; 119166214Srodrigc } 120132624Smarcel addr = (uintptr_t)TAILQ_FIRST(&p.p_threads); 121132624Smarcel while (addr != 0) { 122166214Srodrigc if (kvm_read(kvm, addr, &td, sizeof(td)) != 123166214Srodrigc sizeof(td)) { 124132624Smarcel warnx("kvm_read: %s", kvm_geterr(kvm)); 125166214Srodrigc break; 126166214Srodrigc } 127132624Smarcel kt = malloc(sizeof(*kt)); 128132624Smarcel kt->next = first; 129132624Smarcel kt->kaddr = addr; 130161621Sjhb if (td.td_tid == dumptid) 131161621Sjhb kt->pcb = dumppcb; 132161621Sjhb else if (td.td_state == TDS_RUNNING && ((1 << td.td_oncpu) & stopped_cpus) 133161621Sjhb && stoppcbs != 0) 134161621Sjhb kt->pcb = (uintptr_t) stoppcbs + sizeof(struct pcb) * td.td_oncpu; 135163440Sjhb else 136161621Sjhb kt->pcb = (uintptr_t)td.td_pcb; 137132624Smarcel kt->kstack = td.td_kstack; 138132624Smarcel kt->tid = td.td_tid; 139142151Skan kt->pid = p.p_pid; 140142151Skan kt->paddr = paddr; 141173681Sjhb kt->cpu = td.td_oncpu; 142132624Smarcel first = kt; 143132624Smarcel addr = (uintptr_t)TAILQ_NEXT(&td, td_plist); 144132624Smarcel } 145132624Smarcel paddr = (uintptr_t)LIST_NEXT(&p, p_list); 146132624Smarcel } 147142151Skan curkthr = kgdb_thr_lookup_tid(dumptid); 148132624Smarcel if (curkthr == NULL) 149132624Smarcel curkthr = first; 150132624Smarcel return (first); 151132624Smarcel} 152132624Smarcel 153132624Smarcelstruct kthr * 154142151Skankgdb_thr_lookup_tid(int tid) 155132624Smarcel{ 156132624Smarcel struct kthr *kt; 157132624Smarcel 158132624Smarcel kt = first; 159132624Smarcel while (kt != NULL && kt->tid != tid) 160132624Smarcel kt = kt->next; 161132624Smarcel return (kt); 162132624Smarcel} 163132624Smarcel 164132624Smarcelstruct kthr * 165142151Skankgdb_thr_lookup_taddr(uintptr_t taddr) 166142151Skan{ 167142151Skan struct kthr *kt; 168142151Skan 169142151Skan kt = first; 170142151Skan while (kt != NULL && kt->kaddr != taddr) 171142151Skan kt = kt->next; 172142151Skan return (kt); 173142151Skan} 174142151Skan 175142151Skanstruct kthr * 176142151Skankgdb_thr_lookup_pid(int pid) 177142151Skan{ 178142151Skan struct kthr *kt; 179142151Skan 180142151Skan kt = first; 181142151Skan while (kt != NULL && kt->pid != pid) 182142151Skan kt = kt->next; 183142151Skan return (kt); 184142151Skan} 185142151Skan 186142151Skanstruct kthr * 187142151Skankgdb_thr_lookup_paddr(uintptr_t paddr) 188142151Skan{ 189142151Skan struct kthr *kt; 190142151Skan 191142151Skan kt = first; 192142151Skan while (kt != NULL && kt->paddr != paddr) 193142151Skan kt = kt->next; 194142151Skan return (kt); 195142151Skan} 196142151Skan 197142151Skanstruct kthr * 198132624Smarcelkgdb_thr_next(struct kthr *kt) 199132624Smarcel{ 200132624Smarcel return (kt->next); 201132624Smarcel} 202132624Smarcel 203132624Smarcelstruct kthr * 204132624Smarcelkgdb_thr_select(struct kthr *kt) 205132624Smarcel{ 206132624Smarcel struct kthr *pcur; 207132624Smarcel 208132624Smarcel pcur = curkthr; 209132624Smarcel curkthr = kt; 210132624Smarcel return (pcur); 211132624Smarcel} 212142151Skan 213142151Skanchar * 214142151Skankgdb_thr_extra_thread_info(int tid) 215142151Skan{ 216175452Semaste char comm[MAXCOMLEN + 1]; 217175452Semaste char td_name[MAXCOMLEN + 1]; 218142151Skan struct kthr *kt; 219142151Skan struct proc *p; 220175452Semaste struct thread *t; 221178713Sjhb static char buf[64]; 222142151Skan 223142151Skan kt = kgdb_thr_lookup_tid(tid); 224142151Skan if (kt == NULL) 225178713Sjhb return (NULL); 226178713Sjhb snprintf(buf, sizeof(buf), "PID=%d", kt->pid); 227142151Skan p = (struct proc *)kt->paddr; 228142151Skan if (kvm_read(kvm, (uintptr_t)&p->p_comm[0], &comm, sizeof(comm)) != 229142151Skan sizeof(comm)) 230178713Sjhb return (buf); 231178713Sjhb strlcat(buf, ": ", sizeof(buf)); 232178713Sjhb strlcat(buf, comm, sizeof(buf)); 233178713Sjhb t = (struct thread *)kt->kaddr; 234175452Semaste if (kvm_read(kvm, (uintptr_t)&t->td_name[0], &td_name, 235175452Semaste sizeof(td_name)) == sizeof(td_name) && 236178713Sjhb strcmp(comm, td_name) != 0) { 237178713Sjhb strlcat(buf, "/", sizeof(buf)); 238178713Sjhb strlcat(buf, td_name, sizeof(buf)); 239178713Sjhb } 240178713Sjhb return (buf); 241142151Skan} 242