2 * Copyright (c) 2004 Marcel Moolenaar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
26 * $FreeBSD: src/gnu/usr.bin/gdb/kgdb/kthr.c,v 1.3 2005/09/10 18:25:53 marcel Exp $
27 * $DragonFly: src/gnu/usr.bin/gdb/kgdb/kthr.c,v 1.5 2008/01/14 21:36:38 corecode Exp $
30 #define _KERNEL_STRUCTURES
32 #include <sys/cdefs.h>
34 #include <sys/param.h>
35 #include <machine/globaldata.h>
37 #include <sys/types.h>
38 #include <sys/signal.h>
46 #include <frame-unwind.h>
50 static uintptr_t dumppcb
;
53 static struct kthr
*first
;
68 struct mdglobaldata gd
;
70 uintptr_t addr
, paddr
, prvspace
;
73 addr
= lookup("_ncpus");
76 kvm_read(kvm
, addr
, &ncpus
, sizeof(ncpus
));
78 dumppcb
= lookup("_dumppcb");
82 prvspace
= lookup("CPU_prvspace");
86 addr
= lookup("_dumpthread");
88 kvm_read(kvm
, addr
, &dumptid
, sizeof(dumptid
));
91 * XXX Well then. We don't know who dumped us.
92 * We could do some fancy stack matching, but
93 * I doubt this will work. For now just use
96 * Actually we don't even know if we were dumped
97 * or if we are life. Find out by querying "dumping".
101 addr
= lookup("_dumping");
102 kvm_read(kvm
, addr
, &dumping
, sizeof(dumping
));
104 kvm_read(kvm
, prvspace
+
105 offsetof(struct privatespace
, mdglobaldata
),
106 &gd
, sizeof(struct mdglobaldata
));
107 dumptid
= (intptr_t)gd
.mi
.gd_curthread
;
109 /* We must be a live system */
114 for (cpu
= 0; cpu
< ncpus
; cpu
++) {
115 kvm_read(kvm
, prvspace
+
116 cpu
* sizeof(struct privatespace
) +
117 offsetof(struct privatespace
, mdglobaldata
),
118 &gd
, sizeof(struct mdglobaldata
));
120 addr
= (uintptr_t)TAILQ_FIRST(&gd
.mi
.gd_tdallq
);
122 if (kvm_read(kvm
, addr
, &td
, sizeof(td
)) != sizeof(td
))
123 warnx("kvm_read: %s", kvm_geterr(kvm
));
124 kt
= malloc(sizeof(*kt
));
127 kt
->tid
= addr
; /* XXX do we have tids? */
128 kt
->pcb
= (kt
->tid
== dumptid
) ? dumppcb
:
129 (uintptr_t)td
.td_pcb
;
130 kt
->kstack
= (uintptr_t)td
.td_kstack
;
131 if (td
.td_proc
!= NULL
) {
132 paddr
= (uintptr_t)td
.td_proc
;
133 if (kvm_read(kvm
, paddr
, &p
, sizeof(p
)) != sizeof(p
))
134 warnx("kvm_read: %s", kvm_geterr(kvm
));
139 * XXX for some stupid reason, gdb uses pid == -1
140 * as a marker for "dead" threads, so we have to
141 * hook all kernel threads on a different pid :/
146 * We are a kernel thread, so our td_pcb is
147 * not used anyways. An exception is the
149 * kt->pcb == 0 is a marker for
150 * "non-dumping kernel thread".
152 if (kt
->tid
!= dumptid
)
156 addr
= (uintptr_t)TAILQ_NEXT(&td
, td_allq
);
160 curkthr
= kgdb_thr_lookup_tid(dumptid
);
167 kgdb_thr_lookup_tid(int tid
)
172 while (kt
!= NULL
&& kt
->tid
!= tid
)
178 kgdb_thr_lookup_taddr(uintptr_t taddr
)
183 while (kt
!= NULL
&& kt
->kaddr
!= taddr
)
189 kgdb_thr_lookup_pid(int pid
)
194 while (kt
!= NULL
&& kt
->pid
!= pid
)
200 kgdb_thr_lookup_paddr(uintptr_t paddr
)
205 while (kt
!= NULL
&& kt
->paddr
!= paddr
)
211 kgdb_thr_next(struct kthr
*kt
)
217 kgdb_thr_select(struct kthr
*kt
)
227 kgdb_thr_extra_thread_info(int tid
)
230 static char comm
[MAXCOMLEN
+ 1];
232 kt
= kgdb_thr_lookup_tid(tid
);
235 if (kvm_read(kvm
, kt
->kaddr
+ offsetof(struct thread
, td_comm
), &comm
,
236 sizeof(comm
)) != sizeof(comm
))