Print this page
4474 DTrace Userland CTF Support
4475 DTrace userland Keyword
4476 DTrace tests should be better citizens
4479 pid provider types
4480 dof emulation missing checks
Reviewed by: Bryan Cantrill <bryan@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libdtrace/common/dt_pid.c
          +++ new/usr/src/lib/libdtrace/common/dt_pid.c
↓ open down ↓ 15 lines elided ↑ open up ↑
  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 2010 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
       26 +/*
       27 + * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
       28 + */
  26   29  
  27   30  #include <assert.h>
  28   31  #include <strings.h>
  29   32  #include <stdlib.h>
  30   33  #include <stdio.h>
  31   34  #include <errno.h>
  32   35  #include <ctype.h>
  33   36  #include <alloca.h>
  34   37  #include <libgen.h>
  35   38  #include <stddef.h>
       39 +#include <sys/sysmacros.h>
  36   40  
  37   41  #include <dt_impl.h>
  38   42  #include <dt_program.h>
  39   43  #include <dt_pid.h>
  40   44  #include <dt_string.h>
       45 +#include <dt_module.h>
  41   46  
  42   47  typedef struct dt_pid_probe {
  43   48          dtrace_hdl_t *dpp_dtp;
  44   49          dt_pcb_t *dpp_pcb;
  45   50          dt_proc_t *dpp_dpr;
  46   51          struct ps_prochandle *dpp_pr;
  47   52          const char *dpp_mod;
  48   53          char *dpp_func;
  49   54          const char *dpp_name;
  50   55          const char *dpp_obj;
↓ open down ↓ 697 lines elided ↑ open up ↑
 748  753          if (found) {
 749  754                  /*
 750  755                   * Give DTrace a shot to the ribs to get it to check
 751  756                   * out the newly created probes.
 752  757                   */
 753  758                  (void) dt_ioctl(dtp, DTRACEIOC_ENABLE, NULL);
 754  759          }
 755  760  
 756  761          return (ret);
 757  762  }
      763 +
      764 +/*
      765 + * libdtrace has a backroom deal with us to ask us for type information on
      766 + * behalf of pid provider probes when fasttrap doesn't return any type
      767 + * information. Instead we'll look up the module and see if there is type
      768 + * information available. However, if there is no type information available due
      769 + * to a lack of CTF data, then we want to make sure that DTrace still carries on
      770 + * in face of that. As such we don't have a meaningful exit code about failure.
      771 + * We emit information about why we failed to the dtrace debug log so someone
      772 + * can figure it out by asking nicely for DTRACE_DEBUG.
      773 + */
      774 +void
      775 +dt_pid_get_types(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
      776 +    dtrace_argdesc_t *adp, int *nargs)
      777 +{
      778 +        dt_module_t *dmp;
      779 +        ctf_file_t *fp;
      780 +        ctf_funcinfo_t f;
      781 +        ctf_id_t argv[32];
      782 +        GElf_Sym sym;
      783 +        prsyminfo_t si;
      784 +        struct ps_prochandle *p;
      785 +        int i, args;
      786 +        char buf[DTRACE_ARGTYPELEN];
      787 +        const char *mptr;
      788 +        char *eptr;
      789 +        int ret = 0;
      790 +        int argc = sizeof (argv) / sizeof (ctf_id_t);
      791 +        Lmid_t lmid;
      792 +
      793 +        /* Set up a potential outcome */
      794 +        args = *nargs;
      795 +        *nargs = 0;
      796 +
      797 +        /*
      798 +         * If we don't have an entry or return probe then we can just stop right
      799 +         * now as we don't have arguments for offset probes.
      800 +         */
      801 +        if (strcmp(pdp->dtpd_name, "entry") != 0 &&
      802 +            strcmp(pdp->dtpd_name, "return") != 0)
      803 +                return;
      804 +
      805 +        dmp = dt_module_create(dtp, pdp->dtpd_provider);
      806 +        if (dmp == NULL) {
      807 +                dt_dprintf("failed to find module for %s\n",
      808 +                    pdp->dtpd_provider);
      809 +                return;
      810 +        }
      811 +        if (dt_module_load(dtp, dmp) != 0) {
      812 +                dt_dprintf("failed to load module for %s\n",
      813 +                    pdp->dtpd_provider);
      814 +                return;
      815 +        }
      816 +
      817 +        /*
      818 +         * We may be working with a module that doesn't have ctf. If that's the
      819 +         * case then we just return now and move on with life.
      820 +         */
      821 +        fp = dt_module_getctflib(dtp, dmp, pdp->dtpd_mod);
      822 +        if (fp == NULL) {
      823 +                dt_dprintf("no ctf container for  %s\n",
      824 +                    pdp->dtpd_mod);
      825 +                return;
      826 +        }
      827 +        p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE);
      828 +        if (p == NULL) {
      829 +                dt_dprintf("failed to grab pid\n");
      830 +                return;
      831 +        }
      832 +        dt_proc_lock(dtp, p);
      833 +
      834 +        /*
      835 +         * Check to see if the D module has a link map ID and separate that out
      836 +         * for properly interrogating libproc.
      837 +         */
      838 +        if ((mptr = strchr(pdp->dtpd_mod, '`')) != NULL) {
      839 +                if (strlen(pdp->dtpd_mod) < 3) {
      840 +                        dt_dprintf("found weird modname with linkmap, "
      841 +                            "aborting: %s\n", pdp->dtpd_mod);
      842 +                        goto out;
      843 +                }
      844 +                if (pdp->dtpd_mod[0] != 'L' || pdp->dtpd_mod[1] != 'M') {
      845 +                        dt_dprintf("missing leading 'LM', "
      846 +                            "aborting: %s\n", pdp->dtpd_mod);
      847 +                        goto out;
      848 +                }
      849 +                errno = 0;
      850 +                lmid = strtol(pdp->dtpd_mod + 2, &eptr, 16);
      851 +                if (errno == ERANGE || eptr != mptr) {
      852 +                        dt_dprintf("failed to parse out lmid, aborting: %s\n",
      853 +                            pdp->dtpd_mod);
      854 +                        goto out;
      855 +                }
      856 +                mptr++;
      857 +        } else {
      858 +                mptr = pdp->dtpd_mod;
      859 +                lmid = 0;
      860 +        }
      861 +
      862 +        if (Pxlookup_by_name(p, lmid, mptr, pdp->dtpd_func,
      863 +            &sym, &si) != 0) {
      864 +                dt_dprintf("failed to find function %s in %s`%s\n",
      865 +                    pdp->dtpd_func, pdp->dtpd_provider, pdp->dtpd_mod);
      866 +                goto out;
      867 +        }
      868 +        if (ctf_func_info(fp, si.prs_id, &f) == CTF_ERR) {
      869 +                dt_dprintf("failed to get ctf information for %s in %s`%s\n",
      870 +                    pdp->dtpd_func, pdp->dtpd_provider, pdp->dtpd_mod);
      871 +                goto out;
      872 +        }
      873 +
      874 +        (void) snprintf(buf, sizeof (buf), "%s`%s", pdp->dtpd_provider,
      875 +            pdp->dtpd_mod);
      876 +
      877 +        if (strcmp(pdp->dtpd_name, "return") == 0) {
      878 +                if (args < 2)
      879 +                        goto out;
      880 +
      881 +                bzero(adp, sizeof (dtrace_argdesc_t));
      882 +                adp->dtargd_ndx = 0;
      883 +                adp->dtargd_id = pdp->dtpd_id;
      884 +                adp->dtargd_mapping = adp->dtargd_ndx;
      885 +                /*
      886 +                 * We explicitly leave out the library here, we only care that
      887 +                 * it is some int. We are assuming that there is no ctf
      888 +                 * container in here that is lying about what an int is.
      889 +                 */
      890 +                (void) snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
      891 +                    "user %s`%s", pdp->dtpd_provider, "int");
      892 +                adp++;
      893 +                bzero(adp, sizeof (dtrace_argdesc_t));
      894 +                adp->dtargd_ndx = 1;
      895 +                adp->dtargd_id = pdp->dtpd_id;
      896 +                adp->dtargd_mapping = adp->dtargd_ndx;
      897 +                ret = snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
      898 +                    "userland ");
      899 +                (void) ctf_type_qname(fp, f.ctc_return, adp->dtargd_native +
      900 +                    ret, DTRACE_ARGTYPELEN - ret, buf);
      901 +                *nargs = 2;
      902 +        } else {
      903 +                if (ctf_func_args(fp, si.prs_id, argc, argv) == CTF_ERR)
      904 +                        goto out;
      905 +
      906 +                *nargs = MIN(args, f.ctc_argc);
      907 +                for (i = 0; i < *nargs; i++, adp++) {
      908 +                        bzero(adp, sizeof (dtrace_argdesc_t));
      909 +                        adp->dtargd_ndx = i;
      910 +                        adp->dtargd_id = pdp->dtpd_id;
      911 +                        adp->dtargd_mapping = adp->dtargd_ndx;
      912 +                        ret = snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
      913 +                            "userland ");
      914 +                        (void) ctf_type_qname(fp, argv[i], adp->dtargd_native +
      915 +                            ret, DTRACE_ARGTYPELEN - ret, buf);
      916 +                }
      917 +        }
      918 +out:
      919 +        dt_proc_unlock(dtp, p);
      920 +        dt_proc_release(dtp, p);
      921 +}
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX