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, ®s); --- 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, ®s); --- 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 --- |