kthr.c revision 142151
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 142151 2005-02-20 22:55:07Z kan $"); 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> 41142151Skan 42132624Smarcel#include "kgdb.h" 43132624Smarcel 44132624Smarcelstatic uintptr_t dumppcb; 45132624Smarcelstatic int dumptid; 46132624Smarcel 47132624Smarcelstatic struct kthr *first; 48132624Smarcelstruct kthr *curkthr; 49132624Smarcel 50132624Smarcelstatic uintptr_t 51132624Smarcellookup(const char *sym) 52132624Smarcel{ 53132624Smarcel struct nlist nl[2]; 54132624Smarcel 55132624Smarcel nl[0].n_name = (char *)(uintptr_t)sym; 56132624Smarcel nl[1].n_name = NULL; 57132624Smarcel if (kvm_nlist(kvm, nl) != 0) { 58132624Smarcel warnx("kvm_nlist(%s): %s", sym, kvm_geterr(kvm)); 59132624Smarcel return (0); 60132624Smarcel } 61132624Smarcel return (nl[0].n_value); 62132624Smarcel} 63132624Smarcel 64132624Smarcelstruct kthr * 65132624Smarcelkgdb_thr_first(void) 66132624Smarcel{ 67132624Smarcel return (first); 68132624Smarcel} 69132624Smarcel 70132624Smarcelstruct kthr * 71132624Smarcelkgdb_thr_init(void) 72132624Smarcel{ 73132624Smarcel struct proc p; 74132624Smarcel struct thread td; 75132624Smarcel struct kthr *kt; 76132624Smarcel uintptr_t addr, paddr; 77132624Smarcel 78132624Smarcel addr = lookup("_allproc"); 79132624Smarcel if (addr == 0) 80132624Smarcel return (NULL); 81132624Smarcel kvm_read(kvm, addr, &paddr, sizeof(paddr)); 82132624Smarcel 83132624Smarcel dumppcb = lookup("_dumppcb"); 84132624Smarcel if (dumppcb == 0) 85132624Smarcel return (NULL); 86132624Smarcel 87132624Smarcel addr = lookup("_dumptid"); 88132624Smarcel if (addr != 0) 89132624Smarcel kvm_read(kvm, addr, &dumptid, sizeof(dumptid)); 90132624Smarcel else 91132624Smarcel dumptid = -1; 92132624Smarcel 93132624Smarcel while (paddr != 0) { 94132624Smarcel if (kvm_read(kvm, paddr, &p, sizeof(p)) != sizeof(p)) 95132624Smarcel warnx("kvm_read: %s", kvm_geterr(kvm)); 96132624Smarcel addr = (uintptr_t)TAILQ_FIRST(&p.p_threads); 97132624Smarcel while (addr != 0) { 98132624Smarcel if (kvm_read(kvm, addr, &td, sizeof(td)) != sizeof(td)) 99132624Smarcel warnx("kvm_read: %s", kvm_geterr(kvm)); 100132624Smarcel kt = malloc(sizeof(*kt)); 101132624Smarcel kt->next = first; 102132624Smarcel kt->kaddr = addr; 103132624Smarcel kt->pcb = (td.td_tid == dumptid) ? dumppcb : 104132624Smarcel (uintptr_t)td.td_pcb; 105132624Smarcel kt->kstack = td.td_kstack; 106132624Smarcel kt->tid = td.td_tid; 107142151Skan kt->pid = p.p_pid; 108142151Skan kt->paddr = paddr; 109132624Smarcel first = kt; 110132624Smarcel addr = (uintptr_t)TAILQ_NEXT(&td, td_plist); 111132624Smarcel } 112132624Smarcel paddr = (uintptr_t)LIST_NEXT(&p, p_list); 113132624Smarcel } 114142151Skan curkthr = kgdb_thr_lookup_tid(dumptid); 115132624Smarcel if (curkthr == NULL) 116132624Smarcel curkthr = first; 117132624Smarcel return (first); 118132624Smarcel} 119132624Smarcel 120132624Smarcelstruct kthr * 121142151Skankgdb_thr_lookup_tid(int tid) 122132624Smarcel{ 123132624Smarcel struct kthr *kt; 124132624Smarcel 125132624Smarcel kt = first; 126132624Smarcel while (kt != NULL && kt->tid != tid) 127132624Smarcel kt = kt->next; 128132624Smarcel return (kt); 129132624Smarcel} 130132624Smarcel 131132624Smarcelstruct kthr * 132142151Skankgdb_thr_lookup_taddr(uintptr_t taddr) 133142151Skan{ 134142151Skan struct kthr *kt; 135142151Skan 136142151Skan kt = first; 137142151Skan while (kt != NULL && kt->kaddr != taddr) 138142151Skan kt = kt->next; 139142151Skan return (kt); 140142151Skan} 141142151Skan 142142151Skanstruct kthr * 143142151Skankgdb_thr_lookup_pid(int pid) 144142151Skan{ 145142151Skan struct kthr *kt; 146142151Skan 147142151Skan kt = first; 148142151Skan while (kt != NULL && kt->pid != pid) 149142151Skan kt = kt->next; 150142151Skan return (kt); 151142151Skan} 152142151Skan 153142151Skanstruct kthr * 154142151Skankgdb_thr_lookup_paddr(uintptr_t paddr) 155142151Skan{ 156142151Skan struct kthr *kt; 157142151Skan 158142151Skan kt = first; 159142151Skan while (kt != NULL && kt->paddr != paddr) 160142151Skan kt = kt->next; 161142151Skan return (kt); 162142151Skan} 163142151Skan 164142151Skanstruct kthr * 165132624Smarcelkgdb_thr_next(struct kthr *kt) 166132624Smarcel{ 167132624Smarcel return (kt->next); 168132624Smarcel} 169132624Smarcel 170132624Smarcelstruct kthr * 171132624Smarcelkgdb_thr_select(struct kthr *kt) 172132624Smarcel{ 173132624Smarcel struct kthr *pcur; 174132624Smarcel 175132624Smarcel pcur = curkthr; 176132624Smarcel curkthr = kt; 177132624Smarcel return (pcur); 178132624Smarcel} 179142151Skan 180142151Skanchar * 181142151Skankgdb_thr_extra_thread_info(int tid) 182142151Skan{ 183142151Skan struct kthr *kt; 184142151Skan struct proc *p; 185142151Skan static char comm[MAXCOMLEN + 1]; 186142151Skan 187142151Skan kt = kgdb_thr_lookup_tid(tid); 188142151Skan if (kt == NULL) 189142151Skan return (NULL); 190142151Skan p = (struct proc *)kt->paddr; 191142151Skan if (kvm_read(kvm, (uintptr_t)&p->p_comm[0], &comm, sizeof(comm)) != 192142151Skan sizeof(comm)) 193142151Skan return (NULL); 194142151Skan 195142151Skan return (comm); 196142151Skan} 197