Deleted Added
full compact
libpthread_db.c (133342) libpthread_db.c (133802)
1/*
2 * Copyright (c) 2004 David Xu <davidxu@freebsd.org>
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 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*
2 * Copyright (c) 2004 David Xu <davidxu@freebsd.org>
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 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/lib/libthread_db/libpthread_db.c 133342 2004-08-08 22:37:53Z davidxu $");
28__FBSDID("$FreeBSD: head/lib/libthread_db/libpthread_db.c 133802 2004-08-16 03:30:16Z davidxu $");
29
29
30#include <link.h>
31#include <stddef.h>
32#include <stdlib.h>
33#include <string.h>
34#include <unistd.h>
35#include <pthread.h>
36#include <sys/types.h>
37#include <sys/kse.h>
38#include <sys/ptrace.h>
39#include <proc_service.h>
40#include <thread_db.h>
41
30#include <stddef.h>
31#include <stdlib.h>
32#include <string.h>
33#include <unistd.h>
34#include <pthread.h>
35#include <sys/types.h>
36#include <sys/kse.h>
37#include <sys/ptrace.h>
38#include <proc_service.h>
39#include <thread_db.h>
40
42#include "rtld.h"
43
44#include "libpthread.h"
45#include "libpthread_db.h"
46
47#define P2T(c) ps2td(c)
48
49static void pt_unmap_lwp(const td_thragent_t *ta, lwpid_t lwp);
50static int pt_validate(const td_thrhandle_t *th);
51
52static int

--- 74 unchanged lines hidden (view full) ---

127#define LOOKUP_SYM(proc, sym, addr) \
128 ret = ps_pglobal_lookup(proc, NULL, sym, addr); \
129 if (ret != 0) { \
130 TDBG("can not find symbol: %s\n", sym); \
131 ret = TD_NOLIBTHREAD; \
132 goto error; \
133 }
134
41#include "libpthread_db.h"
42
43#define P2T(c) ps2td(c)
44
45static void pt_unmap_lwp(const td_thragent_t *ta, lwpid_t lwp);
46static int pt_validate(const td_thrhandle_t *th);
47
48static int

--- 74 unchanged lines hidden (view full) ---

123#define LOOKUP_SYM(proc, sym, addr) \
124 ret = ps_pglobal_lookup(proc, NULL, sym, addr); \
125 if (ret != 0) { \
126 TDBG("can not find symbol: %s\n", sym); \
127 ret = TD_NOLIBTHREAD; \
128 goto error; \
129 }
130
131#define LOOKUP_VAL(proc, sym, val) \
132 ret = ps_pglobal_lookup(proc, NULL, sym, &vaddr);\
133 if (ret != 0) { \
134 TDBG("can not find symbol: %s\n", sym); \
135 ret = TD_NOLIBTHREAD; \
136 goto error; \
137 } \
138 ret = ps_pread(proc, vaddr, val, sizeof(int)); \
139 if (ret != 0) { \
140 TDBG("can not read value of %s\n", sym);\
141 ret = TD_NOLIBTHREAD; \
142 goto error; \
143 }
144
135 td_thragent_t *ta;
145 td_thragent_t *ta;
146 psaddr_t vaddr;
136 int dbg;
137 int ret;
138
139 TDBG_FUNC();
140
141 ta = malloc(sizeof(td_thragent_t));
142 if (ta == NULL)
143 return (TD_MALLOC);
144
145 ta->ph = ph;
146 ta->thread_activated = 0;
147 ta->map = NULL;
148 ta->map_len = 0;
149
150 LOOKUP_SYM(ph, "_libkse_debug", &ta->libkse_debug_addr);
151 LOOKUP_SYM(ph, "_thread_list", &ta->thread_list_addr);
152 LOOKUP_SYM(ph, "_thread_activated", &ta->thread_activated_addr);
153 LOOKUP_SYM(ph, "_thread_active_threads",&ta->thread_active_threads_addr);
154 LOOKUP_SYM(ph, "_thread_keytable", &ta->thread_keytable_addr);
147 int dbg;
148 int ret;
149
150 TDBG_FUNC();
151
152 ta = malloc(sizeof(td_thragent_t));
153 if (ta == NULL)
154 return (TD_MALLOC);
155
156 ta->ph = ph;
157 ta->thread_activated = 0;
158 ta->map = NULL;
159 ta->map_len = 0;
160
161 LOOKUP_SYM(ph, "_libkse_debug", &ta->libkse_debug_addr);
162 LOOKUP_SYM(ph, "_thread_list", &ta->thread_list_addr);
163 LOOKUP_SYM(ph, "_thread_activated", &ta->thread_activated_addr);
164 LOOKUP_SYM(ph, "_thread_active_threads",&ta->thread_active_threads_addr);
165 LOOKUP_SYM(ph, "_thread_keytable", &ta->thread_keytable_addr);
155
166 LOOKUP_VAL(ph, "_thread_off_dtv", &ta->thread_off_dtv);
167 LOOKUP_VAL(ph, "_thread_off_kse_locklevel", &ta->thread_off_kse_locklevel);
168 LOOKUP_VAL(ph, "_thread_off_kse", &ta->thread_off_kse);
169 LOOKUP_VAL(ph, "_thread_off_tlsindex", &ta->thread_off_tlsindex);
170 LOOKUP_VAL(ph, "_thread_off_attr_flags", &ta->thread_off_attr_flags);
171 LOOKUP_VAL(ph, "_thread_size_key", &ta->thread_size_key);
172 LOOKUP_VAL(ph, "_thread_off_tcb", &ta->thread_off_tcb);
173 LOOKUP_VAL(ph, "_thread_off_linkmap", &ta->thread_off_linkmap);
174 LOOKUP_VAL(ph, "_thread_off_tmbx", &ta->thread_off_tmbx);
175 LOOKUP_VAL(ph, "_thread_off_thr_locklevel", &ta->thread_off_thr_locklevel);
176 LOOKUP_VAL(ph, "_thread_off_next", &ta->thread_off_next);
177 LOOKUP_VAL(ph, "_thread_off_state", &ta->thread_off_state);
178 LOOKUP_VAL(ph, "_thread_max_keys", &ta->thread_max_keys);
179 LOOKUP_VAL(ph, "_thread_off_key_allocated", &ta->thread_off_key_allocated);
180 LOOKUP_VAL(ph, "_thread_off_key_destructor", &ta->thread_off_key_destructor);
181 LOOKUP_VAL(ph, "_thread_state_running", &ta->thread_state_running);
182 LOOKUP_VAL(ph, "_thread_state_zoombie", &ta->thread_state_zoombie);
156 dbg = getpid();
157 /*
158 * If this fails it probably means we're debugging a core file and
159 * can't write to it.
160 */
161 ps_pwrite(ph, ta->libkse_debug_addr, &dbg, sizeof(int));
162 *pta = ta;
163 return (0);

--- 42 unchanged lines hidden (view full) ---

206 pt = (psaddr_t)thread_list.tqh_first;
207 if (ta->map[id].type == PT_LWP) {
208 /*
209 * if we are referencing a lwp, make sure it was not already
210 * mapped to user thread.
211 */
212 while (pt != 0) {
213 ret = ps_pread(ta->ph,
183 dbg = getpid();
184 /*
185 * If this fails it probably means we're debugging a core file and
186 * can't write to it.
187 */
188 ps_pwrite(ph, ta->libkse_debug_addr, &dbg, sizeof(int));
189 *pta = ta;
190 return (0);

--- 42 unchanged lines hidden (view full) ---

233 pt = (psaddr_t)thread_list.tqh_first;
234 if (ta->map[id].type == PT_LWP) {
235 /*
236 * if we are referencing a lwp, make sure it was not already
237 * mapped to user thread.
238 */
239 while (pt != 0) {
240 ret = ps_pread(ta->ph,
214 pt + offsetof(struct pthread, tcb),
241 pt + ta->thread_off_tcb,
215 &tcb_addr, sizeof(tcb_addr));
216 if (ret != 0)
217 return (P2T(ret));
218 ret = ps_pread(ta->ph,
242 &tcb_addr, sizeof(tcb_addr));
243 if (ret != 0)
244 return (P2T(ret));
245 ret = ps_pread(ta->ph,
219 tcb_addr + offsetof(struct tcb,
220 tcb_tmbx.tm_lwp),
246 tcb_addr + ta->thread_off_tmbx +
247 offsetof(struct kse_thr_mailbox, tm_lwp),
221 &lwp, sizeof(lwp));
222 if (ret != 0)
223 return (P2T(ret));
224 /*
225 * If the lwp was already mapped to userland thread,
226 * we shouldn't reference it directly in future.
227 */
228 if (lwp == ta->map[id].lwp) {
229 ta->map[id].type = PT_NONE;
230 return (TD_NOTHR);
231 }
232 /* get next thread */
233 ret = ps_pread(ta->ph,
248 &lwp, sizeof(lwp));
249 if (ret != 0)
250 return (P2T(ret));
251 /*
252 * If the lwp was already mapped to userland thread,
253 * we shouldn't reference it directly in future.
254 */
255 if (lwp == ta->map[id].lwp) {
256 ta->map[id].type = PT_NONE;
257 return (TD_NOTHR);
258 }
259 /* get next thread */
260 ret = ps_pread(ta->ph,
234 pt + offsetof(struct pthread, tle.tqe_next),
261 pt + ta->thread_off_next,
235 &pt, sizeof(pt));
236 if (ret != 0)
237 return (P2T(ret));
238 }
239 /* check lwp */
240 ret = ptrace(PT_GETREGS, ta->map[id].lwp, (caddr_t)&gregs, 0);
241 if (ret != 0) {
242 /* no longer exists */
243 ta->map[id].type = PT_NONE;
244 return (TD_NOTHR);
245 }
246 } else {
247 while (pt != 0 && ta->map[id].thr != pt) {
248 ret = ps_pread(ta->ph,
262 &pt, sizeof(pt));
263 if (ret != 0)
264 return (P2T(ret));
265 }
266 /* check lwp */
267 ret = ptrace(PT_GETREGS, ta->map[id].lwp, (caddr_t)&gregs, 0);
268 if (ret != 0) {
269 /* no longer exists */
270 ta->map[id].type = PT_NONE;
271 return (TD_NOTHR);
272 }
273 } else {
274 while (pt != 0 && ta->map[id].thr != pt) {
275 ret = ps_pread(ta->ph,
249 pt + offsetof(struct pthread, tcb),
276 pt + ta->thread_off_tcb,
250 &tcb_addr, sizeof(tcb_addr));
251 if (ret != 0)
252 return (P2T(ret));
253 /* get next thread */
254 ret = ps_pread(ta->ph,
277 &tcb_addr, sizeof(tcb_addr));
278 if (ret != 0)
279 return (P2T(ret));
280 /* get next thread */
281 ret = ps_pread(ta->ph,
255 pt + offsetof(struct pthread, tle.tqe_next),
282 pt + ta->thread_off_next,
256 &pt, sizeof(pt));
257 if (ret != 0)
258 return (P2T(ret));
259 }
260
261 if (pt == 0) {
262 /* no longer exists */
263 ta->map[id].type = PT_NONE;

--- 16 unchanged lines hidden (view full) ---

280 TDBG_FUNC();
281
282 ret = ps_pread(ta->ph, ta->thread_list_addr, &thread_list,
283 sizeof(thread_list));
284 if (ret != 0)
285 return (P2T(ret));
286 pt = (psaddr_t)thread_list.tqh_first;
287 while (pt != 0) {
283 &pt, sizeof(pt));
284 if (ret != 0)
285 return (P2T(ret));
286 }
287
288 if (pt == 0) {
289 /* no longer exists */
290 ta->map[id].type = PT_NONE;

--- 16 unchanged lines hidden (view full) ---

307 TDBG_FUNC();
308
309 ret = ps_pread(ta->ph, ta->thread_list_addr, &thread_list,
310 sizeof(thread_list));
311 if (ret != 0)
312 return (P2T(ret));
313 pt = (psaddr_t)thread_list.tqh_first;
314 while (pt != 0) {
288 ret = ps_pread(ta->ph, pt + offsetof(struct pthread, tcb),
315 ret = ps_pread(ta->ph, pt + ta->thread_off_tcb,
289 &ptr, sizeof(ptr));
290 if (ret != 0)
291 return (P2T(ret));
316 &ptr, sizeof(ptr));
317 if (ret != 0)
318 return (P2T(ret));
292 ptr += offsetof(struct tcb, tcb_tmbx.tm_lwp);
319 ptr += ta->thread_off_tmbx +
320 offsetof(struct kse_thr_mailbox, tm_lwp);
293 ret = ps_pread(ta->ph, ptr, &tmp_lwp, sizeof(lwpid_t));
294 if (ret != 0)
295 return (P2T(ret));
296 if (tmp_lwp == lwp) {
297 th->th_ta = ta;
298 th->th_tid = pt_map_thread(ta, pt, PT_USER);
299 if (th->th_tid == -1)
300 return (TD_MALLOC);
301 pt_unmap_lwp(ta, lwp);
302 return (TD_OK);
303 }
304
305 /* get next thread */
306 ret = ps_pread(ta->ph,
321 ret = ps_pread(ta->ph, ptr, &tmp_lwp, sizeof(lwpid_t));
322 if (ret != 0)
323 return (P2T(ret));
324 if (tmp_lwp == lwp) {
325 th->th_ta = ta;
326 th->th_tid = pt_map_thread(ta, pt, PT_USER);
327 if (th->th_tid == -1)
328 return (TD_MALLOC);
329 pt_unmap_lwp(ta, lwp);
330 return (TD_OK);
331 }
332
333 /* get next thread */
334 ret = ps_pread(ta->ph,
307 pt + offsetof(struct pthread, tle.tqe_next),
335 pt + ta->thread_off_next,
308 &pt, sizeof(pt));
309 if (ret != 0)
310 return (P2T(ret));
311 }
312
313 return (TD_NOTHR);
314}
315

--- 29 unchanged lines hidden (view full) ---

345 th.th_tid = pt_map_thread(ta, pt, PT_USER);
346 /* should we unmap lwp here ? */
347 if (th.th_tid == -1)
348 return (TD_MALLOC);
349 if ((*callback)(&th, cbdata_p))
350 return (TD_DBERR);
351 /* get next thread */
352 pserr = ps_pread(ta->ph,
336 &pt, sizeof(pt));
337 if (ret != 0)
338 return (P2T(ret));
339 }
340
341 return (TD_NOTHR);
342}
343

--- 29 unchanged lines hidden (view full) ---

373 th.th_tid = pt_map_thread(ta, pt, PT_USER);
374 /* should we unmap lwp here ? */
375 if (th.th_tid == -1)
376 return (TD_MALLOC);
377 if ((*callback)(&th, cbdata_p))
378 return (TD_DBERR);
379 /* get next thread */
380 pserr = ps_pread(ta->ph,
353 pt + offsetof(struct pthread, tle.tqe_next), &pt,
381 pt + ta->thread_off_next, &pt,
354 sizeof(pt));
355 if (pserr != PS_OK)
356 return (P2T(pserr));
357 }
358 return (TD_OK);
359}
360
361static td_err_e
362pt_ta_tsd_iter(const td_thragent_t *ta, td_key_iter_f *ki, void *arg)
363{
382 sizeof(pt));
383 if (pserr != PS_OK)
384 return (P2T(pserr));
385 }
386 return (TD_OK);
387}
388
389static td_err_e
390pt_ta_tsd_iter(const td_thragent_t *ta, td_key_iter_f *ki, void *arg)
391{
364 struct pthread_key keytable[PTHREAD_KEYS_MAX];
365 int i, ret;
392 char *keytable;
393 void *destructor;
394 int i, ret, allocated;
366
367 TDBG_FUNC();
368
395
396 TDBG_FUNC();
397
398 keytable = malloc(ta->thread_max_keys * ta->thread_size_key);
399 if (keytable == NULL)
400 return (TD_MALLOC);
369 ret = ps_pread(ta->ph, (psaddr_t)ta->thread_keytable_addr, keytable,
401 ret = ps_pread(ta->ph, (psaddr_t)ta->thread_keytable_addr, keytable,
370 sizeof(keytable));
402 ta->thread_max_keys * ta->thread_size_key);
371 if (ret != 0)
372 return (P2T(ret));
403 if (ret != 0)
404 return (P2T(ret));
373
374 for (i = 0; i < PTHREAD_KEYS_MAX; i++) {
375 if (keytable[i].allocated) {
376 ret = (ki)(i, keytable[i].destructor, arg);
377 if (ret != 0)
405 for (i = 0; i < ta->thread_max_keys; i++) {
406 allocated = *(int *)(keytable + i * ta->thread_size_key +
407 ta->thread_off_key_allocated);
408 destructor = *(void **)(keytable + i * ta->thread_size_key +
409 ta->thread_off_key_destructor);
410 if (allocated) {
411 ret = (ki)(i, destructor, arg);
412 if (ret != 0) {
413 free(keytable);
378 return (TD_DBERR);
414 return (TD_DBERR);
415 }
379 }
380 }
416 }
417 }
418 free(keytable);
381 return (TD_OK);
382}
383
384static td_err_e
385pt_ta_event_addr(const td_thragent_t *ta, td_event_e event, td_notify_t *ptr)
386{
387 TDBG_FUNC();
388 return (TD_NOEVENT);

--- 39 unchanged lines hidden (view full) ---

428 if (suspend)
429 ret = ps_lstop(ta->ph, ta->map[th->th_tid].lwp);
430 else
431 ret = ps_lcontinue(ta->ph, ta->map[th->th_tid].lwp);
432 return (P2T(ret));
433 }
434
435 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
419 return (TD_OK);
420}
421
422static td_err_e
423pt_ta_event_addr(const td_thragent_t *ta, td_event_e event, td_notify_t *ptr)
424{
425 TDBG_FUNC();
426 return (TD_NOEVENT);

--- 39 unchanged lines hidden (view full) ---

466 if (suspend)
467 ret = ps_lstop(ta->ph, ta->map[th->th_tid].lwp);
468 else
469 ret = ps_lcontinue(ta->ph, ta->map[th->th_tid].lwp);
470 return (P2T(ret));
471 }
472
473 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
436 offsetof(struct pthread, attr.flags),
474 ta->thread_off_attr_flags,
437 &attrflags, sizeof(attrflags));
438 if (ret != 0)
439 return (P2T(ret));
440 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
475 &attrflags, sizeof(attrflags));
476 if (ret != 0)
477 return (P2T(ret));
478 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
441 offsetof(struct pthread, tcb),
442 &tcb_addr, sizeof(tcb_addr));
479 ta->thread_off_tcb,
480 &tcb_addr, sizeof(tcb_addr));
443 if (ret != 0)
444 return (P2T(ret));
481 if (ret != 0)
482 return (P2T(ret));
445 tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
483 tmbx_addr = tcb_addr + ta->thread_off_tmbx;
446 ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
447 ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
448 if (ret != 0)
449 return (P2T(ret));
450
451 if (lwp != 0) {
452 /* don't suspend signal thread */
484 ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
485 ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
486 if (ret != 0)
487 return (P2T(ret));
488
489 if (lwp != 0) {
490 /* don't suspend signal thread */
453 if (attrflags & THR_SIGNAL_THREAD)
491 if (attrflags & 0x200)
454 return (0);
455 if (attrflags & PTHREAD_SCOPE_SYSTEM) {
456 /*
457 * don't suspend system scope thread if it is holding
458 * some low level locks
459 */
492 return (0);
493 if (attrflags & PTHREAD_SCOPE_SYSTEM) {
494 /*
495 * don't suspend system scope thread if it is holding
496 * some low level locks
497 */
460 ptr = ta->map[th->th_tid].thr +
461 offsetof(struct pthread, kse);
498 ptr = ta->map[th->th_tid].thr + ta->thread_off_kse;
462 ret = ps_pread(ta->ph, ptr, &ptr, sizeof(ptr));
463 if (ret != 0)
464 return (P2T(ret));
499 ret = ps_pread(ta->ph, ptr, &ptr, sizeof(ptr));
500 if (ret != 0)
501 return (P2T(ret));
465 ret = ps_pread(ta->ph, ptr + offsetof(struct kse,
466 k_locklevel), &locklevel, sizeof(int));
502 ret = ps_pread(ta->ph, ptr + ta->thread_off_kse_locklevel,
503 &locklevel, sizeof(int));
467 if (ret != 0)
468 return (P2T(ret));
469 if (locklevel <= 0) {
470 ptr = ta->map[th->th_tid].thr +
504 if (ret != 0)
505 return (P2T(ret));
506 if (locklevel <= 0) {
507 ptr = ta->map[th->th_tid].thr +
471 offsetof(struct pthread, locklevel);
508 ta->thread_off_thr_locklevel;
472 ret = ps_pread(ta->ph, ptr, &locklevel,
473 sizeof(int));
474 if (ret != 0)
475 return (P2T(ret));
476 }
477 if (suspend) {
478 if (locklevel <= 0)
479 ret = ps_lstop(ta->ph, lwp);

--- 63 unchanged lines hidden (view full) ---

543 &temp);
544 return (ret);
545}
546
547static td_err_e
548pt_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
549{
550 const td_thragent_t *ta = th->th_ta;
509 ret = ps_pread(ta->ph, ptr, &locklevel,
510 sizeof(int));
511 if (ret != 0)
512 return (P2T(ret));
513 }
514 if (suspend) {
515 if (locklevel <= 0)
516 ret = ps_lstop(ta->ph, lwp);

--- 63 unchanged lines hidden (view full) ---

580 &temp);
581 return (ret);
582}
583
584static td_err_e
585pt_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
586{
587 const td_thragent_t *ta = th->th_ta;
551 struct pthread pt;
552 int ret;
588 psaddr_t tcb_addr;
553 uint32_t dflags;
589 uint32_t dflags;
590 int state;
591 int ret;
554
555 TDBG_FUNC();
556
557 ret = pt_validate(th);
558 if (ret)
559 return (ret);
560
561 memset(info, 0, sizeof(*info));
562 if (ta->map[th->th_tid].type == PT_LWP) {
563 info->ti_type = TD_THR_SYSTEM;
564 info->ti_lid = ta->map[th->th_tid].lwp;
565 info->ti_tid = th->th_tid;
566 info->ti_state = TD_THR_RUN;
567 info->ti_type = TD_THR_SYSTEM;
568 return (TD_OK);
569 }
592
593 TDBG_FUNC();
594
595 ret = pt_validate(th);
596 if (ret)
597 return (ret);
598
599 memset(info, 0, sizeof(*info));
600 if (ta->map[th->th_tid].type == PT_LWP) {
601 info->ti_type = TD_THR_SYSTEM;
602 info->ti_lid = ta->map[th->th_tid].lwp;
603 info->ti_tid = th->th_tid;
604 info->ti_state = TD_THR_RUN;
605 info->ti_type = TD_THR_SYSTEM;
606 return (TD_OK);
607 }
570
571 ret = ps_pread(ta->ph, (psaddr_t)(ta->map[th->th_tid].thr),
572 &pt, sizeof(pt));
608 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr + ta->thread_off_tcb,
609 &tcb_addr, sizeof(tcb_addr));
573 if (ret != 0)
574 return (P2T(ret));
610 if (ret != 0)
611 return (P2T(ret));
575 if (pt.magic != THR_MAGIC)
576 return (TD_BADTH);
612 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr + ta->thread_off_state,
613 &state, sizeof(state));
577 ret = ps_pread(ta->ph,
614 ret = ps_pread(ta->ph,
578 ((psaddr_t)pt.tcb) + offsetof(struct tcb, tcb_tmbx.tm_lwp),
615 tcb_addr + ta->thread_off_tmbx +
616 offsetof(struct kse_thr_mailbox, tm_lwp),
579 &info->ti_lid, sizeof(lwpid_t));
580 if (ret != 0)
581 return (P2T(ret));
582 ret = ps_pread(ta->ph,
617 &info->ti_lid, sizeof(lwpid_t));
618 if (ret != 0)
619 return (P2T(ret));
620 ret = ps_pread(ta->ph,
583 ((psaddr_t)pt.tcb) + offsetof(struct tcb, tcb_tmbx.tm_dflags),
621 tcb_addr + ta->thread_off_tmbx +
622 offsetof(struct kse_thr_mailbox, tm_dflags),
584 &dflags, sizeof(dflags));
585 if (ret != 0)
586 return (P2T(ret));
587 info->ti_ta_p = th->th_ta;
588 info->ti_tid = th->th_tid;
623 &dflags, sizeof(dflags));
624 if (ret != 0)
625 return (P2T(ret));
626 info->ti_ta_p = th->th_ta;
627 info->ti_tid = th->th_tid;
589 info->ti_tls = (char *)pt.specific;
590 info->ti_startfunc = (psaddr_t)pt.start_routine;
591 info->ti_stkbase = (psaddr_t) pt.attr.stackaddr_attr;
592 info->ti_stksize = pt.attr.stacksize_attr;
593 switch (pt.state) {
594 case PS_RUNNING:
628 if (state == ta->thread_state_running)
595 info->ti_state = TD_THR_RUN;
629 info->ti_state = TD_THR_RUN;
596 break;
597 case PS_LOCKWAIT:
598 case PS_MUTEX_WAIT:
599 case PS_COND_WAIT:
600 case PS_SIGSUSPEND:
601 case PS_SIGWAIT:
602 case PS_JOIN:
603 case PS_SUSPENDED:
604 case PS_DEADLOCK:
605 case PS_SLEEP_WAIT:
606 info->ti_state = TD_THR_SLEEP;
607 break;
608 case PS_DEAD:
630 else if (state == ta->thread_state_zoombie)
609 info->ti_state = TD_THR_ZOMBIE;
631 info->ti_state = TD_THR_ZOMBIE;
610 break;
611 default:
612 info->ti_state = TD_THR_UNKNOWN;
613 break;
614 }
615
632 else
633 info->ti_state = TD_THR_SLEEP;
616 info->ti_db_suspended = ((dflags & TMDF_SUSPEND) != 0);
617 info->ti_type = TD_THR_USER;
634 info->ti_db_suspended = ((dflags & TMDF_SUSPEND) != 0);
635 info->ti_type = TD_THR_USER;
618 info->ti_pri = pt.active_priority;
619 info->ti_sigmask = pt.sigmask;
620 info->ti_traceme = 0;
621 info->ti_pending = pt.sigpend;
622 info->ti_events = 0;
623 return (0);
624}
625
626static td_err_e
627pt_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregs)
628{
629 const td_thragent_t *ta = th->th_ta;
630 struct kse_thr_mailbox tmbx;

--- 7 unchanged lines hidden (view full) ---

638 if (ret)
639 return (ret);
640
641 if (ta->map[th->th_tid].type == PT_LWP) {
642 ret = ps_lgetfpregs(ta->ph, ta->map[th->th_tid].lwp, fpregs);
643 return (P2T(ret));
644 }
645
636 return (0);
637}
638
639static td_err_e
640pt_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregs)
641{
642 const td_thragent_t *ta = th->th_ta;
643 struct kse_thr_mailbox tmbx;

--- 7 unchanged lines hidden (view full) ---

651 if (ret)
652 return (ret);
653
654 if (ta->map[th->th_tid].type == PT_LWP) {
655 ret = ps_lgetfpregs(ta->ph, ta->map[th->th_tid].lwp, fpregs);
656 return (P2T(ret));
657 }
658
646 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
647 offsetof(struct pthread, tcb),
659 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr + ta->thread_off_tcb,
648 &tcb_addr, sizeof(tcb_addr));
649 if (ret != 0)
650 return (P2T(ret));
660 &tcb_addr, sizeof(tcb_addr));
661 if (ret != 0)
662 return (P2T(ret));
651 tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
663 tmbx_addr = tcb_addr + ta->thread_off_tmbx;
652 ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
653 ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
654 if (ret != 0)
655 return (P2T(ret));
656 if (lwp != 0) {
657 ret = ps_lgetfpregs(ta->ph, lwp, fpregs);
658 return (P2T(ret));
659 }

--- 21 unchanged lines hidden (view full) ---

681 return (ret);
682
683 if (ta->map[th->th_tid].type == PT_LWP) {
684 ret = ps_lgetregs(ta->ph,
685 ta->map[th->th_tid].lwp, gregs);
686 return (P2T(ret));
687 }
688
664 ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
665 ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
666 if (ret != 0)
667 return (P2T(ret));
668 if (lwp != 0) {
669 ret = ps_lgetfpregs(ta->ph, lwp, fpregs);
670 return (P2T(ret));
671 }

--- 21 unchanged lines hidden (view full) ---

693 return (ret);
694
695 if (ta->map[th->th_tid].type == PT_LWP) {
696 ret = ps_lgetregs(ta->ph,
697 ta->map[th->th_tid].lwp, gregs);
698 return (P2T(ret));
699 }
700
689 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
690 offsetof(struct pthread, tcb),
701 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr + ta->thread_off_tcb,
691 &tcb_addr, sizeof(tcb_addr));
692 if (ret != 0)
693 return (P2T(ret));
702 &tcb_addr, sizeof(tcb_addr));
703 if (ret != 0)
704 return (P2T(ret));
694 tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
705 tmbx_addr = tcb_addr + ta->thread_off_tmbx;
695 ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
696 ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
697 if (ret != 0)
698 return (P2T(ret));
699 if (lwp != 0) {
700 ret = ps_lgetregs(ta->ph, lwp, gregs);
701 return (P2T(ret));
702 }

--- 20 unchanged lines hidden (view full) ---

723 return (ret);
724
725 if (ta->map[th->th_tid].type == PT_LWP) {
726 ret = ps_lsetfpregs(ta->ph, ta->map[th->th_tid].lwp, fpregs);
727 return (P2T(ret));
728 }
729
730 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
706 ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
707 ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
708 if (ret != 0)
709 return (P2T(ret));
710 if (lwp != 0) {
711 ret = ps_lgetregs(ta->ph, lwp, gregs);
712 return (P2T(ret));
713 }

--- 20 unchanged lines hidden (view full) ---

734 return (ret);
735
736 if (ta->map[th->th_tid].type == PT_LWP) {
737 ret = ps_lsetfpregs(ta->ph, ta->map[th->th_tid].lwp, fpregs);
738 return (P2T(ret));
739 }
740
741 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
731 offsetof(struct pthread, tcb),
742 ta->thread_off_tcb,
732 &tcb_addr, sizeof(tcb_addr));
733 if (ret != 0)
734 return (P2T(ret));
743 &tcb_addr, sizeof(tcb_addr));
744 if (ret != 0)
745 return (P2T(ret));
735 tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
746 tmbx_addr = tcb_addr + ta->thread_off_tmbx;
736 ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
737 ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
738 if (ret != 0)
739 return (P2T(ret));
740 if (lwp != 0) {
741 ret = ps_lsetfpregs(ta->ph, lwp, fpregs);
742 return (P2T(ret));
743 }

--- 26 unchanged lines hidden (view full) ---

770 return (ret);
771
772 if (ta->map[th->th_tid].type == PT_LWP) {
773 ret = ps_lsetregs(ta->ph, ta->map[th->th_tid].lwp, gregs);
774 return (P2T(ret));
775 }
776
777 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
747 ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
748 ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
749 if (ret != 0)
750 return (P2T(ret));
751 if (lwp != 0) {
752 ret = ps_lsetfpregs(ta->ph, lwp, fpregs);
753 return (P2T(ret));
754 }

--- 26 unchanged lines hidden (view full) ---

781 return (ret);
782
783 if (ta->map[th->th_tid].type == PT_LWP) {
784 ret = ps_lsetregs(ta->ph, ta->map[th->th_tid].lwp, gregs);
785 return (P2T(ret));
786 }
787
788 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
778 offsetof(struct pthread, tcb),
789 ta->thread_off_tcb,
779 &tcb_addr, sizeof(tcb_addr));
780 if (ret != 0)
781 return (P2T(ret));
790 &tcb_addr, sizeof(tcb_addr));
791 if (ret != 0)
792 return (P2T(ret));
782 tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
793 tmbx_addr = tcb_addr + ta->thread_off_tmbx;
783 ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
784 ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
785 if (ret != 0)
786 return (P2T(ret));
787 if (lwp != 0) {
788 ret = ps_lsetregs(ta->ph, lwp, gregs);
789 return (P2T(ret));
790 }

--- 54 unchanged lines hidden (view full) ---

845 ret = pt_validate(th);
846 if (ret)
847 return (ret);
848
849 if (ta->map[th->th_tid].type == PT_LWP)
850 return (TD_BADTH);
851
852 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
794 ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
795 ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
796 if (ret != 0)
797 return (P2T(ret));
798 if (lwp != 0) {
799 ret = ps_lsetregs(ta->ph, lwp, gregs);
800 return (P2T(ret));
801 }

--- 54 unchanged lines hidden (view full) ---

856 ret = pt_validate(th);
857 if (ret)
858 return (ret);
859
860 if (ta->map[th->th_tid].type == PT_LWP)
861 return (TD_BADTH);
862
863 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
853 offsetof(struct pthread, tcb),
864 ta->thread_off_tcb,
854 &tcb_addr, sizeof(tcb_addr));
855 if (ret != 0)
856 return (P2T(ret));
857
858 /* Clear or set single step flag in thread mailbox */
865 &tcb_addr, sizeof(tcb_addr));
866 if (ret != 0)
867 return (P2T(ret));
868
869 /* Clear or set single step flag in thread mailbox */
859 ret = ps_pread(ta->ph, tcb_addr + offsetof(struct tcb,
860 tcb_tmbx.tm_dflags), &dflags, sizeof(uint32_t));
870 ret = ps_pread(ta->ph,
871 tcb_addr + ta->thread_off_tmbx +
872 offsetof(struct kse_thr_mailbox, tm_dflags),
873 &dflags, sizeof(uint32_t));
861 if (ret != 0)
862 return (P2T(ret));
863 if (step != 0)
864 dflags |= TMDF_SSTEP;
865 else
866 dflags &= ~TMDF_SSTEP;
874 if (ret != 0)
875 return (P2T(ret));
876 if (step != 0)
877 dflags |= TMDF_SSTEP;
878 else
879 dflags &= ~TMDF_SSTEP;
867 ret = ps_pwrite(ta->ph, tcb_addr + offsetof(struct tcb,
868 tcb_tmbx.tm_dflags), &dflags, sizeof(uint32_t));
880 ret = ps_pwrite(ta->ph,
881 tcb_addr + ta->thread_off_tmbx +
882 offsetof(struct kse_thr_mailbox, tm_dflags),
883 &dflags, sizeof(uint32_t));
869 if (ret != 0)
870 return (P2T(ret));
871 /* Get lwp */
884 if (ret != 0)
885 return (P2T(ret));
886 /* Get lwp */
872 ret = ps_pread(ta->ph, tcb_addr + offsetof(struct tcb,
873 tcb_tmbx.tm_lwp), &lwp, sizeof(lwpid_t));
887 ret = ps_pread(ta->ph,
888 tcb_addr + ta->thread_off_tmbx +
889 offsetof(struct kse_thr_mailbox, tm_lwp),
890 &lwp, sizeof(lwpid_t));
874 if (ret != 0)
875 return (P2T(ret));
876 if (lwp != 0)
877 return (0);
878
891 if (ret != 0)
892 return (P2T(ret));
893 if (lwp != 0)
894 return (0);
895
879 tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
896 tmbx_addr = tcb_addr + ta->thread_off_tmbx;
880 /*
881 * context is in userland, some architectures store
882 * single step status in registers, we should change
883 * these registers.
884 */
885 ret = ps_pread(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
886 if (ret == 0) {
887 pt_ucontext_to_reg(&tmbx.tm_context, &regs);

--- 29 unchanged lines hidden (view full) ---

917 return (TD_NOTHR);
918 return (TD_OK);
919}
920
921td_err_e
922pt_thr_tls_get_addr(const td_thrhandle_t *th, void *_linkmap, size_t offset,
923 void **address)
924{
897 /*
898 * context is in userland, some architectures store
899 * single step status in registers, we should change
900 * these registers.
901 */
902 ret = ps_pread(ta->ph, tmbx_addr, &tmbx, sizeof(tmbx));
903 if (ret == 0) {
904 pt_ucontext_to_reg(&tmbx.tm_context, &regs);

--- 29 unchanged lines hidden (view full) ---

934 return (TD_NOTHR);
935 return (TD_OK);
936}
937
938td_err_e
939pt_thr_tls_get_addr(const td_thrhandle_t *th, void *_linkmap, size_t offset,
940 void **address)
941{
925#if 0
926 Obj_Entry *obj_entry;
942 char *obj_entry;
927 const td_thragent_t *ta = th->th_ta;
928 psaddr_t tcb_addr, *dtv_addr, tcb_tp;
929 int tls_index, ret;
930
931 /* linkmap is a member of Obj_Entry */
943 const td_thragent_t *ta = th->th_ta;
944 psaddr_t tcb_addr, *dtv_addr, tcb_tp;
945 int tls_index, ret;
946
947 /* linkmap is a member of Obj_Entry */
932 obj_entry = (Obj_Entry *)
933 (((char *)_linkmap) - offsetof(Obj_Entry, linkmap));
948 obj_entry = (char *)_linkmap - ta->thread_off_linkmap;
934
935 /* get tlsindex of the object file */
936 ret = ps_pread(ta->ph,
949
950 /* get tlsindex of the object file */
951 ret = ps_pread(ta->ph,
937 ((char *)obj_entry) + offsetof(Obj_Entry, tlsindex),
952 obj_entry + ta->thread_off_tlsindex,
938 &tls_index, sizeof(tls_index));
939 if (ret != 0)
940 return (P2T(ret));
941
942 /* get thread tcb */
943 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
953 &tls_index, sizeof(tls_index));
954 if (ret != 0)
955 return (P2T(ret));
956
957 /* get thread tcb */
958 ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
944 offsetof(struct pthread, tcb),
959 ta->thread_off_tcb,
945 &tcb_addr, sizeof(tcb_addr));
946 if (ret != 0)
947 return (P2T(ret));
948
960 &tcb_addr, sizeof(tcb_addr));
961 if (ret != 0)
962 return (P2T(ret));
963
949#ifdef TLS_DTV_AT_TCB
950 /* get dtv array address */
964 /* get dtv array address */
951 ret = ps_pread(ta->ph, tcb_addr + offsetof(struct tcb, tcb_dtv),
965 ret = ps_pread(ta->ph, tcb_addr + ta->thread_off_dtv,
952 &dtv_addr, sizeof(dtv_addr));
953 if (ret != 0)
954 return (P2T(ret));
966 &dtv_addr, sizeof(dtv_addr));
967 if (ret != 0)
968 return (P2T(ret));
955#else
956 #ifdef TLS_DTV_AT_TP
957 ret = ps_pread(ta->ph, tcb_addr + offsetof(struct tcb, tcb_tp),
958 &tcb_tp, sizeof(tcb_tp));
959 if (ret != 0)
960 return (P2T(ret));
961 ret = ps_pread(ta->ph, tcb_tp + offsetof(struct tp, tp_dtv),
962 &dtv_addr, sizeof(dtv_addr));
963 #else
964 #error "Either TLS_DTV_AT_TP or TLS_DTV_AT_TCB must be defined."
965 #endif
966#endif
967 /* now get the object's tls block base address */
968 ret = ps_pread(ta->ph, &dtv_addr[tls_index+1], address,
969 sizeof(*address));
970 if (ret != 0)
971 return (P2T(ret));
972
973 *address += offset;
969 /* now get the object's tls block base address */
970 ret = ps_pread(ta->ph, &dtv_addr[tls_index+1], address,
971 sizeof(*address));
972 if (ret != 0)
973 return (P2T(ret));
974
975 *address += offset;
974#endif
975 return (TD_OK);
976}
977
978struct ta_ops libpthread_db_ops = {
979 .to_init = pt_init,
980 .to_ta_clear_event = pt_ta_clear_event,
981 .to_ta_delete = pt_ta_delete,
982 .to_ta_event_addr = pt_ta_event_addr,

--- 24 unchanged lines hidden ---
976 return (TD_OK);
977}
978
979struct ta_ops libpthread_db_ops = {
980 .to_init = pt_init,
981 .to_ta_clear_event = pt_ta_clear_event,
982 .to_ta_delete = pt_ta_delete,
983 .to_ta_event_addr = pt_ta_event_addr,

--- 24 unchanged lines hidden ---