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 #include <sys/cdefs.h>
32 #include <sys/param.h>
33 #include <machine/globaldata.h>
35 #include <sys/types.h>
36 #include <sys/signal.h>
44 #include <frame-unwind.h>
48 static uintptr_t dumppcb
;
51 static struct kthr
*first
;
66 struct mdglobaldata gd
;
68 uintptr_t addr
, paddr
, prvspace
;
71 addr
= lookup("_ncpus");
74 kvm_read(kvm
, addr
, &ncpus
, sizeof(ncpus
));
76 dumppcb
= lookup("_dumppcb");
80 prvspace
= lookup("CPU_prvspace");
84 addr
= lookup("_dumpthread");
86 kvm_read(kvm
, addr
, &dumptid
, sizeof(dumptid
));
89 * XXX Well then. We don't know who dumped us.
90 * We could do some fancy stack matching, but
91 * I doubt this will work. For now just use
94 * Actually we don't even know if we were dumped
95 * or if we are life. Find out by querying "dumping".
99 addr
= lookup("_dumping");
100 kvm_read(kvm
, addr
, &dumping
, sizeof(dumping
));
102 kvm_read(kvm
, prvspace
+
103 offsetof(struct privatespace
, mdglobaldata
),
104 &gd
, sizeof(struct mdglobaldata
));
105 dumptid
= (intptr_t)gd
.mi
.gd_curthread
;
107 /* We must be a live system */
112 for (cpu
= 0; cpu
< ncpus
; cpu
++) {
113 kvm_read(kvm
, prvspace
+
114 cpu
* sizeof(struct privatespace
) +
115 offsetof(struct privatespace
, mdglobaldata
),
116 &gd
, sizeof(struct mdglobaldata
));
118 addr
= (uintptr_t)TAILQ_FIRST(&gd
.mi
.gd_tdallq
);
120 if (kvm_read(kvm
, addr
, &td
, sizeof(td
)) != sizeof(td
)) {
121 warnx("kvm_read: %s, while accessing thread",
125 kt
= malloc(sizeof(*kt
));
128 kt
->tid
= addr
; /* XXX do we have tids? */
129 kt
->pcb
= (kt
->tid
== dumptid
) ? dumppcb
:
130 (uintptr_t)td
.td_pcb
;
131 kt
->kstack
= (uintptr_t)td
.td_kstack
;
132 if (td
.td_proc
!= NULL
) {
133 paddr
= (uintptr_t)td
.td_proc
;
134 if (kvm_read(kvm
, paddr
, &p
, sizeof(p
)) != sizeof(p
))
135 warnx("kvm_read: %s", kvm_geterr(kvm
));
140 * XXX for some stupid reason, gdb uses pid == -1
141 * as a marker for "dead" threads, so we have to
142 * hook all kernel threads on a different pid :/
147 * We are a kernel thread, so our td_pcb is
148 * not used anyways. An exception is the
150 * kt->pcb == 0 is a marker for
151 * "non-dumping kernel thread".
153 if (kt
->tid
!= dumptid
)
157 addr
= (uintptr_t)TAILQ_NEXT(&td
, td_allq
);
161 curkthr
= kgdb_thr_lookup_tid(dumptid
);
168 kgdb_thr_lookup_tid(int tid
)
173 while (kt
!= NULL
&& kt
->tid
!= tid
)
179 kgdb_thr_lookup_taddr(uintptr_t taddr
)
184 while (kt
!= NULL
&& kt
->kaddr
!= taddr
)
190 kgdb_thr_lookup_pid(int pid
)
195 while (kt
!= NULL
&& kt
->pid
!= pid
)
201 kgdb_thr_lookup_paddr(uintptr_t paddr
)
206 while (kt
!= NULL
&& kt
->paddr
!= paddr
)
212 kgdb_thr_next(struct kthr
*kt
)
218 kgdb_thr_select(struct kthr
*kt
)
228 kgdb_thr_extra_thread_info(int tid
)
231 static char comm
[MAXCOMLEN
+ 1];
233 kt
= kgdb_thr_lookup_tid(tid
);
236 if (kvm_read(kvm
, kt
->kaddr
+ offsetof(struct thread
, td_comm
), &comm
,
237 sizeof(comm
)) != sizeof(comm
))