Mercurial > illumos > illumos-gate
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