Author: pfg
Date: Tue Jul 17 19:57:34 2012
New Revision: 238558
URL: http://svn.freebsd.org/changeset/base/238558

Log:
  Dtrace: improve handling of library paths.
  
  Merge changes from illumos
  
  906 dtrace depends_on pragma should search all library paths, not just the
  current one
  
  949 dtrace should only include the first instance of a library found on
  its library path
  
  Illumos Revisions:    13353:936a1e45726c
                        13354:2b2c36a81512
  
  Reference:
  https://www.illumos.org/issues/906
  https://www.illumos.org/issues/949
  
  Tested by:    Fabian Keil
  Obtained from:        Illumos
  MFC after:    3 weeks

Added:
  head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/include/
     - copied from r238552, 
vendor/illumos/dist/cmd/dtrace/test/tst/common/include/
  
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdepsepdir.ksh
     - copied unchanged from r238552, 
vendor/illumos/dist/cmd/dtrace/test/tst/common/pragma/tst.libdepsepdir.ksh
Modified:
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c

Copied: 
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdepsepdir.ksh
 (from r238552, 
vendor/illumos/dist/cmd/dtrace/test/tst/common/pragma/tst.libdepsepdir.ksh)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ 
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdepsepdir.ksh
        Tue Jul 17 19:57:34 2012        (r238558, copy of r238552, 
vendor/illumos/dist/cmd/dtrace/test/tst/common/pragma/tst.libdepsepdir.ksh)
@@ -0,0 +1,76 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2011, Joyent Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# Test to catch that we properly look for libraries dependencies in
+# our full library parth
+#
+
+if [ $# != 1 ]; then
+       echo expected one argument: '<'dtrace-path'>'
+       exit 2
+fi
+
+libdira=${TMPDIR:-/tmp}/libdepa.$$
+libdirb=${TMPDIR:-/tmp}/libdepb.$$
+libdirc=${TMPDIR:-/tmp}/libdepc.$$
+dtrace=$1
+
+setup_libs()
+{
+        mkdir $libdira
+        mkdir $libdirb
+        mkdir $libdirc
+        cat > $libdira/liba.$$.d <<EOF
+#pragma D depends_on library libb.$$.d
+#pragma D depends_on library libc.$$.d
+#pragma D depends_on library libd.$$.d
+EOF
+        cat > $libdirb/libb.$$.d <<EOF
+#pragma D depends_on library libc.$$.d
+EOF
+        cat > $libdirb/libc.$$.d <<EOF
+EOF
+        cat > $libdirb/libd.$$.d <<EOF
+EOF
+        cat > $libdirc/libe.$$.d <<EOF
+#pragma D depends_on library liba.$$.d
+EOF
+        cat > $libdirc/libf.$$.d <<EOF
+EOF
+}
+
+
+setup_libs
+
+$dtrace -L$libdira -L$libdirb -L$libdirc -e
+
+status=$?
+rm -rf $libdira
+rm -rf $libdirb
+rm -rf $libdirc
+return $status
+

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c  Tue Jul 17 
19:29:32 2012        (r238557)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c  Tue Jul 17 
19:57:34 2012        (r238558)
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent Inc. All rights reserved.
  */
 
 /*
@@ -2150,25 +2151,23 @@ dt_lib_depend_free(dtrace_hdl_t *dtp)
        }
 }
 
-
 /*
- * Open all of the .d library files found in the specified directory and
- * compile each one in topological order to cache its inlines and translators,
- * etc.  We silently ignore any missing directories and other files found
- * therein. We only fail (and thereby fail dt_load_libs()) if we fail to
- * compile a library and the error is something other than #pragma D 
depends_on.
- * Dependency errors are silently ignored to permit a library directory to
- * contain libraries which may not be accessible depending on our privileges.
+ * Open all the .d library files found in the specified directory and
+ * compile each one of them.  We silently ignore any missing directories and
+ * other files found therein.  We only fail (and thereby fail dt_load_libs()) 
if
+ * we fail to compile a library and the error is something other than #pragma D
+ * depends_on.  Dependency errors are silently ignored to permit a library
+ * directory to contain libraries which may not be accessible depending on our
+ * privileges.
  */
 static int
 dt_load_libs_dir(dtrace_hdl_t *dtp, const char *path)
 {
        struct dirent *dp;
-       const char *p;
+       const char *p, *end;
        DIR *dirp;
 
        char fname[PATH_MAX];
-       dtrace_prog_t *pgp;
        FILE *fp;
        void *rv;
        dt_lib_depend_t *dld;
@@ -2192,9 +2191,28 @@ dt_load_libs_dir(dtrace_hdl_t *dtp, cons
                        continue;
                }
 
+               /*
+                * Skip files whose name match an already processed library
+                */
+               for (dld = dt_list_next(&dtp->dt_lib_dep); dld != NULL;
+                   dld = dt_list_next(dld)) {
+                       end = strrchr(dld->dtld_library, '/');
+                       /* dt_lib_depend_add ensures this */
+                       assert(end != NULL);
+                       if (strcmp(end + 1, dp->d_name) == 0)
+                               break;
+               }
+
+               if (dld != NULL) {
+                       dt_dprintf("skipping library %s, already processed "
+                           "library with the same name: %s", dp->d_name,
+                           dld->dtld_library);
+                       continue;
+               }
+
                dtp->dt_filetag = fname;
                if (dt_lib_depend_add(dtp, &dtp->dt_lib_dep, fname) != 0)
-                       goto err;
+                       return (-1); /* preserve dt_errno */
 
                rv = dt_compile(dtp, DT_CTX_DPROG,
                    DTRACE_PROBESPEC_NAME, NULL,
@@ -2203,7 +2221,7 @@ dt_load_libs_dir(dtrace_hdl_t *dtp, cons
                if (rv != NULL && dtp->dt_errno &&
                    (dtp->dt_errno != EDT_COMPILER ||
                    dtp->dt_errtag != dt_errtag(D_PRAGMA_DEPEND)))
-                       goto err;
+                       return (-1); /* preserve dt_errno */
 
                if (dtp->dt_errno)
                        dt_dprintf("error parsing library %s: %s\n",
@@ -2214,6 +2232,27 @@ dt_load_libs_dir(dtrace_hdl_t *dtp, cons
        }
 
        (void) closedir(dirp);
+
+       return (0);
+}
+
+/*
+ * Perform a topological sorting of all the libraries found across the entire
+ * dt_lib_path.  Once sorted, compile each one in topological order to cache 
its
+ * inlines and translators, etc.  We silently ignore any missing directories 
and
+ * other files found therein. We only fail (and thereby fail dt_load_libs()) if
+ * we fail to compile a library and the error is something other than #pragma D
+ * depends_on.  Dependency errors are silently ignored to permit a library
+ * directory to contain libraries which may not be accessible depending on our
+ * privileges.
+ */
+static int
+dt_load_libs_sort(dtrace_hdl_t *dtp)
+{
+       dtrace_prog_t *pgp;
+       FILE *fp;
+       dt_lib_depend_t *dld;
+
        /*
         * Finish building the graph containing the library dependencies
         * and perform a topological sort to generate an ordered list
@@ -2274,7 +2313,14 @@ dt_load_libs(dtrace_hdl_t *dtp)
 
        dtp->dt_cflags |= DTRACE_C_NOLIBS;
 
-       for (dirp = dt_list_next(&dtp->dt_lib_path);
+       /*
+        * /usr/lib/dtrace is always at the head of the list. The rest of the
+        * list is specified in the precedence order the user requested. Process
+        * everything other than the head first. DTRACE_C_NOLIBS has already
+        * been spcified so dt_vopen will ensure that there is always one entry
+        * in dt_lib_path.
+        */
+       for (dirp = dt_list_next(dt_list_next(&dtp->dt_lib_path));
            dirp != NULL; dirp = dt_list_next(dirp)) {
                if (dt_load_libs_dir(dtp, dirp->dir_path) != 0) {
                        dtp->dt_cflags &= ~DTRACE_C_NOLIBS;
@@ -2282,6 +2328,16 @@ dt_load_libs(dtrace_hdl_t *dtp)
                }
        }
 
+       /* Handle /usr/lib/dtrace */
+       dirp = dt_list_next(&dtp->dt_lib_path);
+       if (dt_load_libs_dir(dtp, dirp->dir_path) != 0) {
+               dtp->dt_cflags &= ~DTRACE_C_NOLIBS;
+               return (-1); /* errno is set for us */
+       }
+
+       if (dt_load_libs_sort(dtp) < 0)
+               return (-1); /* errno is set for us */
+
        return (0);
 }
 

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c      Tue Jul 
17 19:29:32 2012        (r238557)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c      Tue Jul 
17 19:57:34 2012        (r238558)
@@ -21,7 +21,7 @@
 
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2011, Joyent Inc. All rights reserved.
  */
 
 #pragma ident  "%Z%%M% %I%     %E% SMI"
@@ -31,9 +31,13 @@
 #if defined(sun)
 #include <alloca.h>
 #endif
+#include <fcntl.h>
 #include <stdlib.h>
 #include <stdio.h>
 
+#include <sys/types.h>
+#include <sys/stat.h>
+
 #include <dt_parser.h>
 #include <dt_impl.h>
 #include <dt_provider.h>
@@ -201,6 +205,29 @@ dt_pragma_binding(const char *prname, dt
                dtp->dt_globals->dh_defer = &dt_pragma_apply;
 }
 
+static void 
+dt_pragma_depends_finddep(dtrace_hdl_t *dtp, const char *lname, char *lib,
+    size_t len)
+{
+       dt_dirpath_t *dirp;
+       struct stat sbuf;
+       int found = 0;
+
+       for (dirp = dt_list_next(&dtp->dt_lib_path); dirp != NULL;
+           dirp = dt_list_next(dirp)) {
+               (void) snprintf(lib, len, "%s/%s", dirp->dir_path, lname);
+
+               if (stat(lib, &sbuf) == 0) {
+                       found = 1;
+                       break;
+               }
+       }
+
+       if (!found)
+               xyerror(D_PRAGMA_DEPEND,
+                   "failed to find dependency in libpath: %s", lname);
+}
+
 /*
  * The #pragma depends_on directive can be used to express a dependency on a
  * module, provider or library which if not present will cause processing to
@@ -230,16 +257,13 @@ dt_pragma_depends(const char *prname, dt
                if (yypcb->pcb_cflags & DTRACE_C_CTL) {
                        assert(dtp->dt_filetag != NULL);
 
-                       /*
-                        * We have the file we are working on in dtp->dt_filetag
-                        * so find that node and add the dependency in.
-                        */
+                       dt_pragma_depends_finddep(dtp, nnp->dn_string, lib,
+                           sizeof (lib));
+
                        dld = dt_lib_depend_lookup(&dtp->dt_lib_dep,
                            dtp->dt_filetag);
                        assert(dld != NULL);
 
-                       (void) snprintf(lib, sizeof (lib), "%s%s",
-                           dld->dtld_libpath, nnp->dn_string);
                        if ((dt_lib_depend_add(dtp, &dld->dtld_dependencies,
                            lib)) != 0) {
                                xyerror(D_PRAGMA_DEPEND,
@@ -261,8 +285,8 @@ dt_pragma_depends(const char *prname, dt
                            dtp->dt_filetag);
                        assert(dld != NULL);
 
-                       (void) snprintf(lib, sizeof (lib), "%s%s",
-                           dld->dtld_libpath, nnp->dn_string);
+                       dt_pragma_depends_finddep(dtp, nnp->dn_string, lib,
+                           sizeof (lib));
                        dld = dt_lib_depend_lookup(&dtp->dt_lib_dep_sorted,
                            lib);
                        assert(dld != NULL);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to