1 /* Low level interface for debugging UnixWare user-mode threads for 2 GDB, the GNU debugger. 3 4 Copyright 1999, 2000, 2001 Free Software Foundation, Inc. 5 Written by Nick Duffek <nsd@cygnus.com>. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 59 Temple Place - Suite 330, 22 Boston, MA 02111-1307, USA. */ 23 24 25 /* Like many systems, UnixWare implements two classes of threads: 26 kernel-mode threads, which are scheduled by the kernel; and 27 user-mode threads, which are scheduled by a library. UnixWare 28 calls these two classes lightweight processes (LWPs) and threads, 29 respectively. 30 31 This module deals with user-mode threads. It calls procfs_ops 32 functions to deal with LWPs and processes and core_ops functions to 33 deal with core files. 34 35 As of this writing, the user-mode thread debugging interface is not 36 documented beyond the comments in <thread.h>. The following 37 description has been gleaned from experience and from information 38 provided by SCO. 39 40 libthread.so, against which all UnixWare user-mode thread programs 41 link, provides a global thread_debug structure named _thr_debug. 42 It has three fields: 43 44 (1) thr_map is a pointer to a pointer to an element of a 45 thread_map ring. A thread_map contains a single thread's id 46 number, state, LWP pointer, recent register state, and other 47 useful information. 48 49 (2) thr_brk is a pointer to a stub function that libthread.so 50 calls when it changes a thread's state, e.g. by creating it, 51 switching it to an LWP, or causing it to exit. 52 53 (3) thr_debug_on controls whether libthread.so calls thr_brk(). 54 55 Debuggers are able to track thread activity by setting a private 56 breakpoint on thr_brk() and setting thr_debug_on to 1. 57 58 thr_brk() receives two arguments: 59 60 (1) a pointer to a thread_map describing the thread being 61 changed; and 62 63 (2) an enum thread_change specifying one of the following 64 changes: 65 66 invalid unknown 67 thread_create thread has just been created 68 thread_exit thread has just exited 69 switch_begin thread will be switched to an LWP 70 switch_complete thread has been switched to an LWP 71 cancel_complete thread wasn't switched to an LWP 72 thread_suspend thread has been thr_suspend()ed 73 thread_suspend_pending thread will be thr_suspend()ed 74 thread_continue thread has been thr_continue()d 75 76 The thread_map argument to thr_brk() is NULL under the following 77 circumstances: 78 79 - The main thread is being acted upon. The main thread always 80 has id 1, so its thread_map is easy to find by scanning through 81 _thr_debug.thr_map. 82 83 - A "switch_complete" change is occurring, which means that the 84 thread specified in the most recent "switch_begin" change has 85 moved to an LWP. 86 87 - A "cancel_complete" change is occurring, which means that the 88 thread specified in the most recent "switch_begin" change has 89 not moved to an LWP after all. 90 91 - A spurious "switch_begin" change is occurring after a 92 "thread_exit" change. 93 94 Between switch_begin and switch_complete or cancel_complete, the 95 affected thread's LWP pointer is not reliable. It is possible that 96 other parts of the thread's thread_map are also unreliable during 97 that time. */ 98 99 100 #include "defs.h" 101 #include "gdbthread.h" 102 #include "target.h" 103 #include "inferior.h" 104 #include "regcache.h" 105 #include <fcntl.h> 106 107 /* <thread.h> includes <sys/priocntl.h>, which requires boolean_t from 108 <sys/types.h>, which doesn't typedef boolean_t with gcc. */ 109 110 #define boolean_t int 111 #include <thread.h> 112 #undef boolean_t 113 114 #include <synch.h> /* for UnixWare 2.x */ 115 116 /* Prototypes for supply_gregset etc. */ 117 #include "gregset.h" 118 119 /* Offset from SP to first arg on stack at first instruction of a 120 function. We provide a default here that's right for most, if not 121 all, targets that use this file. */ 122 123 #ifndef SP_ARG0 124 #define SP_ARG0 (1 * 4) 125 #endif 126 127 /* Whether to emit debugging output. */ 128 129 #define DEBUG 0 130 131 /* Default debugging output file, overridden by envvar UWTHR_DEBUG. */ 132 133 #define DEBUG_FILE "/dev/tty" 134 135 /* #if DEBUG, write string S to the debugging output channel. */ 136 137 #if !DEBUG 138 # define DBG(fmt_and_args) 139 # define DBG2(fmt_and_args) 140 #else 141 # define DBG(fmt_and_args) dbg fmt_and_args 142 # define DBG2(fmt_and_args) 143 #endif 144 145 /* Back end to CALL_BASE() and TRY_BASE(): evaluate CALL, then convert 146 inferior_ptid to a composite thread/process id. */ 147 148 #define CALL_BASE_1(call) \ 149 do { \ 150 DBG2(("CALL_BASE(" #call ")")); \ 151 call; \ 152 do_cleanups (infpid_cleanup); \ 153 } while (0) 154 155 /* If inferior_ptid can be converted to a composite lwp/process id, do so, 156 evaluate base_ops function CALL, and then convert inferior_ptid back to a 157 composite thread/process id. 158 159 Otherwise, issue an error message and return nonlocally. */ 160 161 #define CALL_BASE(call) \ 162 do { \ 163 if (!lwp_infpid ()) \ 164 error ("uw-thread: no lwp"); \ 165 CALL_BASE_1 (call); \ 166 } while (0) 167 168 /* Like CALL_BASE(), but instead of returning nonlocally on error, set 169 *CALLED to whether the inferior_ptid conversion was successful. */ 170 171 #define TRY_BASE(call, called) \ 172 do { \ 173 if ((*(called) = lwp_infpid ())) \ 174 CALL_BASE_1 (call); \ 175 } while (0) 176 177 /* Information passed by thread_iter() to its callback parameter. */ 178 179 typedef struct { 180 struct thread_map map; 181 __lwp_desc_t lwp; 182 CORE_ADDR mapp; 183 } iter_t; 184 185 /* Private thread data for the thread_info struct. */ 186 187 struct private_thread_info { 188 int stable; /* 0 if libthread.so is modifying thread map */ 189 int thrid; /* thread id assigned by libthread.so */ 190 int lwpid; /* thread's lwp if .stable, 0 means no lwp */ 191 CORE_ADDR mapp; /* address of thread's map structure */ 192 }; 193 194 195 /* procfs.c's target-specific operations. */ 196 extern struct target_ops procfs_ops; 197 198 /* Flag to prevent procfs.c from starting inferior processes. */ 199 extern int procfs_suppress_run; 200 201 /* This module's target-specific operations. */ 202 static struct target_ops uw_thread_ops; 203 204 /* Copy of the target over which uw_thread_ops is pushed. This is 205 more convenient than a pointer to procfs_ops or core_ops, because 206 they lack current_target's default callbacks. */ 207 static struct target_ops base_ops; 208 209 /* Saved pointer to previous owner of 210 deprecated_target_new_objfile_hook. */ 211 static void (*target_new_objfile_chain)(struct objfile *); 212 213 /* Whether we are debugging a user-space thread program. This isn't 214 set until after libthread.so is loaded by the program being 215 debugged. 216 217 Except for module one-time intialization and where otherwise 218 documented, no functions in this module get called when 219 !uw_thread_active. */ 220 static int uw_thread_active; 221 222 /* For efficiency, cache the addresses of libthread.so's _thr_debug 223 structure, its thr_brk stub function, and the main thread's map. */ 224 static CORE_ADDR thr_debug_addr; 225 static CORE_ADDR thr_brk_addr; 226 static CORE_ADDR thr_map_main; 227 228 /* Remember the thread most recently marked as switching. Necessary because 229 libthread.so passes null map when calling stub with tc_*_complete. */ 230 static struct thread_info *switchto_thread; 231 232 /* Cleanup chain for safely restoring inferior_ptid after CALL_BASE. */ 233 static struct cleanup *infpid_cleanup; 234 235 236 #if DEBUG 237 /* Helper function for DBG() macro: if printf-style FMT is non-null, format it 238 with args and display the result on the debugging output channel. */ 239 240 static void 241 dbg (char *fmt, ...) 242 { 243 static int fd = -1, len; 244 va_list args; 245 char buf[1024]; 246 char *path; 247 248 if (!fmt) 249 return; 250 251 if (fd < 0) 252 { 253 path = getenv ("UWTHR_DEBUG"); 254 if (!path) 255 path = DEBUG_FILE; 256 if ((fd = open (path, O_WRONLY | O_CREAT | O_TRUNC, 0664)) < 0) 257 error ("can't open %s\n", path); 258 } 259 260 va_start (args, fmt); 261 vsprintf (buf, fmt, args); 262 va_end (args); 263 264 len = strlen (buf); 265 buf[len] = '\n'; 266 (void)write (fd, buf, len + 1); 267 } 268 269 #if 0 270 /* Return a string representing composite PID's components. */ 271 272 static char * 273 dbgpid (ptid_t ptid) 274 { 275 static char *buf, buf1[80], buf2[80]; 276 if (!buf || buf == buf2) 277 buf = buf1; 278 else 279 buf = buf2; 280 281 if (PIDGET (ptid) <= 0) 282 sprintf (buf, "%d", PIDGET (ptid)); 283 else 284 sprintf (buf, "%s %ld/%d", ISTID (pid) ? "thr" : "lwp", 285 TIDGET (pid), PIDGET (pid)); 286 287 return buf; 288 } 289 290 /* Return a string representing thread state CHANGE. */ 291 292 static char * 293 dbgchange (enum thread_change change) 294 { 295 switch (change) { 296 case tc_invalid: return "invalid"; 297 case tc_thread_create: return "thread_create"; 298 case tc_thread_exit: return "thread_exit"; 299 case tc_switch_begin: return "switch_begin"; 300 case tc_switch_complete: return "switch_complete"; 301 case tc_cancel_complete: return "cancel_complete"; 302 case tc_thread_suspend: return "thread_suspend"; 303 case tc_thread_suspend_pending: return "thread_suspend_pending"; 304 case tc_thread_continue: return "thread_continue"; 305 default: return "unknown"; 306 } 307 } 308 309 /* Return a string representing thread STATE. */ 310 311 static char * 312 dbgstate (int state) 313 { 314 switch (state) { 315 case TS_ONPROC: return "running"; 316 case TS_SLEEP: return "sleeping"; 317 case TS_RUNNABLE: return "runnable"; 318 case TS_ZOMBIE: return "zombie"; 319 case TS_SUSPENDED: return "suspended"; 320 #ifdef TS_FORK 321 case TS_FORK: return "forking"; 322 #endif 323 default: return "confused"; 324 } 325 } 326 #endif /* 0 */ 327 #endif /* DEBUG */ 328 329 330 /* Read the contents of _thr_debug into *DEBUGP. Return success. */ 331 332 static int 333 read_thr_debug (struct thread_debug *debugp) 334 { 335 return base_ops.deprecated_xfer_memory (thr_debug_addr, (char *)debugp, 336 sizeof (*debugp), 0, NULL, 337 &base_ops); 338 } 339 340 /* Read into MAP the contents of the thread map at inferior process address 341 MAPP. Return success. */ 342 343 static int 344 read_map (CORE_ADDR mapp, struct thread_map *map) 345 { 346 return base_ops.deprecated_xfer_memory ((CORE_ADDR)THR_MAP (mapp), 347 (char *)map, sizeof (*map), 348 0, NULL, &base_ops); 349 } 350 351 /* Read into LWP the contents of the lwp decriptor at inferior process address 352 LWPP. Return success. */ 353 354 static int 355 read_lwp (CORE_ADDR lwpp, __lwp_desc_t *lwp) 356 { 357 return base_ops.deprecated_xfer_memory (lwpp, (char *)lwp, 358 sizeof (*lwp), 0, NULL, &base_ops); 359 } 360 361 /* Iterate through all user threads, applying FUNC(<map>, <lwp>, DATA) until 362 (a) FUNC returns nonzero, 363 (b) FUNC has been applied to all threads, or 364 (c) an error occurs, 365 where <map> is the thread's struct thread_map and <lwp> if non-null is the 366 thread's current __lwp_desc_t. 367 368 If a call to FUNC returns nonzero, return that value; otherwise, return 0. */ 369 370 static int 371 thread_iter (int (*func)(iter_t *, void *), void *data) 372 { 373 struct thread_debug debug; 374 CORE_ADDR first, mapp; 375 iter_t iter; 376 int ret; 377 378 if (!read_thr_debug (&debug)) 379 return 0; 380 if (!base_ops.deprecated_xfer_memory ((CORE_ADDR)debug.thr_map, 381 (char *)&mapp, sizeof (mapp), 0, NULL, 382 &base_ops)) 383 return 0; 384 if (!mapp) 385 return 0; 386 387 for (first = mapp;;) 388 { 389 if (!read_map (mapp, &iter.map)) 390 return 0; 391 392 if (iter.map.thr_lwpp) 393 if (!read_lwp ((CORE_ADDR)iter.map.thr_lwpp, &iter.lwp)) 394 return 0; 395 396 iter.mapp = mapp; 397 if ((ret = func (&iter, data))) 398 return ret; 399 400 mapp = (CORE_ADDR)iter.map.thr_next; 401 if (mapp == first) 402 return 0; 403 } 404 } 405 406 /* Deactivate user-mode thread support. */ 407 408 static void 409 deactivate_uw_thread (void) 410 { 411 remove_thread_event_breakpoints (); 412 uw_thread_active = 0; 413 unpush_target (&uw_thread_ops); 414 } 415 416 /* Return the composite lwp/process id corresponding to composite 417 id PID. If PID is a thread with no lwp, return 0. */ 418 419 static ptid_t 420 thr_to_lwp (ptid_t ptid) 421 { 422 struct thread_info *info; 423 ptid_t lid; 424 425 if (!ISTID (ptid)) 426 lid = ptid; 427 else if (!(info = find_thread_pid (ptid))) 428 lid = null_ptid; 429 else if (!info->private->lwpid) 430 lid = null_ptid; 431 else 432 lid = MKLID (PIDGET (ptid), info->private->lwpid); 433 434 DBG2((" thr_to_lwp(%s) = %s", dbgpid (pid), dbgpid (lid))); 435 return lid; 436 } 437 438 /* find_thread_lwp() callback: return whether TP describes a thread 439 associated with lwp id DATA. */ 440 441 static int 442 find_thread_lwp_callback (struct thread_info *tp, void *data) 443 { 444 int lwpid = (int)data; 445 446 if (!ISTID (tp->ptid)) 447 return 0; 448 if (!tp->private->stable) 449 return 0; 450 if (lwpid != tp->private->lwpid) 451 return 0; 452 453 /* match */ 454 return 1; 455 } 456 457 /* If a thread is associated with lwp id LWPID, return the corresponding 458 member of the global thread list; otherwise, return null. */ 459 460 static struct thread_info * 461 find_thread_lwp (int lwpid) 462 { 463 return iterate_over_threads (find_thread_lwp_callback, (void *)lwpid); 464 } 465 466 /* Return the composite thread/process id corresponding to composite 467 id PID. If PID is an lwp with no thread, return PID. */ 468 469 static ptid_t 470 lwp_to_thr (ptid_t ptid) 471 { 472 struct thread_info *info; 473 int lwpid; 474 ptid_t tid = ptid; 475 476 if (ISTID (ptid)) 477 goto done; 478 if (!(lwpid = LIDGET (ptid))) 479 goto done; 480 if (!(info = find_thread_lwp (lwpid))) 481 goto done; 482 tid = MKTID (PIDGET (ptid), info->private->thrid); 483 484 done: 485 DBG2((ISTID (tid) ? NULL : "lwp_to_thr: no thr for %s", dbgpid (ptid))); 486 return tid; 487 } 488 489 /* do_cleanups() callback: convert inferior_ptid to a composite 490 thread/process id after having made a procfs call. */ 491 492 static void 493 thr_infpid (void *unused) 494 { 495 ptid_t ptid = lwp_to_thr (inferior_ptid); 496 DBG2((" inferior_ptid from procfs: %s => %s", 497 dbgpid (inferior_ptid), dbgpid (ptid))); 498 inferior_ptid = ptid; 499 } 500 501 /* If possible, convert inferior_ptid to a composite lwp/process id in 502 preparation for making a procfs call. Return success. */ 503 504 static int 505 lwp_infpid (void) 506 { 507 ptid_t ptid = thr_to_lwp (inferior_ptid); 508 DBG2((" inferior_ptid to procfs: %s => %s", 509 dbgpid (inferior_ptid), dbgpid (ptid))); 510 511 if (ptid_equal (ptid, null_ptid)) 512 return 0; 513 514 inferior_ptid = ptid; 515 infpid_cleanup = make_cleanup (thr_infpid, NULL); 516 return 1; 517 } 518 519 /* Add to the global thread list a new user-mode thread with system id THRID, 520 lwp id LWPID, map address MAPP, and composite thread/process PID. */ 521 522 static void 523 add_thread_uw (int thrid, int lwpid, CORE_ADDR mapp, ptid_t ptid) 524 { 525 struct thread_info *newthread; 526 527 if ((newthread = add_thread (ptid)) == NULL) 528 error ("failed to create new thread structure"); 529 530 newthread->private = xmalloc (sizeof (struct private_thread_info)); 531 newthread->private->stable = 1; 532 newthread->private->thrid = thrid; 533 newthread->private->lwpid = lwpid; 534 newthread->private->mapp = mapp; 535 536 if (target_has_execution) 537 printf_unfiltered ("[New %s]\n", target_pid_to_str (ptid)); 538 } 539 540 /* notice_threads() and find_main() callback: if the thread list doesn't 541 already contain the thread described by ITER, add it if it's the main 542 thread or if !DATA. */ 543 544 static int 545 notice_thread (iter_t *iter, void *data) 546 { 547 int thrid = iter->map.thr_tid; 548 int lwpid = !iter->map.thr_lwpp ? 0 : iter->lwp.lwp_id; 549 ptid_t ptid = MKTID (PIDGET (inferior_ptid), thrid); 550 551 if (!find_thread_pid (ptid) && (!data || thrid == 1)) 552 add_thread_uw (thrid, lwpid, iter->mapp, ptid); 553 554 return 0; 555 } 556 557 /* Add to the thread list any threads it doesn't already contain. */ 558 559 static void 560 notice_threads (void) 561 { 562 thread_iter (notice_thread, NULL); 563 } 564 565 /* Return the address of the main thread's map. On error, return 0. */ 566 567 static CORE_ADDR 568 find_main (void) 569 { 570 if (!thr_map_main) 571 { 572 struct thread_info *info; 573 thread_iter (notice_thread, (void *)1); 574 if ((info = find_thread_pid (MKTID (PIDGET (inferior_ptid), 1)))) 575 thr_map_main = info->private->mapp; 576 } 577 return thr_map_main; 578 } 579 580 /* Attach to process specified by ARGS, then initialize for debugging it 581 and wait for the trace-trap that results from attaching. 582 583 This function only gets called with uw_thread_active == 0. */ 584 585 static void 586 uw_thread_attach (char *args, int from_tty) 587 { 588 procfs_ops.to_attach (args, from_tty); 589 if (uw_thread_active) 590 thr_infpid (NULL); 591 } 592 593 /* Detach from the process attached to by uw_thread_attach(). */ 594 595 static void 596 uw_thread_detach (char *args, int from_tty) 597 { 598 deactivate_uw_thread (); 599 base_ops.to_detach (args, from_tty); 600 } 601 602 /* Tell the inferior process to continue running thread PID if >= 0 603 and all threads otherwise. */ 604 605 static void 606 uw_thread_resume (ptid_t ptid, int step, enum target_signal signo) 607 { 608 if (PIDGET (ptid) > 0) 609 { 610 ptid = thr_to_lwp (ptid); 611 if (ptid_equal (ptid, null_ptid)) 612 ptid = pid_to_ptid (-1); 613 } 614 615 CALL_BASE (base_ops.to_resume (ptid, step, signo)); 616 } 617 618 /* If the trap we just received from lwp PID was due to a breakpoint 619 on the libthread.so debugging stub, update this module's state 620 accordingly. */ 621 622 static void 623 libthread_stub (ptid_t ptid) 624 { 625 CORE_ADDR sp, mapp, mapp_main; 626 enum thread_change change; 627 struct thread_map map; 628 __lwp_desc_t lwp; 629 int lwpid; 630 ptid_t tid = null_ptid; 631 struct thread_info *info; 632 633 /* Check for stub breakpoint. */ 634 if (read_pc_pid (ptid) - DECR_PC_AFTER_BREAK != thr_brk_addr) 635 return; 636 637 /* Retrieve stub args. */ 638 sp = read_register_pid (SP_REGNUM, ptid); 639 if (!base_ops.deprecated_xfer_memory (sp + SP_ARG0, (char *)&mapp, 640 sizeof (mapp), 0, NULL, &base_ops)) 641 goto err; 642 if (!base_ops.deprecated_xfer_memory (sp + SP_ARG0 + sizeof (mapp), 643 (char *)&change, sizeof (change), 0, 644 NULL, &base_ops)) 645 goto err; 646 647 /* create_inferior() may not have finished yet, so notice the main 648 thread to ensure that it's displayed first by add_thread(). */ 649 mapp_main = find_main (); 650 651 /* Notice thread creation, deletion, or stability change. */ 652 switch (change) { 653 case tc_switch_begin: 654 if (!mapp) /* usually means main thread */ 655 mapp = mapp_main; 656 /* fall through */ 657 658 case tc_thread_create: 659 case tc_thread_exit: 660 if (!mapp) 661 break; 662 if (!read_map (mapp, &map)) 663 goto err; 664 tid = MKTID (PIDGET (ptid), map.thr_tid); 665 666 switch (change) { 667 case tc_thread_create: /* new thread */ 668 if (!map.thr_lwpp) 669 lwpid = 0; 670 else if (!read_lwp ((CORE_ADDR)map.thr_lwpp, &lwp)) 671 goto err; 672 else 673 lwpid = lwp.lwp_id; 674 add_thread_uw (map.thr_tid, lwpid, mapp, tid); 675 break; 676 677 case tc_thread_exit: /* thread has exited */ 678 printf_unfiltered ("[Exited %s]\n", target_pid_to_str (tid)); 679 delete_thread (tid); 680 if (ptid_equal (tid, inferior_ptid)) 681 inferior_ptid = ptid; 682 break; 683 684 case tc_switch_begin: /* lwp is switching threads */ 685 if (switchto_thread) 686 goto err; 687 if (!(switchto_thread = find_thread_pid (tid))) 688 goto err; 689 switchto_thread->private->stable = 0; 690 break; 691 692 default: 693 break; 694 } 695 break; 696 697 case tc_switch_complete: /* lwp has switched threads */ 698 case tc_cancel_complete: /* lwp didn't switch threads */ 699 if (!switchto_thread) 700 goto err; 701 702 if (change == tc_switch_complete) 703 { 704 /* If switchto_thread is the main thread, then (a) the corresponding 705 tc_switch_begin probably received a null map argument and therefore 706 (b) it may have been a spurious switch following a tc_thread_exit. 707 708 Therefore, explicitly query the thread's lwp before caching it in 709 its thread list entry. */ 710 711 if (!read_map (switchto_thread->private->mapp, &map)) 712 goto err; 713 if (map.thr_lwpp) 714 { 715 if (!read_lwp ((CORE_ADDR)map.thr_lwpp, &lwp)) 716 goto err; 717 if ((info = find_thread_lwp (lwp.lwp_id))) 718 info->private->lwpid = 0; 719 switchto_thread->private->lwpid = lwp.lwp_id; 720 } 721 } 722 723 switchto_thread->private->stable = 1; 724 switchto_thread = NULL; 725 break; 726 727 case tc_invalid: 728 case tc_thread_suspend: 729 case tc_thread_suspend_pending: 730 case tc_thread_continue: 731 err: 732 DBG(("unexpected condition in libthread_stub()")); 733 break; 734 } 735 736 DBG2(("libthread_stub(%s): %s %s %s", dbgpid (pid), dbgpid (tid), 737 dbgchange (change), tid ? dbgstate (map.thr_state) : "")); 738 } 739 740 /* Wait for thread/lwp/process ID if >= 0 or for any thread otherwise. */ 741 742 static ptid_t 743 uw_thread_wait (ptid_t ptid, struct target_waitstatus *status) 744 { 745 if (PIDGET (ptid) > 0) 746 ptid = thr_to_lwp (ptid); 747 if (PIDGET (ptid) <= 0) 748 ptid = pid_to_ptid (-1); 749 750 CALL_BASE (ptid = base_ops.to_wait (ptid, status)); 751 752 if (status->kind == TARGET_WAITKIND_STOPPED && 753 status->value.sig == TARGET_SIGNAL_TRAP) 754 libthread_stub (ptid); 755 756 return lwp_to_thr (ptid); 757 } 758 759 /* Tell gdb about the registers in the thread/lwp/process specified by 760 inferior_ptid. */ 761 762 static void 763 uw_thread_fetch_registers (int regno) 764 { 765 int called; 766 struct thread_info *info; 767 struct thread_map map; 768 769 TRY_BASE (base_ops.to_fetch_registers (regno), &called); 770 if (called) 771 return; 772 773 if (!(info = find_thread_pid (inferior_ptid))) 774 return; 775 if (!read_map (info->private->mapp, &map)) 776 return; 777 778 supply_gregset (&map.thr_ucontext.uc_mcontext.gregs); 779 supply_fpregset (&map.thr_ucontext.uc_mcontext.fpregs); 780 } 781 782 /* Store gdb's current view of the register set into the thread/lwp/process 783 specified by inferior_ptid. */ 784 785 static void 786 uw_thread_store_registers (int regno) 787 { 788 CALL_BASE (base_ops.to_store_registers (regno)); 789 } 790 791 /* Prepare to modify the registers array. */ 792 793 static void 794 uw_thread_prepare_to_store (void) 795 { 796 CALL_BASE (base_ops.to_prepare_to_store ()); 797 } 798 799 /* Fork an inferior process and start debugging it. 800 801 This function only gets called with uw_thread_active == 0. */ 802 803 static void 804 uw_thread_create_inferior (char *exec_file, char *allargs, char **env, 805 int from_tty) 806 { 807 if (uw_thread_active) 808 deactivate_uw_thread (); 809 810 procfs_ops.to_create_inferior (exec_file, allargs, env, from_tty); 811 if (uw_thread_active) 812 { 813 find_main (); 814 thr_infpid (NULL); 815 } 816 } 817 818 /* Kill and forget about the inferior process. */ 819 820 static void 821 uw_thread_kill (void) 822 { 823 base_ops.to_kill (); 824 } 825 826 /* Clean up after the inferior exits. */ 827 828 static void 829 uw_thread_mourn_inferior (void) 830 { 831 deactivate_uw_thread (); 832 base_ops.to_mourn_inferior (); 833 } 834 835 /* Return whether this module can attach to and run processes. 836 837 This function only gets called with uw_thread_active == 0. */ 838 839 static int 840 uw_thread_can_run (void) 841 { 842 return procfs_suppress_run; 843 } 844 845 /* Return whether thread PID is still valid. */ 846 847 static int 848 uw_thread_alive (ptid_t ptid) 849 { 850 if (!ISTID (ptid)) 851 return base_ops.to_thread_alive (ptid); 852 853 /* If it's in the thread list, it's valid, because otherwise 854 libthread_stub() would have deleted it. */ 855 return in_thread_list (ptid); 856 } 857 858 /* Add to the thread list any threads and lwps it doesn't already contain. */ 859 860 static void 861 uw_thread_find_new_threads (void) 862 { 863 CALL_BASE (if (base_ops.to_find_new_threads) 864 base_ops.to_find_new_threads ()); 865 notice_threads (); 866 } 867 868 /* Return a string for pretty-printing PID in "info threads" output. 869 This may be called by either procfs.c or by generic gdb. */ 870 871 static char * 872 uw_thread_pid_to_str (ptid_t ptid) 873 { 874 #define FMT "Thread %ld" 875 static char buf[sizeof (FMT) + 3 * sizeof (long)]; 876 877 if (!ISTID (ptid)) 878 /* core_ops says "process foo", so call procfs_ops explicitly. */ 879 return procfs_ops.to_pid_to_str (ptid); 880 881 sprintf (buf, FMT, TIDGET (ptid)); 882 #undef FMT 883 return buf; 884 } 885 886 /* Return a string displaying INFO state information in "info threads" 887 output. */ 888 889 static char * 890 uw_extra_thread_info (struct thread_info *info) 891 { 892 static char buf[80]; 893 struct thread_map map; 894 __lwp_desc_t lwp; 895 int lwpid; 896 char *name; 897 898 if (!ISTID (info->ptid)) 899 return NULL; 900 901 if (!info->private->stable) 902 return "switching"; 903 904 if (!read_map (info->private->mapp, &map)) 905 return NULL; 906 907 if (!map.thr_lwpp || !read_lwp ((CORE_ADDR)map.thr_lwpp, &lwp)) 908 lwpid = 0; 909 else 910 lwpid = lwp.lwp_id; 911 912 switch (map.thr_state) { 913 case TS_ONPROC: name = "running"; break; 914 case TS_SLEEP: name = "sleeping"; break; 915 case TS_RUNNABLE: name = "runnable"; break; 916 case TS_ZOMBIE: name = "zombie"; break; 917 case TS_SUSPENDED: name = "suspended"; break; 918 #ifdef TS_FORK 919 case TS_FORK: name = "forking"; break; 920 #endif 921 default: name = "confused"; break; 922 } 923 924 if (!lwpid) 925 return name; 926 927 sprintf (buf, "%s, LWP %d", name, lwpid); 928 return buf; 929 } 930 931 /* Check whether libthread.so has just been loaded, and if so, try to 932 initialize user-space thread debugging support. 933 934 libthread.so loading happens while (a) an inferior process is being 935 started by procfs and (b) a core image is being loaded. 936 937 This function often gets called with uw_thread_active == 0. */ 938 939 static void 940 libthread_init (void) 941 { 942 struct minimal_symbol *ms; 943 struct thread_debug debug; 944 CORE_ADDR onp; 945 struct breakpoint *b; 946 int one = 1; 947 948 /* Don't initialize twice. */ 949 if (uw_thread_active) 950 return; 951 952 /* Check whether libthread.so has been loaded. */ 953 if (!(ms = lookup_minimal_symbol ("_thr_debug", NULL, NULL))) 954 return; 955 956 /* Cache _thr_debug's address. */ 957 if (!(thr_debug_addr = SYMBOL_VALUE_ADDRESS (ms))) 958 return; 959 960 /* Initialize base_ops.deprecated_xfer_memory(). */ 961 base_ops = current_target; 962 963 /* Load _thr_debug's current contents. */ 964 if (!read_thr_debug (&debug)) 965 return; 966 967 /* User code (e.g. my test programs) may dereference _thr_debug, 968 making it availble to GDB before shared libs are loaded. */ 969 if (!debug.thr_map) 970 return; 971 972 /* libthread.so has been loaded, and the current_target should now 973 reflect core_ops or procfs_ops. */ 974 push_target (&uw_thread_ops); /* must precede notice_threads() */ 975 uw_thread_active = 1; 976 977 if (!target_has_execution) 978 979 /* Locate threads in core file. */ 980 notice_threads (); 981 982 else 983 { 984 /* Set a breakpoint on the stub function provided by libthread.so. */ 985 thr_brk_addr = (CORE_ADDR)debug.thr_brk; 986 if (!(b = create_thread_event_breakpoint (thr_brk_addr))) 987 goto err; 988 989 /* Activate the stub function. */ 990 onp = (CORE_ADDR)&((struct thread_debug *)thr_debug_addr)->thr_debug_on; 991 if (!base_ops.deprecated_xfer_memory ((CORE_ADDR)onp, (char *)&one, 992 sizeof (one), 1, NULL, &base_ops)) 993 { 994 delete_breakpoint (b); 995 goto err; 996 } 997 998 /* Prepare for finding the main thread, which doesn't yet exist. */ 999 thr_map_main = 0; 1000 } 1001 1002 return; 1003 1004 err: 1005 warning ("uw-thread: unable to initialize user-mode thread debugging\n"); 1006 deactivate_uw_thread (); 1007 } 1008 1009 /* deprecated_target_new_objfile_hook callback. 1010 1011 If OBJFILE is non-null, check whether libthread.so was just loaded, 1012 and if so, prepare for user-mode thread debugging. 1013 1014 If OBJFILE is null, libthread.so has gone away, so stop debugging 1015 user-mode threads. 1016 1017 This function often gets called with uw_thread_active == 0. */ 1018 1019 static void 1020 uw_thread_new_objfile (struct objfile *objfile) 1021 { 1022 if (objfile) 1023 libthread_init (); 1024 1025 else if (uw_thread_active) 1026 deactivate_uw_thread (); 1027 1028 if (target_new_objfile_chain) 1029 target_new_objfile_chain (objfile); 1030 } 1031 1032 /* Initialize uw_thread_ops. */ 1033 1034 static void 1035 init_uw_thread_ops (void) 1036 { 1037 uw_thread_ops.to_shortname = "unixware-threads"; 1038 uw_thread_ops.to_longname = "UnixWare threads and pthread."; 1039 uw_thread_ops.to_doc = "UnixWare threads and pthread support."; 1040 uw_thread_ops.to_attach = uw_thread_attach; 1041 uw_thread_ops.to_detach = uw_thread_detach; 1042 uw_thread_ops.to_resume = uw_thread_resume; 1043 uw_thread_ops.to_wait = uw_thread_wait; 1044 uw_thread_ops.to_fetch_registers = uw_thread_fetch_registers; 1045 uw_thread_ops.to_store_registers = uw_thread_store_registers; 1046 uw_thread_ops.to_prepare_to_store = uw_thread_prepare_to_store; 1047 uw_thread_ops.to_create_inferior = uw_thread_create_inferior; 1048 uw_thread_ops.to_kill = uw_thread_kill; 1049 uw_thread_ops.to_mourn_inferior = uw_thread_mourn_inferior; 1050 uw_thread_ops.to_can_run = uw_thread_can_run; 1051 uw_thread_ops.to_thread_alive = uw_thread_alive; 1052 uw_thread_ops.to_find_new_threads = uw_thread_find_new_threads; 1053 uw_thread_ops.to_pid_to_str = uw_thread_pid_to_str; 1054 uw_thread_ops.to_extra_thread_info = uw_extra_thread_info; 1055 uw_thread_ops.to_stratum = thread_stratum; 1056 uw_thread_ops.to_magic = OPS_MAGIC; 1057 } 1058 1059 /* Module startup initialization function, automagically called by 1060 init.c. */ 1061 1062 void 1063 _initialize_uw_thread (void) 1064 { 1065 init_uw_thread_ops (); 1066 add_target (&uw_thread_ops); 1067 1068 procfs_suppress_run = 1; 1069 1070 /* Notice when libthread.so gets loaded. */ 1071 target_new_objfile_chain = deprecated_target_new_objfile_hook; 1072 deprecated_target_new_objfile_hook = uw_thread_new_objfile; 1073 } 1074