Print this page
8158 Want named threads API
9857 proc manpages should have LIBRARY section

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/ptools/pstack/pstack.c
          +++ new/usr/src/cmd/ptools/pstack/pstack.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
       24 + *
       25 + * Copyright 2018 Joyent, Inc.
  24   26   */
  25   27  
  26   28  #include <sys/isa_defs.h>
  27   29  
  28   30  #include <stdio.h>
  29   31  #include <stdio_ext.h>
  30   32  #include <fcntl.h>
  31   33  #include <ctype.h>
  32   34  #include <string.h>
  33   35  #include <signal.h>
↓ open down ↓ 96 lines elided ↑ open up ↑
 130  132          int ignore_frame;
 131  133          const char *lwps;
 132  134          int count;
 133  135          pydb_agent_t *pydb;
 134  136  } pstack_handle_t;
 135  137  
 136  138  static  int     thr_stack(const td_thrhandle_t *, void *);
 137  139  static  void    free_threadinfo(void);
 138  140  static  struct threadinfo *find_thread(id_t);
 139  141  static  int     all_call_stacks(pstack_handle_t *, int);
 140      -static  void    tlhead(id_t, id_t);
      142 +static  void    tlhead(id_t, id_t, const char *);
 141  143  static  int     print_frame(void *, prgregset_t, uint_t, const long *);
 142  144  static  void    print_zombie(struct ps_prochandle *, struct threadinfo *);
 143  145  static  void    print_syscall(const lwpstatus_t *, prgregset_t);
 144  146  static  void    call_stack(pstack_handle_t *, const lwpstatus_t *);
 145  147  
 146  148  /*
 147  149   * The number of active and zombie threads.
 148  150   */
 149  151  static  int     nthreads;
 150  152  
↓ open down ↓ 222 lines elided ↑ open up ↑
 373  375                          return (tip);
 374  376                  }
 375  377          }
 376  378          return (NULL);
 377  379  }
 378  380  
 379  381  static int
 380  382  thread_call_stack(void *data, const lwpstatus_t *psp,
 381  383      const lwpsinfo_t *pip)
 382  384  {
      385 +        char lwpname[THREAD_NAME_MAX] = "";
 383  386          pstack_handle_t *h = data;
 384  387          lwpstatus_t lwpstatus;
 385  388          struct threadinfo *tip;
 386  389  
 387  390          if (!proc_lwp_in_set(h->lwps, pip->pr_lwpid))
 388  391                  return (0);
 389  392          h->count++;
 390  393  
 391  394          if ((tip = find_thread(pip->pr_lwpid)) == NULL)
 392  395                  return (0);
 393  396  
 394      -        tlhead(tip->threadid, pip->pr_lwpid);
      397 +        (void) Plwp_getname(h->proc, pip->pr_lwpid,
      398 +            lwpname, sizeof (lwpname));
      399 +
      400 +        tlhead(tip->threadid, pip->pr_lwpid, lwpname);
 395  401          tip->threadid = 0;      /* finish eliminating tid */
 396  402          if (psp)
 397  403                  call_stack(h, psp);
 398  404          else {
 399  405                  if (tip->state == TD_THR_ZOMBIE)
 400  406                          print_zombie(h->proc, tip);
 401  407                  else {
 402  408                          (void) memset(&lwpstatus, 0, sizeof (lwpstatus));
 403  409                          (void) memcpy(lwpstatus.pr_reg, tip->regs,
 404  410                              sizeof (prgregset_t));
 405  411                          call_stack(h, &lwpstatus);
 406  412                  }
 407  413          }
 408  414          return (0);
 409  415  }
 410  416  
 411  417  static int
 412  418  lwp_call_stack(void *data,
 413      -        const lwpstatus_t *psp, const lwpsinfo_t *pip)
      419 +    const lwpstatus_t *psp, const lwpsinfo_t *pip)
 414  420  {
      421 +        char lwpname[THREAD_NAME_MAX] = "";
 415  422          pstack_handle_t *h = data;
 416  423  
 417  424          if (!proc_lwp_in_set(h->lwps, pip->pr_lwpid))
 418  425                  return (0);
 419  426          h->count++;
 420  427  
 421      -        tlhead(0, pip->pr_lwpid);
      428 +        (void) Plwp_getname(h->proc, pip->pr_lwpid,
      429 +            lwpname, sizeof (lwpname));
      430 +
      431 +        tlhead(0, pip->pr_lwpid, lwpname);
 422  432          if (psp)
 423  433                  call_stack(h, psp);
 424  434          else
 425  435                  (void) printf("\t** zombie "
 426  436                      "(exited, not detached, not yet joined) **\n");
 427  437          return (0);
 428  438  }
 429  439  
 430  440  static int
 431  441  all_call_stacks(pstack_handle_t *h, int dothreads)
↓ open down ↓ 23 lines elided ↑ open up ↑
 455  465                  /* for each remaining thread w/o an lwp */
 456  466                  (void) memset(&lwpstatus, 0, sizeof (lwpstatus));
 457  467                  for (tip = thr_head; tip; tip = tip->next) {
 458  468  
 459  469                          if (!proc_lwp_in_set(h->lwps, tip->lwpid))
 460  470                                  tip->threadid = 0;
 461  471  
 462  472                          if ((tid = tip->threadid) != 0) {
 463  473                                  (void) memcpy(lwpstatus.pr_reg, tip->regs,
 464  474                                      sizeof (prgregset_t));
 465      -                                tlhead(tid, tip->lwpid);
      475 +                                tlhead(tid, tip->lwpid, NULL);
 466  476                                  if (tip->state == TD_THR_ZOMBIE)
 467  477                                          print_zombie(Pr, tip);
 468  478                                  else
 469  479                                          call_stack(h, &lwpstatus);
 470  480                          }
 471  481                          tip->threadid = 0;
 472  482                          tip->lwpid = 0;
 473  483                  }
 474  484          }
 475  485          return (0);
 476  486  }
 477  487  
      488 +/* The width of the header */
      489 +#define HEAD_WIDTH      (62)
 478  490  static void
 479      -tlhead(id_t threadid, id_t lwpid)
      491 +tlhead(id_t threadid, id_t lwpid, const char *name)
 480  492  {
      493 +        char buf[128] = { 0 };
      494 +        char num[16];
      495 +        ssize_t amt = 0;
      496 +        int i;
      497 +
 481  498          if (threadid == 0 && lwpid == 0)
 482  499                  return;
 483  500  
 484      -        (void) printf("-----------------");
      501 +        if (lwpid > 0) {
      502 +                (void) snprintf(num, sizeof (num), "%d", (int)lwpid);
      503 +                (void) strlcat(buf, "thread# ", sizeof (buf));
      504 +                (void) strlcat(buf, num, sizeof (buf));
      505 +        }
 485  506  
 486      -        if (threadid && lwpid)
 487      -                (void) printf("  lwp# %d / thread# %d  ",
 488      -                    (int)lwpid, (int)threadid);
 489      -        else if (threadid)
 490      -                (void) printf("---------  thread# %d  ", (int)threadid);
 491      -        else if (lwpid)
 492      -                (void) printf("  lwp# %d  ------------", (int)lwpid);
      507 +        if (threadid > 0) {
      508 +                (void) snprintf(num, sizeof (num), "%d", (int)threadid);
      509 +                if (lwpid > 0)
      510 +                        (void) strlcat(buf, " / ", sizeof (buf));
      511 +                (void) strlcat(buf, "lwp# ", sizeof (buf));
      512 +                (void) strlcat(buf, num, sizeof (buf));
      513 +        }
 493  514  
 494      -        (void) printf("--------------------\n");
      515 +        if (name != NULL && strlen(name) > 0) {
      516 +                (void) strlcat(buf, " [", sizeof (buf));
      517 +                (void) strlcat(buf, name, sizeof (buf));
      518 +                (void) strlcat(buf, "]", sizeof (buf));
      519 +        }
      520 +
      521 +        amt = (HEAD_WIDTH - strlen(buf) - 2);
      522 +        if (amt < 4)
      523 +                amt = 4;
      524 +
      525 +        for (i = 0; i < amt / 2; i++)
      526 +                (void) putc('-', stdout);
      527 +        (void) printf(" %s ", buf);
      528 +        for (i = 0; i < (amt / 2) + (amt % 2); i++)
      529 +                (void) putc('-', stdout);
      530 +        (void) putc('\n', stdout);
 495  531  }
 496  532  
 497  533  /*ARGSUSED*/
 498  534  static int
 499  535  print_java_frame(void *cld, prgregset_t gregs, const char *name, int bci,
 500  536      int line, void *handle)
 501  537  {
 502  538          int length = (is64 ? 16 : 8);
 503  539  
 504  540          (void) printf(" %.*lx * %s", length, (long)gregs[R_PC], name);
↓ open down ↓ 343 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX