Deleted Added
full compact
dt_pid.c (256281) dt_pid.c (268578)
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 9 unchanged lines hidden (view full) ---

18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 9 unchanged lines hidden (view full) ---

18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26/*
27 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
28 */
26
27#include <assert.h>
28#include <strings.h>
29#include <stdlib.h>
30#include <stdio.h>
31#include <errno.h>
32#include <ctype.h>
33#if defined(sun)
34#include <alloca.h>
35#endif
36#include <libgen.h>
37#include <stddef.h>
29
30#include <assert.h>
31#include <strings.h>
32#include <stdlib.h>
33#include <stdio.h>
34#include <errno.h>
35#include <ctype.h>
36#if defined(sun)
37#include <alloca.h>
38#endif
39#include <libgen.h>
40#include <stddef.h>
41#include <sys/sysmacros.h>
38
39#include <dt_impl.h>
40#include <dt_program.h>
41#include <dt_pid.h>
42#include <dt_string.h>
43#if !defined(sun)
44#include <libproc_compat.h>
45#endif
42
43#include <dt_impl.h>
44#include <dt_program.h>
45#include <dt_pid.h>
46#include <dt_string.h>
47#if !defined(sun)
48#include <libproc_compat.h>
49#endif
50#include <dt_module.h>
46
47typedef struct dt_pid_probe {
48 dtrace_hdl_t *dpp_dtp;
49 dt_pcb_t *dpp_pcb;
50 dt_proc_t *dpp_dpr;
51 struct ps_prochandle *dpp_pr;
52 const char *dpp_mod;
53 char *dpp_func;

--- 768 unchanged lines hidden (view full) ---

822 */
823 args.dof = NULL;
824 args.n_matched = 0;
825 (void) dt_ioctl(dtp, DTRACEIOC_ENABLE, &args);
826 }
827
828 return (ret);
829}
51
52typedef struct dt_pid_probe {
53 dtrace_hdl_t *dpp_dtp;
54 dt_pcb_t *dpp_pcb;
55 dt_proc_t *dpp_dpr;
56 struct ps_prochandle *dpp_pr;
57 const char *dpp_mod;
58 char *dpp_func;

--- 768 unchanged lines hidden (view full) ---

827 */
828 args.dof = NULL;
829 args.n_matched = 0;
830 (void) dt_ioctl(dtp, DTRACEIOC_ENABLE, &args);
831 }
832
833 return (ret);
834}
835
836/*
837 * libdtrace has a backroom deal with us to ask us for type information on
838 * behalf of pid provider probes when fasttrap doesn't return any type
839 * information. Instead we'll look up the module and see if there is type
840 * information available. However, if there is no type information available due
841 * to a lack of CTF data, then we want to make sure that DTrace still carries on
842 * in face of that. As such we don't have a meaningful exit code about failure.
843 * We emit information about why we failed to the dtrace debug log so someone
844 * can figure it out by asking nicely for DTRACE_DEBUG.
845 */
846void
847dt_pid_get_types(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
848 dtrace_argdesc_t *adp, int *nargs)
849{
850 dt_module_t *dmp;
851 ctf_file_t *fp;
852 ctf_funcinfo_t f;
853 ctf_id_t argv[32];
854 GElf_Sym sym;
855#if defined(sun)
856 prsyminfo_t si;
857#else
858 void *si;
859#endif
860 struct ps_prochandle *p;
861 int i, args;
862 char buf[DTRACE_ARGTYPELEN];
863 const char *mptr;
864 char *eptr;
865 int ret = 0;
866 int argc = sizeof (argv) / sizeof (ctf_id_t);
867 Lmid_t lmid;
868
869 /* Set up a potential outcome */
870 args = *nargs;
871 *nargs = 0;
872
873 /*
874 * If we don't have an entry or return probe then we can just stop right
875 * now as we don't have arguments for offset probes.
876 */
877 if (strcmp(pdp->dtpd_name, "entry") != 0 &&
878 strcmp(pdp->dtpd_name, "return") != 0)
879 return;
880
881 dmp = dt_module_create(dtp, pdp->dtpd_provider);
882 if (dmp == NULL) {
883 dt_dprintf("failed to find module for %s\n",
884 pdp->dtpd_provider);
885 return;
886 }
887 if (dt_module_load(dtp, dmp) != 0) {
888 dt_dprintf("failed to load module for %s\n",
889 pdp->dtpd_provider);
890 return;
891 }
892
893 /*
894 * We may be working with a module that doesn't have ctf. If that's the
895 * case then we just return now and move on with life.
896 */
897 fp = dt_module_getctflib(dtp, dmp, pdp->dtpd_mod);
898 if (fp == NULL) {
899 dt_dprintf("no ctf container for %s\n",
900 pdp->dtpd_mod);
901 return;
902 }
903 p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE);
904 if (p == NULL) {
905 dt_dprintf("failed to grab pid\n");
906 return;
907 }
908 dt_proc_lock(dtp, p);
909
910 /*
911 * Check to see if the D module has a link map ID and separate that out
912 * for properly interrogating libproc.
913 */
914 if ((mptr = strchr(pdp->dtpd_mod, '`')) != NULL) {
915 if (strlen(pdp->dtpd_mod) < 3) {
916 dt_dprintf("found weird modname with linkmap, "
917 "aborting: %s\n", pdp->dtpd_mod);
918 goto out;
919 }
920 if (pdp->dtpd_mod[0] != 'L' || pdp->dtpd_mod[1] != 'M') {
921 dt_dprintf("missing leading 'LM', "
922 "aborting: %s\n", pdp->dtpd_mod);
923 goto out;
924 }
925 errno = 0;
926 lmid = strtol(pdp->dtpd_mod + 2, &eptr, 16);
927 if (errno == ERANGE || eptr != mptr) {
928 dt_dprintf("failed to parse out lmid, aborting: %s\n",
929 pdp->dtpd_mod);
930 goto out;
931 }
932 mptr++;
933 } else {
934 mptr = pdp->dtpd_mod;
935 lmid = 0;
936 }
937
938 if (Pxlookup_by_name(p, lmid, mptr, pdp->dtpd_func,
939 &sym, &si) != 0) {
940 dt_dprintf("failed to find function %s in %s`%s\n",
941 pdp->dtpd_func, pdp->dtpd_provider, pdp->dtpd_mod);
942 goto out;
943 }
944#if defined(sun)
945 if (ctf_func_info(fp, si.prs_id, &f) == CTF_ERR) {
946 dt_dprintf("failed to get ctf information for %s in %s`%s\n",
947 pdp->dtpd_func, pdp->dtpd_provider, pdp->dtpd_mod);
948 goto out;
949 }
950#endif
951
952 (void) snprintf(buf, sizeof (buf), "%s`%s", pdp->dtpd_provider,
953 pdp->dtpd_mod);
954
955 if (strcmp(pdp->dtpd_name, "return") == 0) {
956 if (args < 2)
957 goto out;
958
959 bzero(adp, sizeof (dtrace_argdesc_t));
960 adp->dtargd_ndx = 0;
961 adp->dtargd_id = pdp->dtpd_id;
962 adp->dtargd_mapping = adp->dtargd_ndx;
963 /*
964 * We explicitly leave out the library here, we only care that
965 * it is some int. We are assuming that there is no ctf
966 * container in here that is lying about what an int is.
967 */
968 (void) snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
969 "user %s`%s", pdp->dtpd_provider, "int");
970 adp++;
971 bzero(adp, sizeof (dtrace_argdesc_t));
972 adp->dtargd_ndx = 1;
973 adp->dtargd_id = pdp->dtpd_id;
974 adp->dtargd_mapping = adp->dtargd_ndx;
975 ret = snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
976 "userland ");
977 (void) ctf_type_qname(fp, f.ctc_return, adp->dtargd_native +
978 ret, DTRACE_ARGTYPELEN - ret, buf);
979 *nargs = 2;
980#if defined(sun)
981 } else {
982 if (ctf_func_args(fp, si.prs_id, argc, argv) == CTF_ERR)
983 goto out;
984
985 *nargs = MIN(args, f.ctc_argc);
986 for (i = 0; i < *nargs; i++, adp++) {
987 bzero(adp, sizeof (dtrace_argdesc_t));
988 adp->dtargd_ndx = i;
989 adp->dtargd_id = pdp->dtpd_id;
990 adp->dtargd_mapping = adp->dtargd_ndx;
991 ret = snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN,
992 "userland ");
993 (void) ctf_type_qname(fp, argv[i], adp->dtargd_native +
994 ret, DTRACE_ARGTYPELEN - ret, buf);
995 }
996#endif
997 }
998out:
999 dt_proc_unlock(dtp, p);
1000 dt_proc_release(dtp, p);
1001}