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) \ 149do { \ 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) \ 162do { \ 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) \ 172do { \ 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 179typedef 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 187struct 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. */ 196extern struct target_ops procfs_ops; 197 198/* Flag to prevent procfs.c from starting inferior processes. */ 199extern int procfs_suppress_run; 200 201/* This module's target-specific operations. */ 202static 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. */ 207static struct target_ops base_ops; 208 209/* Saved pointer to previous owner of target_new_objfile_hook. */ 210static void (*target_new_objfile_chain)(struct objfile *); 211 212/* Whether we are debugging a user-space thread program. This isn't 213 set until after libthread.so is loaded by the program being 214 debugged. 215 216 Except for module one-time intialization and where otherwise 217 documented, no functions in this module get called when 218 !uw_thread_active. */ 219static int uw_thread_active; 220 221/* For efficiency, cache the addresses of libthread.so's _thr_debug 222 structure, its thr_brk stub function, and the main thread's map. */ 223static CORE_ADDR thr_debug_addr; 224static CORE_ADDR thr_brk_addr; 225static CORE_ADDR thr_map_main; 226 227/* Remember the thread most recently marked as switching. Necessary because 228 libthread.so passes null map when calling stub with tc_*_complete. */ 229static struct thread_info *switchto_thread; 230 231/* Cleanup chain for safely restoring inferior_ptid after CALL_BASE. */ 232static struct cleanup *infpid_cleanup; 233 234 235#if DEBUG 236/* Helper function for DBG() macro: if printf-style FMT is non-null, format it 237 with args and display the result on the debugging output channel. */ 238 239static void 240dbg (char *fmt, ...) 241{ 242 static int fd = -1, len; 243 va_list args; 244 char buf[1024]; 245 char *path; 246 247 if (!fmt) 248 return; 249 250 if (fd < 0) 251 { 252 path = getenv ("UWTHR_DEBUG"); 253 if (!path) 254 path = DEBUG_FILE; 255 if ((fd = open (path, O_WRONLY | O_CREAT | O_TRUNC, 0664)) < 0) 256 error ("can't open %s\n", path); 257 } 258 259 va_start (args, fmt); 260 vsprintf (buf, fmt, args); 261 va_end (args); 262 263 len = strlen (buf); 264 buf[len] = '\n'; 265 (void)write (fd, buf, len + 1); 266} 267 268#if 0 269/* Return a string representing composite PID's components. */ 270 271static char * 272dbgpid (ptid_t ptid) 273{ 274 static char *buf, buf1[80], buf2[80]; 275 if (!buf || buf == buf2) 276 buf = buf1; 277 else 278 buf = buf2; 279 280 if (PIDGET (ptid) <= 0) 281 sprintf (buf, "%d", PIDGET (ptid)); 282 else 283 sprintf (buf, "%s %ld/%d", ISTID (pid) ? "thr" : "lwp", 284 TIDGET (pid), PIDGET (pid)); 285 286 return buf; 287} 288 289/* Return a string representing thread state CHANGE. */ 290 291static char * 292dbgchange (enum thread_change change) 293{ 294 switch (change) { 295 case tc_invalid: return "invalid"; 296 case tc_thread_create: return "thread_create"; 297 case tc_thread_exit: return "thread_exit"; 298 case tc_switch_begin: return "switch_begin"; 299 case tc_switch_complete: return "switch_complete"; 300 case tc_cancel_complete: return "cancel_complete"; 301 case tc_thread_suspend: return "thread_suspend"; 302 case tc_thread_suspend_pending: return "thread_suspend_pending"; 303 case tc_thread_continue: return "thread_continue"; 304 default: return "unknown"; 305 } 306} 307 308/* Return a string representing thread STATE. */ 309 310static char * 311dbgstate (int state) 312{ 313 switch (state) { 314 case TS_ONPROC: return "running"; 315 case TS_SLEEP: return "sleeping"; 316 case TS_RUNNABLE: return "runnable"; 317 case TS_ZOMBIE: return "zombie"; 318 case TS_SUSPENDED: return "suspended"; 319#ifdef TS_FORK 320 case TS_FORK: return "forking"; 321#endif 322 default: return "confused"; 323 } 324} 325#endif /* 0 */ 326#endif /* DEBUG */ 327 328 329/* Read the contents of _thr_debug into *DEBUGP. Return success. */ 330 331static int 332read_thr_debug (struct thread_debug *debugp) 333{ 334 return base_ops.to_xfer_memory (thr_debug_addr, (char *)debugp, 335 sizeof (*debugp), 0, NULL, &base_ops); 336} 337 338/* Read into MAP the contents of the thread map at inferior process address 339 MAPP. Return success. */ 340 341static int 342read_map (CORE_ADDR mapp, struct thread_map *map) 343{ 344 return base_ops.to_xfer_memory ((CORE_ADDR)THR_MAP (mapp), (char *)map, 345 sizeof (*map), 0, NULL, &base_ops); 346} 347 348/* Read into LWP the contents of the lwp decriptor at inferior process address 349 LWPP. Return success. */ 350 351static int 352read_lwp (CORE_ADDR lwpp, __lwp_desc_t *lwp) 353{ 354 return base_ops.to_xfer_memory (lwpp, (char *)lwp, 355 sizeof (*lwp), 0, NULL, &base_ops); 356} 357 358/* Iterate through all user threads, applying FUNC(<map>, <lwp>, DATA) until 359 (a) FUNC returns nonzero, 360 (b) FUNC has been applied to all threads, or 361 (c) an error occurs, 362 where <map> is the thread's struct thread_map and <lwp> if non-null is the 363 thread's current __lwp_desc_t. 364 365 If a call to FUNC returns nonzero, return that value; otherwise, return 0. */ 366 367static int 368thread_iter (int (*func)(iter_t *, void *), void *data) 369{ 370 struct thread_debug debug; 371 CORE_ADDR first, mapp; 372 iter_t iter; 373 int ret; 374 375 if (!read_thr_debug (&debug)) 376 return 0; 377 if (!base_ops.to_xfer_memory ((CORE_ADDR)debug.thr_map, (char *)&mapp, 378 sizeof (mapp), 0, NULL, &base_ops)) 379 return 0; 380 if (!mapp) 381 return 0; 382 383 for (first = mapp;;) 384 { 385 if (!read_map (mapp, &iter.map)) 386 return 0; 387 388 if (iter.map.thr_lwpp) 389 if (!read_lwp ((CORE_ADDR)iter.map.thr_lwpp, &iter.lwp)) 390 return 0; 391 392 iter.mapp = mapp; 393 if ((ret = func (&iter, data))) 394 return ret; 395 396 mapp = (CORE_ADDR)iter.map.thr_next; 397 if (mapp == first) 398 return 0; 399 } 400} 401 402/* Deactivate user-mode thread support. */ 403 404static void 405deactivate_uw_thread (void) 406{ 407 remove_thread_event_breakpoints (); 408 uw_thread_active = 0; 409 unpush_target (&uw_thread_ops); 410} 411 412/* Return the composite lwp/process id corresponding to composite 413 id PID. If PID is a thread with no lwp, return 0. */ 414 415static ptid_t 416thr_to_lwp (ptid_t ptid) 417{ 418 struct thread_info *info; 419 ptid_t lid; 420 421 if (!ISTID (ptid)) 422 lid = ptid; 423 else if (!(info = find_thread_pid (ptid))) 424 lid = null_ptid; 425 else if (!info->private->lwpid) 426 lid = null_ptid; 427 else 428 lid = MKLID (PIDGET (ptid), info->private->lwpid); 429 430 DBG2((" thr_to_lwp(%s) = %s", dbgpid (pid), dbgpid (lid))); 431 return lid; 432} 433 434/* find_thread_lwp() callback: return whether TP describes a thread 435 associated with lwp id DATA. */ 436 437static int 438find_thread_lwp_callback (struct thread_info *tp, void *data) 439{ 440 int lwpid = (int)data; 441 442 if (!ISTID (tp->ptid)) 443 return 0; 444 if (!tp->private->stable) 445 return 0; 446 if (lwpid != tp->private->lwpid) 447 return 0; 448 449 /* match */ 450 return 1; 451} 452 453/* If a thread is associated with lwp id LWPID, return the corresponding 454 member of the global thread list; otherwise, return null. */ 455 456static struct thread_info * 457find_thread_lwp (int lwpid) 458{ 459 return iterate_over_threads (find_thread_lwp_callback, (void *)lwpid); 460} 461 462/* Return the composite thread/process id corresponding to composite 463 id PID. If PID is an lwp with no thread, return PID. */ 464 465static ptid_t 466lwp_to_thr (ptid_t ptid) 467{ 468 struct thread_info *info; 469 int lwpid; 470 ptid_t tid = ptid; 471 472 if (ISTID (ptid)) 473 goto done; 474 if (!(lwpid = LIDGET (ptid))) 475 goto done; 476 if (!(info = find_thread_lwp (lwpid))) 477 goto done; 478 tid = MKTID (PIDGET (ptid), info->private->thrid); 479 480 done: 481 DBG2((ISTID (tid) ? NULL : "lwp_to_thr: no thr for %s", dbgpid (ptid))); 482 return tid; 483} 484 485/* do_cleanups() callback: convert inferior_ptid to a composite 486 thread/process id after having made a procfs call. */ 487 488static void 489thr_infpid (void *unused) 490{ 491 ptid_t ptid = lwp_to_thr (inferior_ptid); 492 DBG2((" inferior_ptid from procfs: %s => %s", 493 dbgpid (inferior_ptid), dbgpid (ptid))); 494 inferior_ptid = ptid; 495} 496 497/* If possible, convert inferior_ptid to a composite lwp/process id in 498 preparation for making a procfs call. Return success. */ 499 500static int 501lwp_infpid (void) 502{ 503 ptid_t ptid = thr_to_lwp (inferior_ptid); 504 DBG2((" inferior_ptid to procfs: %s => %s", 505 dbgpid (inferior_ptid), dbgpid (ptid))); 506 507 if (ptid_equal (ptid, null_ptid)) 508 return 0; 509 510 inferior_ptid = ptid; 511 infpid_cleanup = make_cleanup (thr_infpid, NULL); 512 return 1; 513} 514 515/* Add to the global thread list a new user-mode thread with system id THRID, 516 lwp id LWPID, map address MAPP, and composite thread/process PID. */ 517 518static void 519add_thread_uw (int thrid, int lwpid, CORE_ADDR mapp, ptid_t ptid) 520{ 521 struct thread_info *newthread; 522 523 if ((newthread = add_thread (ptid)) == NULL) 524 error ("failed to create new thread structure"); 525 526 newthread->private = xmalloc (sizeof (struct private_thread_info)); 527 newthread->private->stable = 1; 528 newthread->private->thrid = thrid; 529 newthread->private->lwpid = lwpid; 530 newthread->private->mapp = mapp; 531 532 if (target_has_execution) 533 printf_unfiltered ("[New %s]\n", target_pid_to_str (ptid)); 534} 535 536/* notice_threads() and find_main() callback: if the thread list doesn't 537 already contain the thread described by ITER, add it if it's the main 538 thread or if !DATA. */ 539 540static int 541notice_thread (iter_t *iter, void *data) 542{ 543 int thrid = iter->map.thr_tid; 544 int lwpid = !iter->map.thr_lwpp ? 0 : iter->lwp.lwp_id; 545 ptid_t ptid = MKTID (PIDGET (inferior_ptid), thrid); 546 547 if (!find_thread_pid (ptid) && (!data || thrid == 1)) 548 add_thread_uw (thrid, lwpid, iter->mapp, ptid); 549 550 return 0; 551} 552 553/* Add to the thread list any threads it doesn't already contain. */ 554 555static void 556notice_threads (void) 557{ 558 thread_iter (notice_thread, NULL); 559} 560 561/* Return the address of the main thread's map. On error, return 0. */ 562 563static CORE_ADDR 564find_main (void) 565{ 566 if (!thr_map_main) 567 { 568 struct thread_info *info; 569 thread_iter (notice_thread, (void *)1); 570 if ((info = find_thread_pid (MKTID (PIDGET (inferior_ptid), 1)))) 571 thr_map_main = info->private->mapp; 572 } 573 return thr_map_main; 574} 575 576/* Attach to process specified by ARGS, then initialize for debugging it 577 and wait for the trace-trap that results from attaching. 578 579 This function only gets called with uw_thread_active == 0. */ 580 581static void 582uw_thread_attach (char *args, int from_tty) 583{ 584 procfs_ops.to_attach (args, from_tty); 585 if (uw_thread_active) 586 thr_infpid (NULL); 587} 588 589/* Detach from the process attached to by uw_thread_attach(). */ 590 591static void 592uw_thread_detach (char *args, int from_tty) 593{ 594 deactivate_uw_thread (); 595 base_ops.to_detach (args, from_tty); 596} 597 598/* Tell the inferior process to continue running thread PID if >= 0 599 and all threads otherwise. */ 600 601static void 602uw_thread_resume (ptid_t ptid, int step, enum target_signal signo) 603{ 604 if (PIDGET (ptid) > 0) 605 { 606 ptid = thr_to_lwp (ptid); 607 if (ptid_equal (ptid, null_ptid)) 608 ptid = pid_to_ptid (-1); 609 } 610 611 CALL_BASE (base_ops.to_resume (ptid, step, signo)); 612} 613 614/* If the trap we just received from lwp PID was due to a breakpoint 615 on the libthread.so debugging stub, update this module's state 616 accordingly. */ 617 618static void 619libthread_stub (ptid_t ptid) 620{ 621 CORE_ADDR sp, mapp, mapp_main; 622 enum thread_change change; 623 struct thread_map map; 624 __lwp_desc_t lwp; 625 int lwpid; 626 ptid_t tid = null_ptid; 627 struct thread_info *info; 628 629 /* Check for stub breakpoint. */ 630 if (read_pc_pid (ptid) - DECR_PC_AFTER_BREAK != thr_brk_addr) 631 return; 632 633 /* Retrieve stub args. */ 634 sp = read_register_pid (SP_REGNUM, ptid); 635 if (!base_ops.to_xfer_memory (sp + SP_ARG0, (char *)&mapp, 636 sizeof (mapp), 0, NULL, &base_ops)) 637 goto err; 638 if (!base_ops.to_xfer_memory (sp + SP_ARG0 + sizeof (mapp), (char *)&change, 639 sizeof (change), 0, NULL, &base_ops)) 640 goto err; 641 642 /* create_inferior() may not have finished yet, so notice the main 643 thread to ensure that it's displayed first by add_thread(). */ 644 mapp_main = find_main (); 645 646 /* Notice thread creation, deletion, or stability change. */ 647 switch (change) { 648 case tc_switch_begin: 649 if (!mapp) /* usually means main thread */ 650 mapp = mapp_main; 651 /* fall through */ 652 653 case tc_thread_create: 654 case tc_thread_exit: 655 if (!mapp) 656 break; 657 if (!read_map (mapp, &map)) 658 goto err; 659 tid = MKTID (PIDGET (ptid), map.thr_tid); 660 661 switch (change) { 662 case tc_thread_create: /* new thread */ 663 if (!map.thr_lwpp) 664 lwpid = 0; 665 else if (!read_lwp ((CORE_ADDR)map.thr_lwpp, &lwp)) 666 goto err; 667 else 668 lwpid = lwp.lwp_id; 669 add_thread_uw (map.thr_tid, lwpid, mapp, tid); 670 break; 671 672 case tc_thread_exit: /* thread has exited */ 673 printf_unfiltered ("[Exited %s]\n", target_pid_to_str (tid)); 674 delete_thread (tid); 675 if (ptid_equal (tid, inferior_ptid)) 676 inferior_ptid = ptid; 677 break; 678 679 case tc_switch_begin: /* lwp is switching threads */ 680 if (switchto_thread) 681 goto err; 682 if (!(switchto_thread = find_thread_pid (tid))) 683 goto err; 684 switchto_thread->private->stable = 0; 685 break; 686 687 default: 688 break; 689 } 690 break; 691 692 case tc_switch_complete: /* lwp has switched threads */ 693 case tc_cancel_complete: /* lwp didn't switch threads */ 694 if (!switchto_thread) 695 goto err; 696 697 if (change == tc_switch_complete) 698 { 699 /* If switchto_thread is the main thread, then (a) the corresponding 700 tc_switch_begin probably received a null map argument and therefore 701 (b) it may have been a spurious switch following a tc_thread_exit. 702 703 Therefore, explicitly query the thread's lwp before caching it in 704 its thread list entry. */ 705 706 if (!read_map (switchto_thread->private->mapp, &map)) 707 goto err; 708 if (map.thr_lwpp) 709 { 710 if (!read_lwp ((CORE_ADDR)map.thr_lwpp, &lwp)) 711 goto err; 712 if ((info = find_thread_lwp (lwp.lwp_id))) 713 info->private->lwpid = 0; 714 switchto_thread->private->lwpid = lwp.lwp_id; 715 } 716 } 717 718 switchto_thread->private->stable = 1; 719 switchto_thread = NULL; 720 break; 721 722 case tc_invalid: 723 case tc_thread_suspend: 724 case tc_thread_suspend_pending: 725 case tc_thread_continue: 726 err: 727 DBG(("unexpected condition in libthread_stub()")); 728 break; 729 } 730 731 DBG2(("libthread_stub(%s): %s %s %s", dbgpid (pid), dbgpid (tid), 732 dbgchange (change), tid ? dbgstate (map.thr_state) : "")); 733} 734 735/* Wait for thread/lwp/process ID if >= 0 or for any thread otherwise. */ 736 737static ptid_t 738uw_thread_wait (ptid_t ptid, struct target_waitstatus *status) 739{ 740 if (PIDGET (ptid) > 0) 741 ptid = thr_to_lwp (ptid); 742 if (PIDGET (ptid) <= 0) 743 ptid = pid_to_ptid (-1); 744 745 CALL_BASE (ptid = base_ops.to_wait (ptid, status)); 746 747 if (status->kind == TARGET_WAITKIND_STOPPED && 748 status->value.sig == TARGET_SIGNAL_TRAP) 749 libthread_stub (ptid); 750 751 return lwp_to_thr (ptid); 752} 753 754/* Tell gdb about the registers in the thread/lwp/process specified by 755 inferior_ptid. */ 756 757static void 758uw_thread_fetch_registers (int regno) 759{ 760 int called; 761 struct thread_info *info; 762 struct thread_map map; 763 764 TRY_BASE (base_ops.to_fetch_registers (regno), &called); 765 if (called) 766 return; 767 768 if (!(info = find_thread_pid (inferior_ptid))) 769 return; 770 if (!read_map (info->private->mapp, &map)) 771 return; 772 773 supply_gregset (&map.thr_ucontext.uc_mcontext.gregs); 774 supply_fpregset (&map.thr_ucontext.uc_mcontext.fpregs); 775} 776 777/* Store gdb's current view of the register set into the thread/lwp/process 778 specified by inferior_ptid. */ 779 780static void 781uw_thread_store_registers (int regno) 782{ 783 CALL_BASE (base_ops.to_store_registers (regno)); 784} 785 786/* Prepare to modify the registers array. */ 787 788static void 789uw_thread_prepare_to_store (void) 790{ 791 CALL_BASE (base_ops.to_prepare_to_store ()); 792} 793 794/* Fork an inferior process and start debugging it. 795 796 This function only gets called with uw_thread_active == 0. */ 797 798static void 799uw_thread_create_inferior (char *exec_file, char *allargs, char **env) 800{ 801 if (uw_thread_active) 802 deactivate_uw_thread (); 803 804 procfs_ops.to_create_inferior (exec_file, allargs, env); 805 if (uw_thread_active) 806 { 807 find_main (); 808 thr_infpid (NULL); 809 } 810} 811 812/* Kill and forget about the inferior process. */ 813 814static void 815uw_thread_kill (void) 816{ 817 base_ops.to_kill (); 818} 819 820/* Clean up after the inferior exits. */ 821 822static void 823uw_thread_mourn_inferior (void) 824{ 825 deactivate_uw_thread (); 826 base_ops.to_mourn_inferior (); 827} 828 829/* Return whether this module can attach to and run processes. 830 831 This function only gets called with uw_thread_active == 0. */ 832 833static int 834uw_thread_can_run (void) 835{ 836 return procfs_suppress_run; 837} 838 839/* Return whether thread PID is still valid. */ 840 841static int 842uw_thread_alive (ptid_t ptid) 843{ 844 if (!ISTID (ptid)) 845 return base_ops.to_thread_alive (ptid); 846 847 /* If it's in the thread list, it's valid, because otherwise 848 libthread_stub() would have deleted it. */ 849 return in_thread_list (ptid); 850} 851 852/* Add to the thread list any threads and lwps it doesn't already contain. */ 853 854static void 855uw_thread_find_new_threads (void) 856{ 857 CALL_BASE (if (base_ops.to_find_new_threads) 858 base_ops.to_find_new_threads ()); 859 notice_threads (); 860} 861 862/* Return a string for pretty-printing PID in "info threads" output. 863 This may be called by either procfs.c or by generic gdb. */ 864 865static char * 866uw_thread_pid_to_str (ptid_t ptid) 867{ 868#define FMT "Thread %ld" 869 static char buf[sizeof (FMT) + 3 * sizeof (long)]; 870 871 if (!ISTID (ptid)) 872 /* core_ops says "process foo", so call procfs_ops explicitly. */ 873 return procfs_ops.to_pid_to_str (ptid); 874 875 sprintf (buf, FMT, TIDGET (ptid)); 876#undef FMT 877 return buf; 878} 879 880/* Return a string displaying INFO state information in "info threads" 881 output. */ 882 883static char * 884uw_extra_thread_info (struct thread_info *info) 885{ 886 static char buf[80]; 887 struct thread_map map; 888 __lwp_desc_t lwp; 889 int lwpid; 890 char *name; 891 892 if (!ISTID (info->ptid)) 893 return NULL; 894 895 if (!info->private->stable) 896 return "switching"; 897 898 if (!read_map (info->private->mapp, &map)) 899 return NULL; 900 901 if (!map.thr_lwpp || !read_lwp ((CORE_ADDR)map.thr_lwpp, &lwp)) 902 lwpid = 0; 903 else 904 lwpid = lwp.lwp_id; 905 906 switch (map.thr_state) { 907 case TS_ONPROC: name = "running"; break; 908 case TS_SLEEP: name = "sleeping"; break; 909 case TS_RUNNABLE: name = "runnable"; break; 910 case TS_ZOMBIE: name = "zombie"; break; 911 case TS_SUSPENDED: name = "suspended"; break; 912#ifdef TS_FORK 913 case TS_FORK: name = "forking"; break; 914#endif 915 default: name = "confused"; break; 916 } 917 918 if (!lwpid) 919 return name; 920 921 sprintf (buf, "%s, LWP %d", name, lwpid); 922 return buf; 923} 924 925/* Check whether libthread.so has just been loaded, and if so, try to 926 initialize user-space thread debugging support. 927 928 libthread.so loading happens while (a) an inferior process is being 929 started by procfs and (b) a core image is being loaded. 930 931 This function often gets called with uw_thread_active == 0. */ 932 933static void 934libthread_init (void) 935{ 936 struct minimal_symbol *ms; 937 struct thread_debug debug; 938 CORE_ADDR onp; 939 struct breakpoint *b; 940 int one = 1; 941 942 /* Don't initialize twice. */ 943 if (uw_thread_active) 944 return; 945 946 /* Check whether libthread.so has been loaded. */ 947 if (!(ms = lookup_minimal_symbol ("_thr_debug", NULL, NULL))) 948 return; 949 950 /* Cache _thr_debug's address. */ 951 if (!(thr_debug_addr = SYMBOL_VALUE_ADDRESS (ms))) 952 return; 953 954 /* Initialize base_ops.to_xfer_memory(). */ 955 base_ops = current_target; 956 957 /* Load _thr_debug's current contents. */ 958 if (!read_thr_debug (&debug)) 959 return; 960 961 /* User code (e.g. my test programs) may dereference _thr_debug, 962 making it availble to GDB before shared libs are loaded. */ 963 if (!debug.thr_map) 964 return; 965 966 /* libthread.so has been loaded, and the current_target should now 967 reflect core_ops or procfs_ops. */ 968 push_target (&uw_thread_ops); /* must precede notice_threads() */ 969 uw_thread_active = 1; 970 971 if (!target_has_execution) 972 973 /* Locate threads in core file. */ 974 notice_threads (); 975 976 else 977 { 978 /* Set a breakpoint on the stub function provided by libthread.so. */ 979 thr_brk_addr = (CORE_ADDR)debug.thr_brk; 980 if (!(b = create_thread_event_breakpoint (thr_brk_addr))) 981 goto err; 982 983 /* Activate the stub function. */ 984 onp = (CORE_ADDR)&((struct thread_debug *)thr_debug_addr)->thr_debug_on; 985 if (!base_ops.to_xfer_memory ((CORE_ADDR)onp, (char *)&one, 986 sizeof (one), 1, NULL, &base_ops)) 987 { 988 delete_breakpoint (b); 989 goto err; 990 } 991 992 /* Prepare for finding the main thread, which doesn't yet exist. */ 993 thr_map_main = 0; 994 } 995 996 return; 997 998 err: 999 warning ("uw-thread: unable to initialize user-mode thread debugging\n"); 1000 deactivate_uw_thread (); 1001} 1002 1003/* target_new_objfile_hook callback. 1004 1005 If OBJFILE is non-null, check whether libthread.so was just loaded, 1006 and if so, prepare for user-mode thread debugging. 1007 1008 If OBJFILE is null, libthread.so has gone away, so stop debugging 1009 user-mode threads. 1010 1011 This function often gets called with uw_thread_active == 0. */ 1012 1013static void 1014uw_thread_new_objfile (struct objfile *objfile) 1015{ 1016 if (objfile) 1017 libthread_init (); 1018 1019 else if (uw_thread_active) 1020 deactivate_uw_thread (); 1021 1022 if (target_new_objfile_chain) 1023 target_new_objfile_chain (objfile); 1024} 1025 1026/* Initialize uw_thread_ops. */ 1027 1028static void 1029init_uw_thread_ops (void) 1030{ 1031 uw_thread_ops.to_shortname = "unixware-threads"; 1032 uw_thread_ops.to_longname = "UnixWare threads and pthread."; 1033 uw_thread_ops.to_doc = "UnixWare threads and pthread support."; 1034 uw_thread_ops.to_attach = uw_thread_attach; 1035 uw_thread_ops.to_detach = uw_thread_detach; 1036 uw_thread_ops.to_resume = uw_thread_resume; 1037 uw_thread_ops.to_wait = uw_thread_wait; 1038 uw_thread_ops.to_fetch_registers = uw_thread_fetch_registers; 1039 uw_thread_ops.to_store_registers = uw_thread_store_registers; 1040 uw_thread_ops.to_prepare_to_store = uw_thread_prepare_to_store; 1041 uw_thread_ops.to_create_inferior = uw_thread_create_inferior; 1042 uw_thread_ops.to_kill = uw_thread_kill; 1043 uw_thread_ops.to_mourn_inferior = uw_thread_mourn_inferior; 1044 uw_thread_ops.to_can_run = uw_thread_can_run; 1045 uw_thread_ops.to_thread_alive = uw_thread_alive; 1046 uw_thread_ops.to_find_new_threads = uw_thread_find_new_threads; 1047 uw_thread_ops.to_pid_to_str = uw_thread_pid_to_str; 1048 uw_thread_ops.to_extra_thread_info = uw_extra_thread_info; 1049 uw_thread_ops.to_stratum = thread_stratum; 1050 uw_thread_ops.to_magic = OPS_MAGIC; 1051} 1052 1053/* Module startup initialization function, automagically called by 1054 init.c. */ 1055 1056void 1057_initialize_uw_thread (void) 1058{ 1059 init_uw_thread_ops (); 1060 add_target (&uw_thread_ops); 1061 1062 procfs_suppress_run = 1; 1063 1064 /* Notice when libthread.so gets loaded. */ 1065 target_new_objfile_chain = target_new_objfile_hook; 1066 target_new_objfile_hook = uw_thread_new_objfile; 1067} 1068