kthr.c revision 132624
1/* 2 * Copyright (c) 2004 Marcel Moolenaar 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/gnu/usr.bin/gdb/kgdb/kthr.c 132624 2004-07-25 05:29:15Z marcel $"); 29 30#include <sys/param.h> 31#include <sys/proc.h> 32#include <sys/types.h> 33#include <sys/signal.h> 34#include <err.h> 35#include <inttypes.h> 36#include <kvm.h> 37#include <stdio.h> 38#include <stdlib.h> 39 40#include "kgdb.h" 41 42static uintptr_t dumppcb; 43static int dumptid; 44 45static struct kthr *first; 46struct kthr *curkthr; 47 48static uintptr_t 49lookup(const char *sym) 50{ 51 struct nlist nl[2]; 52 53 nl[0].n_name = (char *)(uintptr_t)sym; 54 nl[1].n_name = NULL; 55 if (kvm_nlist(kvm, nl) != 0) { 56 warnx("kvm_nlist(%s): %s", sym, kvm_geterr(kvm)); 57 return (0); 58 } 59 return (nl[0].n_value); 60} 61 62struct kthr * 63kgdb_thr_first(void) 64{ 65 return (first); 66} 67 68struct kthr * 69kgdb_thr_init(void) 70{ 71 struct proc p; 72 struct thread td; 73 struct kthr *kt; 74 uintptr_t addr, paddr; 75 76 addr = lookup("_allproc"); 77 if (addr == 0) 78 return (NULL); 79 kvm_read(kvm, addr, &paddr, sizeof(paddr)); 80 81 dumppcb = lookup("_dumppcb"); 82 if (dumppcb == 0) 83 return (NULL); 84 85 addr = lookup("_dumptid"); 86 if (addr != 0) 87 kvm_read(kvm, addr, &dumptid, sizeof(dumptid)); 88 else 89 dumptid = -1; 90 91 while (paddr != 0) { 92 if (kvm_read(kvm, paddr, &p, sizeof(p)) != sizeof(p)) 93 warnx("kvm_read: %s", kvm_geterr(kvm)); 94 addr = (uintptr_t)TAILQ_FIRST(&p.p_threads); 95 while (addr != 0) { 96 if (kvm_read(kvm, addr, &td, sizeof(td)) != sizeof(td)) 97 warnx("kvm_read: %s", kvm_geterr(kvm)); 98 kt = malloc(sizeof(*kt)); 99 kt->next = first; 100 kt->kaddr = addr; 101 kt->pcb = (td.td_tid == dumptid) ? dumppcb : 102 (uintptr_t)td.td_pcb; 103 kt->kstack = td.td_kstack; 104 kt->tid = td.td_tid; 105 first = kt; 106 addr = (uintptr_t)TAILQ_NEXT(&td, td_plist); 107 } 108 paddr = (uintptr_t)LIST_NEXT(&p, p_list); 109 } 110 curkthr = kgdb_thr_lookup(dumptid); 111 if (curkthr == NULL) 112 curkthr = first; 113 return (first); 114} 115 116struct kthr * 117kgdb_thr_lookup(int tid) 118{ 119 struct kthr *kt; 120 121 kt = first; 122 while (kt != NULL && kt->tid != tid) 123 kt = kt->next; 124 return (kt); 125} 126 127struct kthr * 128kgdb_thr_next(struct kthr *kt) 129{ 130 return (kt->next); 131} 132 133struct kthr * 134kgdb_thr_select(struct kthr *kt) 135{ 136 struct kthr *pcur; 137 138 pcur = curkthr; 139 curkthr = kt; 140 return (pcur); 141} 142