1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #define _SYSCALL32 30 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <unistd.h> 34 #include <ctype.h> 35 #include <string.h> 36 #include <memory.h> 37 #include <errno.h> 38 #include <sys/types.h> 39 #include <sys/stack.h> 40 #include <signal.h> 41 #include <limits.h> 42 #include <sys/isa_defs.h> 43 #include <proc_service.h> 44 #include <dlfcn.h> 45 #include <fnmatch.h> 46 #include <libproc.h> 47 #include "ramdata.h" 48 #include "systable.h" 49 #include "print.h" 50 #include "proto.h" 51 #include "htbl.h" 52 53 /* 54 * Functions supporting library function call tracing. 55 */ 56 57 typedef struct { 58 prmap_t *pmap; 59 int nmap; 60 } ph_map_t; 61 62 /* 63 * static functions in this file. 64 */ 65 void function_entry(private_t *, struct bkpt *, struct callstack *); 66 void function_return(private_t *, struct callstack *); 67 int object_iter(void *, const prmap_t *, const char *); 68 int symbol_iter(void *, const GElf_Sym *, const char *); 69 uintptr_t get_return_address(uintptr_t *); 70 int get_arguments(long *argp); 71 uintptr_t previous_fp(uintptr_t, uintptr_t *); 72 int lwp_stack_traps(void *cd, const lwpstatus_t *Lsp); 73 int thr_stack_traps(const td_thrhandle_t *Thp, void *cd); 74 struct bkpt *create_bkpt(uintptr_t, int, int); 75 void set_deferred_breakpoints(void); 76 77 #define DEF_MAXCALL 16 /* initial value of Stk->maxcall */ 78 79 #define FAULT_ADDR ((uintptr_t)(0-8)) 80 81 #define HASHSZ 2048 82 #define bpt_hash(addr) ((((addr) >> 13) ^ ((addr) >> 2)) & 0x7ff) 83 84 static void 85 setup_thread_agent(void) 86 { 87 struct bkpt *Bp; 88 td_notify_t notify; 89 td_thr_events_t events; 90 91 if (Thr_agent != NULL) /* only once */ 92 return; 93 if (td_init() != TD_OK || td_ta_new(Proc, &Thr_agent) != TD_OK) 94 Thr_agent = NULL; 95 else { 96 td_event_emptyset(&events); 97 td_event_addset(&events, TD_CREATE); 98 if (td_ta_event_addr(Thr_agent, TD_CREATE, ¬ify) == TD_OK && 99 notify.type == NOTIFY_BPT && 100 td_ta_set_event(Thr_agent, &events) == TD_OK && 101 (Bp = create_bkpt(notify.u.bptaddr, 0, 1)) != NULL) 102 Bp->flags |= BPT_TD_CREATE; 103 } 104 } 105 106 /* 107 * Establishment of breakpoints on traced library functions. 108 */ 109 void 110 establish_breakpoints(void) 111 { 112 if (Dynpat == NULL) 113 return; 114 115 /* allocate the breakpoint hash table */ 116 if (bpt_hashtable == NULL) { 117 bpt_hashtable = my_malloc(HASHSZ * sizeof (struct bkpt *), 118 NULL); 119 (void) memset(bpt_hashtable, 0, 120 HASHSZ * sizeof (struct bkpt *)); 121 } 122 123 /* 124 * Set special rtld_db event breakpoints, first time only. 125 */ 126 if (Rdb_agent == NULL && 127 (Rdb_agent = Prd_agent(Proc)) != NULL) { 128 rd_notify_t notify; 129 struct bkpt *Bp; 130 131 (void) rd_event_enable(Rdb_agent, 1); 132 if (rd_event_addr(Rdb_agent, RD_PREINIT, ¬ify) == RD_OK && 133 (Bp = create_bkpt(notify.u.bptaddr, 0, 1)) != NULL) 134 Bp->flags |= BPT_PREINIT; 135 if (rd_event_addr(Rdb_agent, RD_POSTINIT, ¬ify) == RD_OK && 136 (Bp = create_bkpt(notify.u.bptaddr, 0, 1)) != NULL) 137 Bp->flags |= BPT_POSTINIT; 138 if (rd_event_addr(Rdb_agent, RD_DLACTIVITY, ¬ify) == RD_OK && 139 (Bp = create_bkpt(notify.u.bptaddr, 0, 1)) != NULL) 140 Bp->flags |= BPT_DLACTIVITY; 141 } 142 143 /* 144 * Set special thread event breakpoint, first time libc is seen. 145 */ 146 if (Thr_agent == NULL) 147 setup_thread_agent(); 148 149 /* 150 * Tell libproc to update its mappings. 151 */ 152 Pupdate_maps(Proc); 153 154 /* 155 * Iterate over the shared objects, creating breakpoints. 156 */ 157 (void) Pobject_iter(Proc, object_iter, NULL); 158 159 /* 160 * Now actually set all the breakpoints we just created. 161 */ 162 set_deferred_breakpoints(); 163 } 164 165 /* 166 * Initial establishment of stacks in a newly-grabbed process. 167 * establish_breakpoints() has already been called. 168 */ 169 void 170 establish_stacks(void) 171 { 172 const pstatus_t *Psp = Pstatus(Proc); 173 char mapfile[64]; 174 int mapfd; 175 struct stat statb; 176 prmap_t *Pmap = NULL; 177 int nmap = 0; 178 ph_map_t ph_map; 179 180 (void) sprintf(mapfile, "/proc/%d/rmap", (int)Psp->pr_pid); 181 if ((mapfd = open(mapfile, O_RDONLY)) < 0 || 182 fstat(mapfd, &statb) != 0 || 183 statb.st_size < sizeof (prmap_t) || 184 (Pmap = my_malloc(statb.st_size, NULL)) == NULL || 185 (nmap = pread(mapfd, Pmap, statb.st_size, 0L)) <= 0 || 186 (nmap /= sizeof (prmap_t)) == 0) { 187 if (Pmap != NULL) 188 free(Pmap); 189 Pmap = NULL; 190 nmap = 0; 191 } 192 if (mapfd >= 0) 193 (void) close(mapfd); 194 195 /* 196 * Iterate over lwps, establishing stacks. 197 */ 198 ph_map.pmap = Pmap; 199 ph_map.nmap = nmap; 200 (void) Plwp_iter(Proc, lwp_stack_traps, &ph_map); 201 if (Pmap != NULL) 202 free(Pmap); 203 204 if (Thr_agent == NULL) 205 return; 206 207 /* 208 * Iterate over unbound threads, establishing stacks. 209 */ 210 (void) td_ta_thr_iter(Thr_agent, thr_stack_traps, NULL, 211 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, 212 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS); 213 } 214 215 void 216 do_symbol_iter(const char *object_name, struct dynpat *Dyp) 217 { 218 if (*Dyp->Dp->prt_name == '\0') 219 object_name = PR_OBJ_EXEC; 220 221 /* 222 * Always search the dynamic symbol table. 223 */ 224 (void) Psymbol_iter(Proc, object_name, 225 PR_DYNSYM, BIND_WEAK|BIND_GLOBAL|TYPE_FUNC, 226 symbol_iter, Dyp); 227 228 /* 229 * Search the static symbol table if this is the 230 * executable file or if we are being asked to 231 * report internal calls within the library. 232 */ 233 if (object_name == PR_OBJ_EXEC || Dyp->internal) 234 (void) Psymbol_iter(Proc, object_name, 235 PR_SYMTAB, BIND_ANY|TYPE_FUNC, 236 symbol_iter, Dyp); 237 } 238 239 /* ARGSUSED */ 240 int 241 object_iter(void *cd, const prmap_t *pmp, const char *object_name) 242 { 243 char name[100]; 244 struct dynpat *Dyp; 245 struct dynlib *Dp; 246 const char *str; 247 char *s; 248 int i; 249 250 if ((pmp->pr_mflags & MA_WRITE) || !(pmp->pr_mflags & MA_EXEC)) 251 return (0); 252 253 /* 254 * Set special thread event breakpoint, first time libc is seen. 255 */ 256 if (Thr_agent == NULL && strstr(object_name, "/libc.so.") != NULL) 257 setup_thread_agent(); 258 259 for (Dp = Dyn; Dp != NULL; Dp = Dp->next) 260 if (strcmp(object_name, Dp->lib_name) == 0 || 261 (strcmp(Dp->lib_name, "a.out") == 0 && 262 strcmp(pmp->pr_mapname, "a.out") == 0)) 263 break; 264 265 if (Dp == NULL) { 266 Dp = my_malloc(sizeof (struct dynlib), NULL); 267 (void) memset(Dp, 0, sizeof (struct dynlib)); 268 if (strcmp(pmp->pr_mapname, "a.out") == 0) { 269 Dp->lib_name = strdup(pmp->pr_mapname); 270 Dp->match_name = strdup(pmp->pr_mapname); 271 Dp->prt_name = strdup(""); 272 } else { 273 Dp->lib_name = strdup(object_name); 274 if ((str = strrchr(object_name, '/')) != NULL) 275 str++; 276 else 277 str = object_name; 278 (void) strncpy(name, str, sizeof (name) - 2); 279 name[sizeof (name) - 2] = '\0'; 280 if ((s = strstr(name, ".so")) != NULL) 281 *s = '\0'; 282 Dp->match_name = strdup(name); 283 (void) strcat(name, ":"); 284 Dp->prt_name = strdup(name); 285 } 286 Dp->next = Dyn; 287 Dyn = Dp; 288 } 289 290 if (Dp->built || 291 (not_consist && strcmp(Dp->prt_name, "ld:") != 0)) /* kludge */ 292 return (0); 293 294 if (hflag && not_consist) 295 (void) fprintf(stderr, "not_consist is TRUE, building %s\n", 296 Dp->lib_name); 297 298 Dp->base = pmp->pr_vaddr; 299 Dp->size = pmp->pr_size; 300 301 /* 302 * For every dynlib pattern that matches this library's name, 303 * iterate through all of the library's symbols looking for 304 * matching symbol name patterns. 305 */ 306 for (Dyp = Dynpat; Dyp != NULL; Dyp = Dyp->next) { 307 if (interrupt|sigusr1) 308 break; 309 for (i = 0; i < Dyp->nlibpat; i++) { 310 if (interrupt|sigusr1) 311 break; 312 if (fnmatch(Dyp->libpat[i], Dp->match_name, 0) != 0) 313 continue; /* no match */ 314 315 /* 316 * Require an exact match for the executable (a.out) 317 * and for the dynamic linker (ld.so.1). 318 */ 319 if ((strcmp(Dp->match_name, "a.out") == 0 || 320 strcmp(Dp->match_name, "ld") == 0) && 321 strcmp(Dyp->libpat[i], Dp->match_name) != 0) 322 continue; 323 324 /* 325 * Set Dyp->Dp to Dp so symbol_iter() can use it. 326 */ 327 Dyp->Dp = Dp; 328 do_symbol_iter(object_name, Dyp); 329 Dyp->Dp = NULL; 330 } 331 } 332 333 Dp->built = TRUE; 334 return (interrupt | sigusr1); 335 } 336 337 /* 338 * Search for an existing breakpoint at the 'pc' location. 339 */ 340 struct bkpt * 341 get_bkpt(uintptr_t pc) 342 { 343 struct bkpt *Bp; 344 345 for (Bp = bpt_hashtable[bpt_hash(pc)]; Bp != NULL; Bp = Bp->next) 346 if (pc == Bp->addr) 347 break; 348 349 return (Bp); 350 } 351 352 /* 353 * Create a breakpoint at 'pc', if one is not there already. 354 * 'ret' is true when creating a function return breakpoint, in which case 355 * fail and return NULL if the breakpoint would be created in writeable data. 356 * If 'set' it true, set the breakpoint in the process now. 357 */ 358 struct bkpt * 359 create_bkpt(uintptr_t pc, int ret, int set) 360 { 361 uint_t hix = bpt_hash(pc); 362 struct bkpt *Bp; 363 const prmap_t *pmp; 364 365 for (Bp = bpt_hashtable[hix]; Bp != NULL; Bp = Bp->next) 366 if (pc == Bp->addr) 367 return (Bp); 368 369 /* 370 * Don't set return breakpoints on writeable data 371 * or on any space other than executable text. 372 * Don't set breakpoints in the child of a vfork() 373 * because that would modify the parent's address space. 374 */ 375 if (is_vfork_child || 376 (ret && 377 ((pmp = Paddr_to_text_map(Proc, pc)) == NULL || 378 !(pmp->pr_mflags & MA_EXEC) || 379 (pmp->pr_mflags & MA_WRITE)))) 380 return (NULL); 381 382 /* create a new unnamed breakpoint */ 383 Bp = my_malloc(sizeof (struct bkpt), NULL); 384 Bp->sym_name = NULL; 385 Bp->dyn = NULL; 386 Bp->addr = pc; 387 Bp->instr = 0; 388 Bp->flags = 0; 389 if (set && Psetbkpt(Proc, Bp->addr, &Bp->instr) == 0) 390 Bp->flags |= BPT_ACTIVE; 391 Bp->next = bpt_hashtable[hix]; 392 bpt_hashtable[hix] = Bp; 393 394 return (Bp); 395 } 396 397 /* 398 * Set all breakpoints that haven't been set yet. 399 * Deactivate all breakpoints from modules that are not present any more. 400 */ 401 void 402 set_deferred_breakpoints(void) 403 { 404 struct bkpt *Bp; 405 int i; 406 407 if (is_vfork_child) 408 return; 409 410 for (i = 0; i < HASHSZ; i++) { 411 for (Bp = bpt_hashtable[i]; Bp != NULL; Bp = Bp->next) { 412 if (!(Bp->flags & BPT_ACTIVE)) { 413 if (!(Bp->flags & BPT_EXCLUDE) && 414 Psetbkpt(Proc, Bp->addr, &Bp->instr) == 0) 415 Bp->flags |= BPT_ACTIVE; 416 } else if (Paddr_to_text_map(Proc, Bp->addr) == NULL) { 417 Bp->flags &= ~BPT_ACTIVE; 418 } 419 } 420 } 421 } 422 423 int 424 symbol_iter(void *cd, const GElf_Sym *sym, const char *sym_name) 425 { 426 struct dynpat *Dyp = cd; 427 struct dynlib *Dp = Dyp->Dp; 428 uintptr_t pc = sym->st_value; 429 struct bkpt *Bp; 430 int i; 431 432 /* ignore any undefined symbols */ 433 if (sym->st_shndx == SHN_UNDEF) 434 return (0); 435 436 /* 437 * Arbitrarily omit "_start" from the executable. 438 * (Avoid indentation before main().) 439 */ 440 if (*Dp->prt_name == '\0' && strcmp(sym_name, "_start") == 0) 441 return (0); 442 443 /* 444 * Arbitrarily omit "_rt_boot" from the dynamic linker. 445 * (Avoid indentation before main().) 446 */ 447 if (strcmp(Dp->match_name, "ld") == 0 && 448 strcmp(sym_name, "_rt_boot") == 0) 449 return (0); 450 451 /* 452 * Arbitrarily omit any symbols whose name starts with '.'. 453 * Apparantly putting a breakpoint on .umul causes a 454 * fatal error in libthread (%y is not restored correctly 455 * when a single step is taken). Looks like a /proc bug. 456 */ 457 if (*sym_name == '.') 458 return (0); 459 460 /* 461 * For each pattern in the array of symbol patterns, 462 * if the pattern matches the symbol name, then 463 * create a breakpoint at the function in question. 464 */ 465 for (i = 0; i < Dyp->nsympat; i++) { 466 if (interrupt|sigusr1) 467 break; 468 if (fnmatch(Dyp->sympat[i], sym_name, 0) != 0) 469 continue; 470 471 if ((Bp = create_bkpt(pc, 0, 0)) == NULL) /* can't fail */ 472 return (0); 473 474 /* 475 * New breakpoints receive a name now. 476 * For existing breakpoints, prefer the subset name if possible, 477 * else prefer the shorter name. 478 */ 479 if (Bp->sym_name == NULL) { 480 Bp->sym_name = strdup(sym_name); 481 } else if (strstr(Bp->sym_name, sym_name) != NULL || 482 strlen(Bp->sym_name) > strlen(sym_name)) { 483 free(Bp->sym_name); 484 Bp->sym_name = strdup(sym_name); 485 } 486 Bp->dyn = Dp; 487 Bp->flags |= Dyp->flag; 488 if (Dyp->exclude) 489 Bp->flags |= BPT_EXCLUDE; 490 else if (Dyp->internal || *Dp->prt_name == '\0') 491 Bp->flags |= BPT_INTERNAL; 492 return (0); 493 } 494 495 return (interrupt | sigusr1); 496 } 497 498 /* For debugging only ---- */ 499 void 500 report_htable_stats(void) 501 { 502 const pstatus_t *Psp = Pstatus(Proc); 503 struct callstack *Stk; 504 struct bkpt *Bp; 505 uint_t Min = 1000000; 506 uint_t Max = 0; 507 uint_t Avg = 0; 508 uint_t Total = 0; 509 uint_t i, j; 510 uint_t bucket[HASHSZ]; 511 512 if (Dynpat == NULL || !hflag) 513 return; 514 515 hflag = FALSE; 516 (void) memset(bucket, 0, sizeof (bucket)); 517 518 for (i = 0; i < HASHSZ; i++) { 519 j = 0; 520 for (Bp = bpt_hashtable[i]; Bp != NULL; Bp = Bp->next) 521 j++; 522 if (j < Min) 523 Min = j; 524 if (j > Max) 525 Max = j; 526 if (j < HASHSZ) 527 bucket[j]++; 528 Total += j; 529 } 530 Avg = (Total + HASHSZ / 2) / HASHSZ; 531 (void) fprintf(stderr, "truss hash table statistics --------\n"); 532 (void) fprintf(stderr, " Total = %u\n", Total); 533 (void) fprintf(stderr, " Min = %u\n", Min); 534 (void) fprintf(stderr, " Max = %u\n", Max); 535 (void) fprintf(stderr, " Avg = %u\n", Avg); 536 for (i = 0; i < HASHSZ; i++) 537 if (bucket[i]) 538 (void) fprintf(stderr, " %3u buckets of size %d\n", 539 bucket[i], i); 540 541 (void) fprintf(stderr, "truss-detected stacks --------\n"); 542 for (Stk = callstack; Stk != NULL; Stk = Stk->next) { 543 (void) fprintf(stderr, 544 " base = 0x%.8lx end = 0x%.8lx size = %ld\n", 545 (ulong_t)Stk->stkbase, 546 (ulong_t)Stk->stkend, 547 (ulong_t)(Stk->stkend - Stk->stkbase)); 548 } 549 (void) fprintf(stderr, "primary unix stack --------\n"); 550 (void) fprintf(stderr, 551 " base = 0x%.8lx end = 0x%.8lx size = %ld\n", 552 (ulong_t)Psp->pr_stkbase, 553 (ulong_t)(Psp->pr_stkbase + Psp->pr_stksize), 554 (ulong_t)Psp->pr_stksize); 555 (void) fprintf(stderr, "nthr_create = %u\n", nthr_create); 556 } 557 558 void 559 make_lwp_stack(const lwpstatus_t *Lsp, prmap_t *Pmap, int nmap) 560 { 561 const pstatus_t *Psp = Pstatus(Proc); 562 uintptr_t sp = Lsp->pr_reg[R_SP]; 563 id_t lwpid = Lsp->pr_lwpid; 564 struct callstack *Stk; 565 td_thrhandle_t th; 566 td_thrinfo_t thrinfo; 567 568 if (data_model != PR_MODEL_LP64) 569 sp = (uint32_t)sp; 570 571 /* check to see if we already have this stack */ 572 if (sp == 0) 573 return; 574 for (Stk = callstack; Stk != NULL; Stk = Stk->next) 575 if (sp >= Stk->stkbase && sp < Stk->stkend) 576 return; 577 578 Stk = my_malloc(sizeof (struct callstack), NULL); 579 Stk->next = callstack; 580 callstack = Stk; 581 nstack++; 582 Stk->tref = 0; 583 Stk->tid = 0; 584 Stk->nthr_create = 0; 585 Stk->ncall = 0; 586 Stk->maxcall = DEF_MAXCALL; 587 Stk->stack = my_malloc(DEF_MAXCALL * sizeof (*Stk->stack), NULL); 588 589 /* primary stack */ 590 if (sp >= Psp->pr_stkbase && sp < Psp->pr_stkbase + Psp->pr_stksize) { 591 Stk->stkbase = Psp->pr_stkbase; 592 Stk->stkend = Stk->stkbase + Psp->pr_stksize; 593 return; 594 } 595 596 /* alternate stack */ 597 if ((Lsp->pr_altstack.ss_flags & SS_ONSTACK) && 598 sp >= (uintptr_t)Lsp->pr_altstack.ss_sp && 599 sp < (uintptr_t)Lsp->pr_altstack.ss_sp 600 + Lsp->pr_altstack.ss_size) { 601 Stk->stkbase = (uintptr_t)Lsp->pr_altstack.ss_sp; 602 Stk->stkend = Stk->stkbase + Lsp->pr_altstack.ss_size; 603 return; 604 } 605 606 /* thread stacks? */ 607 if (Thr_agent != NULL && 608 td_ta_map_lwp2thr(Thr_agent, lwpid, &th) == TD_OK && 609 td_thr_get_info(&th, &thrinfo) == TD_OK && 610 sp >= (uintptr_t)thrinfo.ti_stkbase - thrinfo.ti_stksize && 611 sp < (uintptr_t)thrinfo.ti_stkbase) { 612 /* The bloody fools got this backwards! */ 613 Stk->stkend = (uintptr_t)thrinfo.ti_stkbase; 614 Stk->stkbase = Stk->stkend - thrinfo.ti_stksize; 615 return; 616 } 617 618 /* last chance -- try the raw memory map */ 619 for (; nmap; nmap--, Pmap++) { 620 if (sp >= Pmap->pr_vaddr && 621 sp < Pmap->pr_vaddr + Pmap->pr_size) { 622 Stk->stkbase = Pmap->pr_vaddr; 623 Stk->stkend = Pmap->pr_vaddr + Pmap->pr_size; 624 return; 625 } 626 } 627 628 callstack = Stk->next; 629 nstack--; 630 free(Stk->stack); 631 free(Stk); 632 } 633 634 void 635 make_thr_stack(const td_thrhandle_t *Thp, prgregset_t reg) 636 { 637 const pstatus_t *Psp = Pstatus(Proc); 638 td_thrinfo_t thrinfo; 639 uintptr_t sp = reg[R_SP]; 640 struct callstack *Stk; 641 642 if (data_model != PR_MODEL_LP64) 643 sp = (uint32_t)sp; 644 645 /* check to see if we already have this stack */ 646 if (sp == 0) 647 return; 648 for (Stk = callstack; Stk != NULL; Stk = Stk->next) 649 if (sp >= Stk->stkbase && sp < Stk->stkend) 650 return; 651 652 Stk = my_malloc(sizeof (struct callstack), NULL); 653 Stk->next = callstack; 654 callstack = Stk; 655 nstack++; 656 Stk->tref = 0; 657 Stk->tid = 0; 658 Stk->nthr_create = 0; 659 Stk->ncall = 0; 660 Stk->maxcall = DEF_MAXCALL; 661 Stk->stack = my_malloc(DEF_MAXCALL * sizeof (*Stk->stack), NULL); 662 663 /* primary stack */ 664 if (sp >= Psp->pr_stkbase && sp < Psp->pr_stkbase + Psp->pr_stksize) { 665 Stk->stkbase = Psp->pr_stkbase; 666 Stk->stkend = Stk->stkbase + Psp->pr_stksize; 667 return; 668 } 669 670 if (td_thr_get_info(Thp, &thrinfo) == TD_OK && 671 sp >= (uintptr_t)thrinfo.ti_stkbase - thrinfo.ti_stksize && 672 sp < (uintptr_t)thrinfo.ti_stkbase) { 673 /* The bloody fools got this backwards! */ 674 Stk->stkend = (uintptr_t)thrinfo.ti_stkbase; 675 Stk->stkbase = Stk->stkend - thrinfo.ti_stksize; 676 return; 677 } 678 679 callstack = Stk->next; 680 nstack--; 681 free(Stk->stack); 682 free(Stk); 683 } 684 685 struct callstack * 686 find_lwp_stack(uintptr_t sp) 687 { 688 const pstatus_t *Psp = Pstatus(Proc); 689 char mapfile[64]; 690 int mapfd; 691 struct stat statb; 692 prmap_t *Pmap = NULL; 693 prmap_t *pmap = NULL; 694 int nmap = 0; 695 struct callstack *Stk = NULL; 696 697 /* 698 * Get the address space map. 699 */ 700 (void) sprintf(mapfile, "/proc/%d/rmap", (int)Psp->pr_pid); 701 if ((mapfd = open(mapfile, O_RDONLY)) < 0 || 702 fstat(mapfd, &statb) != 0 || 703 statb.st_size < sizeof (prmap_t) || 704 (Pmap = my_malloc(statb.st_size, NULL)) == NULL || 705 (nmap = pread(mapfd, Pmap, statb.st_size, 0L)) <= 0 || 706 (nmap /= sizeof (prmap_t)) == 0) { 707 if (Pmap != NULL) 708 free(Pmap); 709 if (mapfd >= 0) 710 (void) close(mapfd); 711 return (NULL); 712 } 713 (void) close(mapfd); 714 715 for (pmap = Pmap; nmap--; pmap++) { 716 if (sp >= pmap->pr_vaddr && 717 sp < pmap->pr_vaddr + pmap->pr_size) { 718 Stk = my_malloc(sizeof (struct callstack), NULL); 719 Stk->next = callstack; 720 callstack = Stk; 721 nstack++; 722 Stk->stkbase = pmap->pr_vaddr; 723 Stk->stkend = pmap->pr_vaddr + pmap->pr_size; 724 Stk->tref = 0; 725 Stk->tid = 0; 726 Stk->nthr_create = 0; 727 Stk->ncall = 0; 728 Stk->maxcall = DEF_MAXCALL; 729 Stk->stack = my_malloc( 730 DEF_MAXCALL * sizeof (*Stk->stack), NULL); 731 break; 732 } 733 } 734 735 free(Pmap); 736 return (Stk); 737 } 738 739 struct callstack * 740 find_stack(uintptr_t sp) 741 { 742 const pstatus_t *Psp = Pstatus(Proc); 743 private_t *pri = get_private(); 744 const lwpstatus_t *Lsp = pri->lwpstat; 745 id_t lwpid = Lsp->pr_lwpid; 746 #if defined(__sparc) 747 prgreg_t tref = Lsp->pr_reg[R_G7]; 748 #elif defined(__amd64) 749 prgreg_t tref = Lsp->pr_reg[REG_FS]; 750 #elif defined(__i386) 751 prgreg_t tref = Lsp->pr_reg[GS]; 752 #endif 753 struct callstack *Stk = NULL; 754 td_thrhandle_t th; 755 td_thrinfo_t thrinfo; 756 td_err_e error; 757 758 /* primary stack */ 759 if (sp >= Psp->pr_stkbase && sp < Psp->pr_stkbase + Psp->pr_stksize) { 760 Stk = my_malloc(sizeof (struct callstack), NULL); 761 Stk->next = callstack; 762 callstack = Stk; 763 nstack++; 764 Stk->stkbase = Psp->pr_stkbase; 765 Stk->stkend = Stk->stkbase + Psp->pr_stksize; 766 Stk->tref = 0; 767 Stk->tid = 0; 768 Stk->nthr_create = 0; 769 Stk->ncall = 0; 770 Stk->maxcall = DEF_MAXCALL; 771 Stk->stack = my_malloc(DEF_MAXCALL * sizeof (*Stk->stack), 772 NULL); 773 return (Stk); 774 } 775 776 /* alternate stack */ 777 if ((Lsp->pr_altstack.ss_flags & SS_ONSTACK) && 778 sp >= (uintptr_t)Lsp->pr_altstack.ss_sp && 779 sp < (uintptr_t)Lsp->pr_altstack.ss_sp 780 + Lsp->pr_altstack.ss_size) { 781 Stk = my_malloc(sizeof (struct callstack), NULL); 782 Stk->next = callstack; 783 callstack = Stk; 784 nstack++; 785 Stk->stkbase = (uintptr_t)Lsp->pr_altstack.ss_sp; 786 Stk->stkend = Stk->stkbase + Lsp->pr_altstack.ss_size; 787 Stk->tref = 0; 788 Stk->tid = 0; 789 Stk->nthr_create = 0; 790 Stk->ncall = 0; 791 Stk->maxcall = DEF_MAXCALL; 792 Stk->stack = my_malloc(DEF_MAXCALL * sizeof (*Stk->stack), 793 NULL); 794 return (Stk); 795 } 796 797 if (Thr_agent == NULL) 798 return (find_lwp_stack(sp)); 799 800 /* thread stacks? */ 801 if ((error = td_ta_map_lwp2thr(Thr_agent, lwpid, &th)) != TD_OK) { 802 if (hflag) 803 (void) fprintf(stderr, 804 "cannot get thread handle for " 805 "lwp#%d, error=%d, tref=0x%.8lx\n", 806 (int)lwpid, error, (long)tref); 807 return (NULL); 808 } 809 810 if ((error = td_thr_get_info(&th, &thrinfo)) != TD_OK) { 811 if (hflag) 812 (void) fprintf(stderr, 813 "cannot get thread info for " 814 "lwp#%d, error=%d, tref=0x%.8lx\n", 815 (int)lwpid, error, (long)tref); 816 return (NULL); 817 } 818 819 if (sp >= (uintptr_t)thrinfo.ti_stkbase - thrinfo.ti_stksize && 820 sp < (uintptr_t)thrinfo.ti_stkbase) { 821 Stk = my_malloc(sizeof (struct callstack), NULL); 822 Stk->next = callstack; 823 callstack = Stk; 824 nstack++; 825 /* The bloody fools got this backwards! */ 826 Stk->stkend = (uintptr_t)thrinfo.ti_stkbase; 827 Stk->stkbase = Stk->stkend - thrinfo.ti_stksize; 828 Stk->tref = tref; 829 Stk->tid = thrinfo.ti_tid; 830 Stk->nthr_create = nthr_create; 831 Stk->ncall = 0; 832 Stk->maxcall = DEF_MAXCALL; 833 Stk->stack = my_malloc(DEF_MAXCALL * sizeof (*Stk->stack), 834 NULL); 835 return (Stk); 836 } 837 838 /* stack bounds failure -- complain bitterly */ 839 if (hflag) { 840 (void) fprintf(stderr, 841 "sp not within thread stack: " 842 "sp=0x%.8lx stkbase=0x%.8lx stkend=0x%.8lx\n", 843 (ulong_t)sp, 844 /* The bloody fools got this backwards! */ 845 (ulong_t)thrinfo.ti_stkbase - thrinfo.ti_stksize, 846 (ulong_t)thrinfo.ti_stkbase); 847 } 848 849 return (NULL); 850 } 851 852 void 853 get_tid(struct callstack *Stk) 854 { 855 private_t *pri = get_private(); 856 const lwpstatus_t *Lsp = pri->lwpstat; 857 id_t lwpid = Lsp->pr_lwpid; 858 #if defined(__sparc) 859 prgreg_t tref = Lsp->pr_reg[R_G7]; 860 #elif defined(__amd64) 861 prgreg_t tref = (data_model == PR_MODEL_LP64) ? 862 Lsp->pr_reg[REG_FS] : Lsp->pr_reg[REG_GS]; 863 #elif defined(__i386) 864 prgreg_t tref = Lsp->pr_reg[GS]; 865 #endif 866 td_thrhandle_t th; 867 td_thrinfo_t thrinfo; 868 td_err_e error; 869 870 if (Thr_agent == NULL) { 871 Stk->tref = 0; 872 Stk->tid = 0; 873 Stk->nthr_create = 0; 874 return; 875 } 876 877 /* 878 * Shortcut here -- 879 * If we have a matching tref and no new threads have 880 * been created since the last time we encountered this 881 * stack, then we don't have to go through the overhead 882 * of calling td_ta_map_lwp2thr() to get the thread-id. 883 */ 884 if (tref == Stk->tref && Stk->nthr_create == nthr_create) 885 return; 886 887 if ((error = td_ta_map_lwp2thr(Thr_agent, lwpid, &th)) != TD_OK) { 888 if (hflag) 889 (void) fprintf(stderr, 890 "cannot get thread handle for " 891 "lwp#%d, error=%d, tref=0x%.8lx\n", 892 (int)lwpid, error, (long)tref); 893 Stk->tref = 0; 894 Stk->tid = 0; 895 Stk->nthr_create = 0; 896 } else if ((error = td_thr_get_info(&th, &thrinfo)) != TD_OK) { 897 if (hflag) 898 (void) fprintf(stderr, 899 "cannot get thread info for " 900 "lwp#%d, error=%d, tref=0x%.8lx\n", 901 (int)lwpid, error, (long)tref); 902 Stk->tref = 0; 903 Stk->tid = 0; 904 Stk->nthr_create = 0; 905 } else { 906 Stk->tref = tref; 907 Stk->tid = thrinfo.ti_tid; 908 Stk->nthr_create = nthr_create; 909 } 910 } 911 912 struct callstack * 913 callstack_info(uintptr_t sp, uintptr_t fp, int makeid) 914 { 915 struct callstack *Stk; 916 uintptr_t trash; 917 918 if (sp == 0 || 919 Pread(Proc, &trash, sizeof (trash), sp) != sizeof (trash)) 920 return (NULL); 921 922 for (Stk = callstack; Stk != NULL; Stk = Stk->next) 923 if (sp >= Stk->stkbase && sp < Stk->stkend) 924 break; 925 926 /* 927 * If we didn't find the stack, do it the hard way. 928 */ 929 if (Stk == NULL) { 930 uintptr_t stkbase = sp; 931 uintptr_t stkend; 932 uint_t minsize; 933 934 #if defined(i386) || defined(__amd64) 935 #ifdef _LP64 936 if (data_model == PR_MODEL_LP64) 937 minsize = 2 * sizeof (uintptr_t); /* fp + pc */ 938 else 939 #endif 940 minsize = 2 * sizeof (uint32_t); 941 #else 942 #ifdef _LP64 943 if (data_model != PR_MODEL_LP64) 944 minsize = SA32(MINFRAME32); 945 else 946 minsize = SA64(MINFRAME64); 947 #else 948 minsize = SA(MINFRAME); 949 #endif 950 #endif /* i386 */ 951 stkend = sp + minsize; 952 953 while (Stk == NULL && fp != 0 && fp >= sp) { 954 stkend = fp + minsize; 955 for (Stk = callstack; Stk != NULL; Stk = Stk->next) 956 if ((fp >= Stk->stkbase && fp < Stk->stkend) || 957 (stkend > Stk->stkbase && 958 stkend <= Stk->stkend)) 959 break; 960 if (Stk == NULL) 961 fp = previous_fp(fp, NULL); 962 } 963 964 if (Stk != NULL) /* the stack grew */ 965 Stk->stkbase = stkbase; 966 } 967 968 if (Stk == NULL && makeid) /* new stack */ 969 Stk = find_stack(sp); 970 971 if (Stk == NULL) 972 return (NULL); 973 974 /* 975 * Ensure that there is room for at least one more entry. 976 */ 977 if (Stk->ncall == Stk->maxcall) { 978 Stk->maxcall *= 2; 979 Stk->stack = my_realloc(Stk->stack, 980 Stk->maxcall * sizeof (*Stk->stack), NULL); 981 } 982 983 if (makeid) 984 get_tid(Stk); 985 986 return (Stk); 987 } 988 989 /* 990 * Reset the breakpoint information (called on successful exec()). 991 */ 992 void 993 reset_breakpoints(void) 994 { 995 struct dynlib *Dp; 996 struct bkpt *Bp; 997 struct callstack *Stk; 998 int i; 999 1000 if (Dynpat == NULL) 1001 return; 1002 1003 /* destroy all previous dynamic library information */ 1004 while ((Dp = Dyn) != NULL) { 1005 Dyn = Dp->next; 1006 free(Dp->lib_name); 1007 free(Dp->match_name); 1008 free(Dp->prt_name); 1009 free(Dp); 1010 } 1011 1012 /* destroy all previous breakpoint trap information */ 1013 if (bpt_hashtable != NULL) { 1014 for (i = 0; i < HASHSZ; i++) { 1015 while ((Bp = bpt_hashtable[i]) != NULL) { 1016 bpt_hashtable[i] = Bp->next; 1017 if (Bp->sym_name) 1018 free(Bp->sym_name); 1019 free(Bp); 1020 } 1021 } 1022 } 1023 1024 /* destroy all the callstack information */ 1025 while ((Stk = callstack) != NULL) { 1026 callstack = Stk->next; 1027 free(Stk->stack); 1028 free(Stk); 1029 } 1030 1031 /* we are not a multi-threaded process anymore */ 1032 if (Thr_agent != NULL) 1033 (void) td_ta_delete(Thr_agent); 1034 Thr_agent = NULL; 1035 1036 /* tell libproc to clear out its mapping information */ 1037 Preset_maps(Proc); 1038 Rdb_agent = NULL; 1039 1040 /* Reestablish the symbols from the executable */ 1041 (void) establish_breakpoints(); 1042 } 1043 1044 /* 1045 * Clear breakpoints from the process (called before Prelease()). 1046 * Don't actually destroy the breakpoint table; 1047 * threads currently fielding breakpoints will need it. 1048 */ 1049 void 1050 clear_breakpoints(void) 1051 { 1052 struct bkpt *Bp; 1053 int i; 1054 1055 if (Dynpat == NULL) 1056 return; 1057 1058 /* 1059 * Change all breakpoint traps back to normal instructions. 1060 * We attempt to remove a breakpoint from every address which 1061 * may have ever contained a breakpoint to protect our victims. 1062 */ 1063 report_htable_stats(); /* report stats first */ 1064 for (i = 0; i < HASHSZ; i++) { 1065 for (Bp = bpt_hashtable[i]; Bp != NULL; Bp = Bp->next) { 1066 if (Bp->flags & BPT_ACTIVE) 1067 (void) Pdelbkpt(Proc, Bp->addr, Bp->instr); 1068 Bp->flags &= ~BPT_ACTIVE; 1069 } 1070 } 1071 1072 if (Thr_agent != NULL) { 1073 td_thr_events_t events; 1074 1075 td_event_emptyset(&events); 1076 (void) td_ta_set_event(Thr_agent, &events); 1077 (void) td_ta_delete(Thr_agent); 1078 } 1079 Thr_agent = NULL; 1080 } 1081 1082 /* 1083 * Reestablish the breakpoint traps in the process. 1084 * Called after resuming from a vfork() in the parent. 1085 */ 1086 void 1087 reestablish_traps(void) 1088 { 1089 struct bkpt *Bp; 1090 ulong_t instr; 1091 int i; 1092 1093 if (Dynpat == NULL || is_vfork_child) 1094 return; 1095 1096 for (i = 0; i < HASHSZ; i++) { 1097 for (Bp = bpt_hashtable[i]; Bp != NULL; Bp = Bp->next) { 1098 if ((Bp->flags & BPT_ACTIVE) && 1099 Psetbkpt(Proc, Bp->addr, &instr) != 0) 1100 Bp->flags &= ~BPT_ACTIVE; 1101 } 1102 } 1103 } 1104 1105 void 1106 show_function_call(private_t *pri, 1107 struct callstack *Stk, struct dynlib *Dp, struct bkpt *Bp) 1108 { 1109 long arg[8]; 1110 int narg; 1111 int i; 1112 1113 narg = get_arguments(arg); 1114 make_pname(pri, (Stk != NULL)? Stk->tid : 0); 1115 putpname(pri); 1116 timestamp(pri); 1117 if (Stk != NULL) { 1118 for (i = 1; i < Stk->ncall; i++) { 1119 (void) fputc(' ', stdout); 1120 (void) fputc(' ', stdout); 1121 } 1122 } 1123 (void) printf("-> %s%s(", Dp->prt_name, Bp->sym_name); 1124 for (i = 0; i < narg; i++) { 1125 (void) printf("0x%lx", arg[i]); 1126 if (i < narg-1) { 1127 (void) fputc(',', stdout); 1128 (void) fputc(' ', stdout); 1129 } 1130 } 1131 (void) printf(")\n"); 1132 Flush(); 1133 } 1134 1135 /* ARGSUSED */ 1136 void 1137 show_function_return(private_t *pri, long rval, int stret, 1138 struct callstack *Stk, struct dynlib *Dp, struct bkpt *Bp) 1139 { 1140 int i; 1141 1142 make_pname(pri, Stk->tid); 1143 putpname(pri); 1144 timestamp(pri); 1145 for (i = 0; i < Stk->ncall; i++) { 1146 (void) fputc(' ', stdout); 1147 (void) fputc(' ', stdout); 1148 } 1149 (void) printf("<- %s%s() = ", Dp->prt_name, Bp->sym_name); 1150 if (stret) { 1151 (void) printf("struct return\n"); 1152 } else if (data_model == PR_MODEL_LP64) { 1153 if (rval >= (64 * 1024) || -rval >= (64 * 1024)) 1154 (void) printf("0x%lx\n", rval); 1155 else 1156 (void) printf("%ld\n", rval); 1157 } else { 1158 int rval32 = (int)rval; 1159 if (rval32 >= (64 * 1024) || -rval32 >= (64 * 1024)) 1160 (void) printf("0x%x\n", rval32); 1161 else 1162 (void) printf("%d\n", rval32); 1163 } 1164 Flush(); 1165 } 1166 1167 /* 1168 * Called to deal with function-call tracing. 1169 * Return 0 on normal success, 1 to indicate a BPT_HANG success, 1170 * and -1 on failure (not tracing functions or unknown breakpoint). 1171 */ 1172 int 1173 function_trace(private_t *pri, int first, int clear, int dotrace) 1174 { 1175 struct ps_lwphandle *Lwp = pri->Lwp; 1176 const lwpstatus_t *Lsp = pri->lwpstat; 1177 uintptr_t pc = Lsp->pr_reg[R_PC]; 1178 uintptr_t sp = Lsp->pr_reg[R_SP]; 1179 uintptr_t fp = Lsp->pr_reg[R_FP]; 1180 struct bkpt *Bp; 1181 struct dynlib *Dp; 1182 struct callstack *Stk; 1183 ulong_t instr; 1184 int active; 1185 int rval = 0; 1186 1187 if (Dynpat == NULL) 1188 return (-1); 1189 1190 if (data_model != PR_MODEL_LP64) { 1191 pc = (uint32_t)pc; 1192 sp = (uint32_t)sp; 1193 fp = (uint32_t)fp; 1194 } 1195 1196 if ((Bp = get_bkpt(pc)) == NULL) { 1197 if (hflag) 1198 (void) fprintf(stderr, 1199 "function_trace(): " 1200 "cannot find breakpoint for pc: 0x%.8lx\n", 1201 (ulong_t)pc); 1202 return (-1); 1203 } 1204 1205 if ((Bp->flags & (BPT_PREINIT|BPT_POSTINIT|BPT_DLACTIVITY)) && !clear) { 1206 rd_event_msg_t event_msg; 1207 1208 if (hflag) { 1209 if (Bp->flags & BPT_PREINIT) 1210 (void) fprintf(stderr, "function_trace(): " 1211 "RD_PREINIT breakpoint\n"); 1212 if (Bp->flags & BPT_POSTINIT) 1213 (void) fprintf(stderr, "function_trace(): " 1214 "RD_POSTINIT breakpoint\n"); 1215 if (Bp->flags & BPT_DLACTIVITY) 1216 (void) fprintf(stderr, "function_trace(): " 1217 "RD_DLACTIVITY breakpoint\n"); 1218 } 1219 if (rd_event_getmsg(Rdb_agent, &event_msg) == RD_OK) { 1220 if (event_msg.type == RD_DLACTIVITY) { 1221 if (event_msg.u.state == RD_CONSISTENT) 1222 establish_breakpoints(); 1223 if (event_msg.u.state == RD_ADD) { 1224 if (hflag) 1225 (void) fprintf(stderr, 1226 "RD_DLACTIVITY/RD_ADD " 1227 "state reached\n"); 1228 not_consist = TRUE; /* kludge */ 1229 establish_breakpoints(); 1230 not_consist = FALSE; 1231 } 1232 } 1233 if (hflag) { 1234 const char *et; 1235 char buf[32]; 1236 1237 switch (event_msg.type) { 1238 case RD_NONE: 1239 et = "RD_NONE"; 1240 break; 1241 case RD_PREINIT: 1242 et = "RD_PREINIT"; 1243 break; 1244 case RD_POSTINIT: 1245 et = "RD_POSTINIT"; 1246 break; 1247 case RD_DLACTIVITY: 1248 et = "RD_DLACTIVITY"; 1249 break; 1250 default: 1251 (void) sprintf(buf, "0x%x", 1252 event_msg.type); 1253 et = buf; 1254 break; 1255 } 1256 (void) fprintf(stderr, 1257 "event_msg.type = %s ", et); 1258 switch (event_msg.u.state) { 1259 case RD_NOSTATE: 1260 et = "RD_NOSTATE"; 1261 break; 1262 case RD_CONSISTENT: 1263 et = "RD_CONSISTENT"; 1264 break; 1265 case RD_ADD: 1266 et = "RD_ADD"; 1267 break; 1268 case RD_DELETE: 1269 et = "RD_DELETE"; 1270 break; 1271 default: 1272 (void) sprintf(buf, "0x%x", 1273 event_msg.u.state); 1274 et = buf; 1275 break; 1276 } 1277 (void) fprintf(stderr, 1278 "event_msg.u.state = %s\n", et); 1279 } 1280 } 1281 } 1282 1283 if ((Bp->flags & BPT_TD_CREATE) && !clear) { 1284 nthr_create++; 1285 if (hflag) 1286 (void) fprintf(stderr, "function_trace(): " 1287 "BPT_TD_CREATE breakpoint\n"); 1288 /* we don't care about the event message */ 1289 } 1290 1291 Dp = Bp->dyn; 1292 1293 if (dotrace) { 1294 if ((Stk = callstack_info(sp, fp, 1)) == NULL) { 1295 if (Dp != NULL && !clear) { 1296 if (cflag) { 1297 add_fcall(fcall_tbl, Dp->prt_name, 1298 Bp->sym_name, (unsigned long)1); 1299 } 1300 else 1301 show_function_call(pri, NULL, Dp, Bp); 1302 if ((Bp->flags & BPT_HANG) && !first) 1303 rval = 1; 1304 } 1305 } else if (!clear) { 1306 if (Dp != NULL) { 1307 function_entry(pri, Bp, Stk); 1308 if ((Bp->flags & BPT_HANG) && !first) 1309 rval = 1; 1310 } else { 1311 function_return(pri, Stk); 1312 } 1313 } 1314 } 1315 1316 /* 1317 * Single-step the traced instruction. Since it's possible that 1318 * another thread has deactivated this breakpoint, we indicate 1319 * that we have reactivated it by virtue of executing it. 1320 * 1321 * To avoid a deadlock with some other thread in the process 1322 * performing a fork() or a thr_suspend() operation, we must 1323 * drop and later reacquire truss_lock. Some fancy dancing here. 1324 */ 1325 active = (Bp->flags & BPT_ACTIVE); 1326 Bp->flags |= BPT_ACTIVE; 1327 instr = Bp->instr; 1328 (void) mutex_unlock(&truss_lock); 1329 (void) Lxecbkpt(Lwp, instr); 1330 (void) mutex_lock(&truss_lock); 1331 1332 if (rval || clear) { /* leave process stopped and abandoned */ 1333 #if defined(__i386) 1334 /* 1335 * Leave it stopped in a state that a stack trace is reasonable. 1336 */ 1337 /* XX64 needs to be updated for amd64 & gcc */ 1338 if (rval && instr == 0x55) { /* pushl %ebp */ 1339 /* step it over the movl %esp,%ebp */ 1340 (void) mutex_unlock(&truss_lock); 1341 (void) Lsetrun(Lwp, 0, PRCFAULT|PRSTEP); 1342 /* we're wrapping up; wait one second at most */ 1343 (void) Lwait(Lwp, MILLISEC); 1344 (void) mutex_lock(&truss_lock); 1345 } 1346 #endif 1347 if (get_bkpt(pc) != Bp) 1348 abend("function_trace: lost breakpoint", NULL); 1349 (void) Pdelbkpt(Proc, Bp->addr, Bp->instr); 1350 Bp->flags &= ~BPT_ACTIVE; 1351 (void) mutex_unlock(&truss_lock); 1352 (void) Lsetrun(Lwp, 0, PRCFAULT|PRSTOP); 1353 /* we're wrapping up; wait one second at most */ 1354 (void) Lwait(Lwp, MILLISEC); 1355 (void) mutex_lock(&truss_lock); 1356 } else { 1357 if (get_bkpt(pc) != Bp) 1358 abend("function_trace: lost breakpoint", NULL); 1359 if (!active || !(Bp->flags & BPT_ACTIVE)) { 1360 (void) Pdelbkpt(Proc, Bp->addr, Bp->instr); 1361 Bp->flags &= ~BPT_ACTIVE; 1362 } 1363 } 1364 return (rval); 1365 } 1366 1367 void 1368 function_entry(private_t *pri, struct bkpt *Bp, struct callstack *Stk) 1369 { 1370 const lwpstatus_t *Lsp = pri->lwpstat; 1371 uintptr_t sp = Lsp->pr_reg[R_SP]; 1372 uintptr_t rpc = get_return_address(&sp); 1373 struct dynlib *Dp = Bp->dyn; 1374 int oldframe = FALSE; 1375 int i; 1376 1377 #ifdef _LP64 1378 if (data_model != PR_MODEL_LP64) { 1379 sp = (uint32_t)sp; 1380 rpc = (uint32_t)rpc; 1381 } 1382 #endif 1383 1384 /* 1385 * If the sp is not within the stack bounds, forget it. 1386 * If the symbol's 'internal' flag is false, 1387 * don't report internal calls within the library. 1388 */ 1389 if (!(sp >= Stk->stkbase && sp < Stk->stkend) || 1390 (!(Bp->flags & BPT_INTERNAL) && 1391 rpc >= Dp->base && rpc < Dp->base + Dp->size)) 1392 return; 1393 1394 for (i = 0; i < Stk->ncall; i++) { 1395 if (sp >= Stk->stack[i].sp) { 1396 Stk->ncall = i; 1397 if (sp == Stk->stack[i].sp) 1398 oldframe = TRUE; 1399 break; 1400 } 1401 } 1402 1403 /* 1404 * Breakpoints for function returns are set here 1405 * If we're counting function calls, there is no need to set 1406 * a breakpoint upon return 1407 */ 1408 1409 if (!oldframe && !cflag) { 1410 (void) create_bkpt(rpc, 1, 1); /* may or may not be set */ 1411 Stk->stack[Stk->ncall].sp = sp; /* record it anyeay */ 1412 Stk->stack[Stk->ncall].pc = rpc; 1413 Stk->stack[Stk->ncall].fcn = Bp; 1414 } 1415 Stk->ncall++; 1416 if (cflag) { 1417 add_fcall(fcall_tbl, Dp->prt_name, Bp->sym_name, 1418 (unsigned long)1); 1419 } else { 1420 show_function_call(pri, Stk, Dp, Bp); 1421 } 1422 } 1423 1424 /* 1425 * We are here because we hit an unnamed breakpoint. 1426 * Attempt to match this up with a return pc on the stack 1427 * and report the function return. 1428 */ 1429 void 1430 function_return(private_t *pri, struct callstack *Stk) 1431 { 1432 const lwpstatus_t *Lsp = pri->lwpstat; 1433 uintptr_t sp = Lsp->pr_reg[R_SP]; 1434 uintptr_t fp = Lsp->pr_reg[R_FP]; 1435 int i; 1436 1437 #ifdef _LP64 1438 if (data_model != PR_MODEL_LP64) { 1439 sp = (uint32_t)sp; 1440 fp = (uint32_t)fp; 1441 } 1442 #endif 1443 1444 if (fp < sp + 8) 1445 fp = sp + 8; 1446 1447 for (i = Stk->ncall - 1; i >= 0; i--) { 1448 if (sp <= Stk->stack[i].sp && fp > Stk->stack[i].sp) { 1449 Stk->ncall = i; 1450 break; 1451 } 1452 } 1453 1454 #if defined(i386) || defined(__amd64) 1455 if (i < 0) { 1456 /* probably __mul64() or friends -- try harder */ 1457 int j; 1458 for (j = 0; i < 0 && j < 8; j++) { /* up to 8 args */ 1459 sp -= 4; 1460 for (i = Stk->ncall - 1; i >= 0; i--) { 1461 if (sp <= Stk->stack[i].sp && 1462 fp > Stk->stack[i].sp) { 1463 Stk->ncall = i; 1464 break; 1465 } 1466 } 1467 } 1468 } 1469 #endif 1470 1471 if ((i >= 0) && (!cflag)) { 1472 show_function_return(pri, Lsp->pr_reg[R_R0], 0, 1473 Stk, Stk->stack[i].fcn->dyn, Stk->stack[i].fcn); 1474 } 1475 } 1476 1477 #if defined(__sparc) 1478 #define FPADJUST 0 1479 #elif defined(__amd64) 1480 #define FPADJUST 8 1481 #elif defined(__i386) 1482 #define FPADJUST 4 1483 #endif 1484 1485 void 1486 trap_one_stack(prgregset_t reg) 1487 { 1488 struct dynlib *Dp; 1489 struct bkpt *Bp; 1490 struct callstack *Stk; 1491 GElf_Sym sym; 1492 char sym_name[32]; 1493 uintptr_t sp = reg[R_SP]; 1494 uintptr_t pc = reg[R_PC]; 1495 uintptr_t fp; 1496 uintptr_t rpc; 1497 uint_t nframe = 0; 1498 uint_t maxframe = 8; 1499 struct { 1500 uintptr_t sp; /* %sp within called function */ 1501 uintptr_t pc; /* %pc within called function */ 1502 uintptr_t rsp; /* the return sp */ 1503 uintptr_t rpc; /* the return pc */ 1504 } *frame = my_malloc(maxframe * sizeof (*frame), NULL); 1505 1506 /* 1507 * Gather stack frames bottom to top. 1508 */ 1509 while (sp != 0) { 1510 fp = sp; /* remember higest non-null sp */ 1511 frame[nframe].sp = sp; 1512 frame[nframe].pc = pc; 1513 sp = previous_fp(sp, &pc); 1514 frame[nframe].rsp = sp; 1515 frame[nframe].rpc = pc; 1516 if (++nframe == maxframe) { 1517 maxframe *= 2; 1518 frame = my_realloc(frame, maxframe * sizeof (*frame), 1519 NULL); 1520 } 1521 } 1522 1523 /* 1524 * Scan for function return breakpoints top to bottom. 1525 */ 1526 while (nframe--) { 1527 /* lookup the called function in the symbol tables */ 1528 if (Plookup_by_addr(Proc, frame[nframe].pc, sym_name, 1529 sizeof (sym_name), &sym) != 0) 1530 continue; 1531 1532 pc = sym.st_value; /* entry point of the function */ 1533 rpc = frame[nframe].rpc; /* caller's return pc */ 1534 1535 /* lookup the function in the breakpoint table */ 1536 if ((Bp = get_bkpt(pc)) == NULL || (Dp = Bp->dyn) == NULL) 1537 continue; 1538 1539 if (!(Bp->flags & BPT_INTERNAL) && 1540 rpc >= Dp->base && rpc < Dp->base + Dp->size) 1541 continue; 1542 1543 sp = frame[nframe].rsp + FPADJUST; /* %sp at time of call */ 1544 if ((Stk = callstack_info(sp, fp, 0)) == NULL) 1545 continue; /* can't happen? */ 1546 1547 if (create_bkpt(rpc, 1, 1) != NULL) { 1548 Stk->stack[Stk->ncall].sp = sp; 1549 Stk->stack[Stk->ncall].pc = rpc; 1550 Stk->stack[Stk->ncall].fcn = Bp; 1551 Stk->ncall++; 1552 } 1553 } 1554 1555 free(frame); 1556 } 1557 1558 int 1559 lwp_stack_traps(void *cd, const lwpstatus_t *Lsp) 1560 { 1561 ph_map_t *ph_map = (ph_map_t *)cd; 1562 prgregset_t reg; 1563 1564 (void) memcpy(reg, Lsp->pr_reg, sizeof (prgregset_t)); 1565 make_lwp_stack(Lsp, ph_map->pmap, ph_map->nmap); 1566 trap_one_stack(reg); 1567 1568 return (interrupt | sigusr1); 1569 } 1570 1571 /* ARGSUSED */ 1572 int 1573 thr_stack_traps(const td_thrhandle_t *Thp, void *cd) 1574 { 1575 prgregset_t reg; 1576 1577 /* 1578 * We have already dealt with all the lwps. 1579 * We only care about unbound threads here (TD_PARTIALREG). 1580 */ 1581 if (td_thr_getgregs(Thp, reg) != TD_PARTIALREG) 1582 return (0); 1583 1584 make_thr_stack(Thp, reg); 1585 trap_one_stack(reg); 1586 1587 return (interrupt | sigusr1); 1588 } 1589 1590 #if defined(__sparc) 1591 1592 uintptr_t 1593 previous_fp(uintptr_t sp, uintptr_t *rpc) 1594 { 1595 uintptr_t fp = 0; 1596 uintptr_t pc = 0; 1597 1598 #ifdef _LP64 1599 if (data_model == PR_MODEL_LP64) { 1600 struct rwindow64 rwin; 1601 if (Pread(Proc, &rwin, sizeof (rwin), sp + STACK_BIAS) 1602 == sizeof (rwin)) { 1603 fp = (uintptr_t)rwin.rw_fp; 1604 pc = (uintptr_t)rwin.rw_rtn; 1605 } 1606 if (fp != 0 && 1607 Pread(Proc, &rwin, sizeof (rwin), fp + STACK_BIAS) 1608 != sizeof (rwin)) 1609 fp = pc = 0; 1610 } else { 1611 struct rwindow32 rwin; 1612 #else /* _LP64 */ 1613 struct rwindow rwin; 1614 #endif /* _LP64 */ 1615 if (Pread(Proc, &rwin, sizeof (rwin), sp) == sizeof (rwin)) { 1616 fp = (uint32_t)rwin.rw_fp; 1617 pc = (uint32_t)rwin.rw_rtn; 1618 } 1619 if (fp != 0 && 1620 Pread(Proc, &rwin, sizeof (rwin), fp) != sizeof (rwin)) 1621 fp = pc = 0; 1622 #ifdef _LP64 1623 } 1624 #endif 1625 if (rpc) 1626 *rpc = pc; 1627 return (fp); 1628 } 1629 1630 /* ARGSUSED */ 1631 uintptr_t 1632 get_return_address(uintptr_t *psp) 1633 { 1634 instr_t inst; 1635 private_t *pri = get_private(); 1636 const lwpstatus_t *Lsp = pri->lwpstat; 1637 uintptr_t rpc; 1638 1639 rpc = (uintptr_t)Lsp->pr_reg[R_O7] + 8; 1640 if (data_model != PR_MODEL_LP64) 1641 rpc = (uint32_t)rpc; 1642 1643 /* check for structure return (bletch!) */ 1644 if (Pread(Proc, &inst, sizeof (inst), rpc) == sizeof (inst) && 1645 inst < 0x1000) 1646 rpc += sizeof (instr_t); 1647 1648 return (rpc); 1649 } 1650 1651 int 1652 get_arguments(long *argp) 1653 { 1654 private_t *pri = get_private(); 1655 const lwpstatus_t *Lsp = pri->lwpstat; 1656 int i; 1657 1658 if (data_model != PR_MODEL_LP64) 1659 for (i = 0; i < 4; i++) 1660 argp[i] = (uint_t)Lsp->pr_reg[R_O0+i]; 1661 else 1662 for (i = 0; i < 4; i++) 1663 argp[i] = (long)Lsp->pr_reg[R_O0+i]; 1664 return (4); 1665 } 1666 1667 #endif /* __sparc */ 1668 1669 #if defined(__i386) || defined(__amd64) 1670 1671 uintptr_t 1672 previous_fp(uintptr_t fp, uintptr_t *rpc) 1673 { 1674 uintptr_t frame[2]; 1675 uintptr_t trash[2]; 1676 1677 if (Pread(Proc, frame, sizeof (frame), fp) != sizeof (frame) || 1678 (frame[0] != 0 && 1679 Pread(Proc, trash, sizeof (trash), frame[0]) != sizeof (trash))) 1680 frame[0] = frame[1] = 0; 1681 1682 if (rpc) 1683 *rpc = frame[1]; 1684 return (frame[0]); 1685 } 1686 1687 #endif 1688 1689 #if defined(__amd64) || defined(__i386) 1690 1691 /* 1692 * Examine the instruction at the return location of a function call 1693 * and return the byte count by which the stack is adjusted on return. 1694 * It the instruction at the return location is an addl, as expected, 1695 * then adjust the return pc by the size of that instruction so that 1696 * we will place the return breakpoint on the following instruction. 1697 * This allows programs that interrogate their own stacks and record 1698 * function calls and arguments to work correctly even while we interfere. 1699 * Return the count on success, -1 on failure. 1700 */ 1701 int 1702 return_count32(uint32_t *ppc) 1703 { 1704 uintptr_t pc = *ppc; 1705 struct bkpt *Bp; 1706 int count; 1707 uchar_t instr[6]; /* instruction at pc */ 1708 1709 if ((count = Pread(Proc, instr, sizeof (instr), pc)) < 0) 1710 return (-1); 1711 1712 /* find the replaced instruction at pc (if any) */ 1713 if ((Bp = get_bkpt(pc)) != NULL && (Bp->flags & BPT_ACTIVE)) 1714 instr[0] = (uchar_t)Bp->instr; 1715 1716 if (count != sizeof (instr) && 1717 (count < 3 || instr[0] != 0x83)) 1718 return (-1); 1719 1720 /* 1721 * A bit of disassembly of the instruction is required here. 1722 */ 1723 if (instr[1] != 0xc4) { /* not an addl mumble,%esp inctruction */ 1724 count = 0; 1725 } else if (instr[0] == 0x81) { /* count is a longword */ 1726 count = instr[2]+(instr[3]<<8)+(instr[4]<<16)+(instr[5]<<24); 1727 *ppc += 6; 1728 } else if (instr[0] == 0x83) { /* count is a byte */ 1729 count = instr[2]; 1730 *ppc += 3; 1731 } else { /* not an addl inctruction */ 1732 count = 0; 1733 } 1734 1735 return (count); 1736 } 1737 1738 uintptr_t 1739 get_return_address32(uintptr_t *psp) 1740 { 1741 uint32_t sp = *psp; 1742 uint32_t rpc; 1743 int count; 1744 1745 *psp += 4; /* account for popping the stack on return */ 1746 if (Pread(Proc, &rpc, sizeof (rpc), sp) != sizeof (rpc)) 1747 return (0); 1748 if ((count = return_count32(&rpc)) < 0) 1749 count = 0; 1750 *psp += count; /* expected sp on return */ 1751 return (rpc); 1752 } 1753 1754 uintptr_t 1755 get_return_address(uintptr_t *psp) 1756 { 1757 #ifdef _LP64 1758 uintptr_t rpc; 1759 uintptr_t sp = *psp; 1760 1761 if (data_model == PR_MODEL_LP64) { 1762 if (Pread(Proc, &rpc, sizeof (rpc), sp) != sizeof (rpc)) 1763 return (0); 1764 /* 1765 * Ignore arguments pushed on the stack. See comments in 1766 * get_arguments(). 1767 */ 1768 return (rpc); 1769 } else 1770 #endif 1771 return (get_return_address32(psp)); 1772 } 1773 1774 1775 int 1776 get_arguments32(long *argp) 1777 { 1778 private_t *pri = get_private(); 1779 const lwpstatus_t *Lsp = pri->lwpstat; 1780 uint32_t frame[5]; /* return pc + 4 args */ 1781 int narg; 1782 int count; 1783 int i; 1784 1785 narg = Pread(Proc, frame, sizeof (frame), 1786 (uintptr_t)Lsp->pr_reg[R_SP]); 1787 narg -= sizeof (greg32_t); 1788 if (narg <= 0) 1789 return (0); 1790 narg /= sizeof (greg32_t); /* no more than 4 */ 1791 1792 /* 1793 * Given the return PC, determine the number of arguments. 1794 */ 1795 if ((count = return_count32(&frame[0])) < 0) 1796 narg = 0; 1797 else { 1798 count /= sizeof (greg32_t); 1799 if (narg > count) 1800 narg = count; 1801 } 1802 1803 for (i = 0; i < narg; i++) 1804 argp[i] = (long)frame[i+1]; 1805 1806 return (narg); 1807 } 1808 1809 int 1810 get_arguments(long *argp) 1811 { 1812 #ifdef _LP64 1813 private_t *pri = get_private(); 1814 const lwpstatus_t *Lsp = pri->lwpstat; 1815 1816 if (data_model == PR_MODEL_LP64) { 1817 /* 1818 * On amd64, we do not know how many arguments are passed to 1819 * each function. While it may be possible to detect if we 1820 * have more than 6 arguments, it is of marginal value. 1821 * Instead, assume that we always have 6 arguments, which are 1822 * passed via registers. 1823 */ 1824 argp[0] = Lsp->pr_reg[REG_RDI]; 1825 argp[1] = Lsp->pr_reg[REG_RSI]; 1826 argp[2] = Lsp->pr_reg[REG_RDX]; 1827 argp[3] = Lsp->pr_reg[REG_RCX]; 1828 argp[4] = Lsp->pr_reg[REG_R8]; 1829 argp[5] = Lsp->pr_reg[REG_R9]; 1830 return (6); 1831 } else 1832 #endif 1833 return (get_arguments32(argp)); 1834 } 1835 1836 #endif /* __amd64 || __i386 */ 1837