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/mdb/common/modules/genunix/findstack.c
          +++ new/usr/src/cmd/mdb/common/modules/genunix/findstack.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  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  /*
  23   23   * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright (c) 2013, Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
       25 + * Copyright 2018 Joyent, Inc.
  25   26   */
  26   27  
  27   28  #include <mdb/mdb_modapi.h>
  28   29  #include <mdb/mdb_ctf.h>
  29   30  
  30   31  #include <sys/types.h>
  31   32  #include <sys/regset.h>
  32   33  #include <sys/stack.h>
  33   34  #include <sys/thread.h>
  34   35  #include <sys/modctl.h>
  35   36  #include <assert.h>
  36   37  
  37   38  #include "findstack.h"
  38   39  #include "thread.h"
  39   40  #include "sobj.h"
  40   41  
       42 +/*
       43 + * Parts of this file are shared between targets, but this section is only
       44 + * used for KVM and KMDB.
       45 + */
       46 +#ifdef _KERNEL
       47 +
  41   48  int findstack_debug_on = 0;
  42   49  
  43   50  /*
  44   51   * "sp" is a kernel VA.
  45   52   */
  46   53  static int
  47   54  print_stack(uintptr_t sp, uintptr_t pc, uintptr_t addr,
  48   55      int argc, const mdb_arg_t *argv, int free_state)
  49   56  {
  50   57          int showargs = 0, count, err;
       58 +        char tdesc[128] = "";
  51   59  
  52   60          count = mdb_getopts(argc, argv,
  53   61              'v', MDB_OPT_SETBITS, TRUE, &showargs, NULL);
  54   62          argc -= count;
  55   63          argv += count;
  56   64  
  57   65          if (argc > 1 || (argc == 1 && argv->a_type != MDB_TYPE_STRING))
  58   66                  return (DCMD_USAGE);
  59   67  
  60      -        mdb_printf("stack pointer for thread %p%s: %p\n",
  61      -            addr, (free_state ? " (TS_FREE)" : ""), sp);
       68 +        (void) thread_getdesc(addr, B_TRUE, tdesc, sizeof (tdesc));
       69 +
       70 +        mdb_printf("stack pointer for thread %p%s (%s): %p\n",
       71 +            addr, (free_state ? " (TS_FREE)" : ""), tdesc, sp);
  62   72          if (pc != 0)
  63   73                  mdb_printf("[ %0?lr %a() ]\n", sp, pc);
  64   74  
  65   75          mdb_inc_indent(2);
  66   76          mdb_set_dot(sp);
  67   77  
  68   78          if (argc == 1)
  69   79                  err = mdb_eval(argv->a_un.a_str);
  70   80          else if (showargs)
  71   81                  err = mdb_eval("<.$C");
↓ open down ↓ 29 lines elided ↑ open up ↑
 101  111  findstack_debug(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *av)
 102  112  {
 103  113          findstack_debug_on ^= 1;
 104  114  
 105  115          mdb_printf("findstack: debugging is now %s\n",
 106  116              findstack_debug_on ? "on" : "off");
 107  117  
 108  118          return (DCMD_OK);
 109  119  }
 110  120  
      121 +#endif /* _KERNEL */
      122 +
 111  123  static void
 112  124  uppercase(char *p)
 113  125  {
 114  126          for (; *p != '\0'; p++) {
 115  127                  if (*p >= 'a' && *p <= 'z')
 116  128                          *p += 'A' - 'a';
 117  129          }
 118  130  }
 119  131  
 120  132  static void
↓ open down ↓ 69 lines elided ↑ open up ↑
 190  202  
 191  203  /* global state cached between invocations */
 192  204  #define STACKS_STATE_CLEAN      0
 193  205  #define STACKS_STATE_DIRTY      1
 194  206  #define STACKS_STATE_DONE       2
 195  207  static uint_t stacks_state = STACKS_STATE_CLEAN;
 196  208  static stacks_entry_t **stacks_hash;
 197  209  static stacks_entry_t **stacks_array;
 198  210  static size_t stacks_array_size;
 199  211  
 200      -size_t
      212 +static size_t
 201  213  stacks_hash_entry(stacks_entry_t *sep)
 202  214  {
 203  215          size_t depth = sep->se_depth;
 204  216          uintptr_t *stack = sep->se_stack;
 205  217  
 206  218          uint64_t total = depth;
 207  219  
 208  220          while (depth > 0) {
 209  221                  total += *stack;
 210  222                  stack++; depth--;
↓ open down ↓ 6 lines elided ↑ open up ↑
 217  229   * This is used to both compare stacks for equality and to sort the final
 218  230   * list of unique stacks.  forsort specifies the latter behavior, which
 219  231   * additionally:
 220  232   *      compares se_count, and
 221  233   *      sorts the stacks by text function name.
 222  234   *
 223  235   * The equality test is independent of se_count, and doesn't care about
 224  236   * relative ordering, so we don't do the extra work of looking up symbols
 225  237   * for the stack addresses.
 226  238   */
 227      -int
      239 +static int
 228  240  stacks_entry_comp_impl(stacks_entry_t *l, stacks_entry_t *r,
 229  241      uint_t forsort)
 230  242  {
 231  243          int idx;
 232  244  
 233  245          int depth = MIN(l->se_depth, r->se_depth);
 234  246  
 235  247          /* no matter what, panic stacks come last. */
 236  248          if (l->se_panic > r->se_panic)
 237  249                  return (1);
↓ open down ↓ 53 lines elided ↑ open up ↑
 291  303                  return (-1);
 292  304  
 293  305          if (l->se_sobj_ops > r->se_sobj_ops)
 294  306                  return (1);
 295  307          if (l->se_sobj_ops < r->se_sobj_ops)
 296  308                  return (-1);
 297  309  
 298  310          return (0);
 299  311  }
 300  312  
 301      -int
      313 +static int
 302  314  stacks_entry_comp(const void *l_arg, const void *r_arg)
 303  315  {
 304  316          stacks_entry_t * const *lp = l_arg;
 305  317          stacks_entry_t * const *rp = r_arg;
 306  318  
 307  319          return (stacks_entry_comp_impl(*lp, *rp, 1));
 308  320  }
 309  321  
 310  322  void
 311  323  stacks_cleanup(int force)
↓ open down ↓ 49 lines elided ↑ open up ↑
 361  373  
 362  374          stacks_findstack_cleanup();
 363  375  
 364  376          stacks_array_size = 0;
 365  377          stacks_state = STACKS_STATE_CLEAN;
 366  378          stacks_hash = NULL;
 367  379          stacks_array = NULL;
 368  380  }
 369  381  
 370  382  /*ARGSUSED*/
 371      -int
      383 +static int
 372  384  stacks_thread_cb(uintptr_t addr, const void *ignored, void *cbarg)
 373  385  {
 374  386          stacks_info_t *sip = cbarg;
 375  387          findstack_info_t *fsip = &sip->si_fsi;
 376  388  
 377  389          stacks_entry_t **sepp, *nsep, *sep;
 378  390          int idx;
 379  391          size_t depth;
 380  392  
 381  393          if (stacks_findstack(addr, fsip, 0) != DCMD_OK &&
↓ open down ↓ 32 lines elided ↑ open up ↑
 414  426                  return (WALK_NEXT);
 415  427          }
 416  428  
 417  429          nsep->se_next = NULL;
 418  430          *sepp = nsep;
 419  431          sip->si_entries++;
 420  432  
 421  433          return (WALK_NEXT);
 422  434  }
 423  435  
 424      -int
      436 +static int
 425  437  stacks_run_tlist(mdb_pipe_t *tlist, stacks_info_t *si)
 426  438  {
 427  439          size_t idx;
 428  440          size_t found = 0;
 429  441          int ret;
 430  442  
 431  443          for (idx = 0; idx < tlist->pipe_len; idx++) {
 432  444                  uintptr_t addr = tlist->pipe_data[idx];
 433  445  
 434  446                  found++;
↓ open down ↓ 3 lines elided ↑ open up ↑
 438  450                          break;
 439  451                  if (ret != WALK_NEXT)
 440  452                          return (-1);
 441  453          }
 442  454  
 443  455          if (found)
 444  456                  return (0);
 445  457          return (-1);
 446  458  }
 447  459  
 448      -int
      460 +static int
 449  461  stacks_run(int verbose, mdb_pipe_t *tlist)
 450  462  {
 451  463          stacks_info_t si;
 452  464          findstack_info_t *fsip = &si.si_fsi;
 453  465          size_t idx;
 454  466          stacks_entry_t **cur;
 455  467  
 456  468          bzero(&si, sizeof (si));
 457  469  
 458  470          stacks_state = STACKS_STATE_DIRTY;
↓ open down ↓ 449 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX