changeset 13353:936a1e45726c

906 dtrace depends_on pragma should search all library paths, not just the current one Reviewed by: Bryan Cantrill <bryan@joyent.com> Approved by: Garrett D'Amore <garrett@nexenta.com>
author Robert Mustacchi <robert.mustacchi@joyent.com>
date Sun, 06 Feb 2011 17:02:17 -0800
parents f1cdd406b7eb
children 2b2c36a81512
files usr/src/cmd/dtrace/test/tst/common/pragma/tst.libdepsepdir.ksh usr/src/lib/libdtrace/common/dt_cc.c usr/src/lib/libdtrace/common/dt_pragma.c usr/src/pkg/manifests/system-dtrace-tests.mf
diffstat 4 files changed, 144 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/dtrace/test/tst/common/pragma/tst.libdepsepdir.ksh	Sun Feb 06 17:02:17 2011 -0800
@@ -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
+
--- a/usr/src/lib/libdtrace/common/dt_cc.c	Thu Jan 20 15:03:16 2011 -0800
+++ b/usr/src/lib/libdtrace/common/dt_cc.c	Sun Feb 06 17:02:17 2011 -0800
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent Inc. All rights reserved.
  */
 
 /*
@@ -1913,15 +1914,14 @@
 	}
 }
 
-
 /*
- * 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)
@@ -1931,10 +1931,8 @@
 	DIR *dirp;
 
 	char fname[PATH_MAX];
-	dtrace_prog_t *pgp;
 	FILE *fp;
 	void *rv;
-	dt_lib_depend_t *dld;
 
 	if ((dirp = opendir(path)) == NULL) {
 		dt_dprintf("skipping lib dir %s: %s\n", path, strerror(errno));
@@ -1957,7 +1955,7 @@
 
 		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,
@@ -1966,7 +1964,7 @@
 		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",
@@ -1977,6 +1975,27 @@
 	}
 
 	(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
@@ -2045,6 +2064,9 @@
 		}
 	}
 
+	if (dt_load_libs_sort(dtp) < 0)
+		return (-1); /* errno is set for us */
+
 	return (0);
 }
 
--- a/usr/src/lib/libdtrace/common/dt_pragma.c	Thu Jan 20 15:03:16 2011 -0800
+++ b/usr/src/lib/libdtrace/common/dt_pragma.c	Sun Feb 06 17:02:17 2011 -0800
@@ -21,14 +21,19 @@
 
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent Inc. All rights reserved.
  */
 
 #include <assert.h>
 #include <strings.h>
 #include <alloca.h>
+#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>
@@ -196,6 +201,29 @@
 		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
@@ -225,16 +253,13 @@
 		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,
@@ -256,8 +281,8 @@
 			    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);
--- a/usr/src/pkg/manifests/system-dtrace-tests.mf	Thu Jan 20 15:03:16 2011 -0800
+++ b/usr/src/pkg/manifests/system-dtrace-tests.mf	Sun Feb 06 17:02:17 2011 -0800
@@ -1098,6 +1098,7 @@
 file path=opt/SUNWdtrt/tst/common/pragma/tst.libdep.ksh mode=0444
 file path=opt/SUNWdtrt/tst/common/pragma/tst.libdepfullyconnected.ksh \
     mode=0444
+file path=opt/SUNWdtrt/tst/common/pragma/tst.libdepsepdir.ksh mode=0444
 file path=opt/SUNWdtrt/tst/common/predicates/err.D_PRED_SCALAR.NonScalarPred.d \
     mode=0444
 file path=opt/SUNWdtrt/tst/common/predicates/err.D_SYNTAX.invalid.d mode=0444