When running dtrace -h, I get the following unintuitive error message: $ dtrace -h -s perldtrace.d dtrace: failed to compile script perldtrace.d: "/usr/lib/dtrace/regs_x86.d", line 2: type redeclared: struct devinfo This error doesn't occur if I run it without -h, which doesn't make much sense since the scripts in /usr/lib/dtrace/ are processed regardless. Fix: The root of the problem is the "#pragma D depends_on provider" in /usr/lib/dtrace/io.d. When dtrace sees that directive, it calls a DTRACEIOC_PROVIDER ioctl on /dev/dtrace/dtrace with the appropriate provider argument ("io" in this case) to verify that that provider really is available. Turns out that the -h (and -G) option sets the DTRACE_O_NODEV flag, which basically means "don't open /dev/dtrace/dtrace or /dev/dtrace/fasttrap." This allows dtrace -h to be used without needing root privileges. But obviously we need to open /dev/dtrace/dtrace for the reason mentioned above, and dtrace aborts because it can't call the ioctl. For now, I'm working around this by just removing /usr/lib/dtrace/io.d - I don't need it at the moment. I'm not sure what the right fix is. Probably the error message could also be improved in this case, but I haven't really looked into that.
I should also point out that simply removing the depends_on directive in io.d is a sufficient workaround. Just make sure dtio.ko is loaded I guess. :) -Mark
I've attached a patch with an actual fix. Specific, this changes libdtrace to first look for providers from the debug.dtrace.providers sysctl. This doesn't require the user to be root, so dtrace -h works as expected. Here's an easy test case (for CURRENT) to reproduce the original problem: $ cat probe.d provider test { probe testprobe(); }; $ dtrace -h -s probe.d dtrace: failed to compile script probe.d: "/usr/lib/dtrace/regs_x86.d", line 2: type redeclared: struct devinfo $ As I mentioned, this is caused by the depends_on pragma in io.d. The same problem comes up if a "depends_on provider" pragma is added to probe.d. Thanks, -Mark
This patch (dtrace_depends_on_sysctl.patch) was required when I built the Port lang/erlang (Erlang/OTP R15B03-1) with the dtrace option enabled. I suggest this patch should be merged into the STABLE branch ASAP. My test environment: FreeBSD minimax.priv.k2r.org 9.1-STABLE FreeBSD 9.1-STABLE #14 r245019: Fri Jan 4 11:08:18 JST 2013 root@minimax.priv.k2r.org:/usr/obj/usr/src/sys/MINIMAX amd64 And the Ports tree svn revision was r310207. Regards, Kenji Rikitake
State Changed From-To: open->analyzed I believe gnn@ is taking a look at this.
Responsible Changed From-To: freebsd-bugs->gnn I believe gnn@ is taking a look at this.
Here's a slightly updated version of the last patch - this changes the new code so that dt_lookup_provider() is still called if we can't find the provider in the debug.dtrace.providers sysctl. Thanks, -Mark
State Changed From-To: analyzed->patched I have committed what I think is a fix to HEAD, in the form of an updated io.d. Please test aand let me know.
State Changed From-To: patched->analyzed Need to apply a different patch moving back to analyzed for the moment.
State Changed From-To: analyzed->patched Apply the latest patch to address this from the reporter.
Author: gnn Date: Thu Mar 28 20:31:03 2013 New Revision: 248848 URL: http://svnweb.freebsd.org/changeset/base/248848 Log: Commit a patch that fixes a problem in the #pragma statement when searching for and loading dependent modules. This addresses a bug seen with io.d where it was being doubly included. PR: 171678 Submitted by: Mark Johnston MFC after: 2 weeks Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c ============================================================================== --- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c Thu Mar 28 20:27:01 2013 (r248847) +++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c Thu Mar 28 20:31:03 2013 (r248848) @@ -241,6 +241,8 @@ dt_pragma_depends(const char *prname, dt int found; dt_lib_depend_t *dld; char lib[MAXPATHLEN]; + size_t plen; + char *provs, *cpy, *tok; if (cnp == NULL || nnp == NULL || cnp->dn_kind != DT_NODE_IDENT || nnp->dn_kind != DT_NODE_IDENT) { @@ -248,9 +250,31 @@ dt_pragma_depends(const char *prname, dt "<class> <name>\n", prname); } - if (strcmp(cnp->dn_string, "provider") == 0) - found = dt_provider_lookup(dtp, nnp->dn_string) != NULL; - else if (strcmp(cnp->dn_string, "module") == 0) { + if (strcmp(cnp->dn_string, "provider") == 0) { + /* + * First try to get the provider list using the + * debug.dtrace.providers sysctl, since that'll work even if + * we're not running as root. + */ + provs = NULL; + if (sysctlbyname("debug.dtrace.providers", NULL, &plen, NULL, 0) || + ((provs = dt_alloc(dtp, plen)) == NULL) || + sysctlbyname("debug.dtrace.providers", provs, &plen, NULL, 0)) + found = dt_provider_lookup(dtp, nnp->dn_string) != NULL; + else { + found = B_FALSE; + for (cpy = provs; (tok = strsep(&cpy, " ")) != NULL; ) + if (strcmp(tok, nnp->dn_string) == 0) { + found = B_TRUE; + break; + } + if (found == B_FALSE) + found = dt_provider_lookup(dtp, + nnp->dn_string) != NULL; + } + if (provs != NULL) + dt_free(dtp, provs); + } else if (strcmp(cnp->dn_string, "module") == 0) { dt_module_t *mp = dt_module_lookup_by_name(dtp, nnp->dn_string); found = mp != NULL && dt_module_getctf(dtp, mp) != NULL; } else if (strcmp(cnp->dn_string, "library") == 0) { _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Author: gnn Date: Mon Jun 17 15:42:21 2013 New Revision: 251857 URL: http://svnweb.freebsd.org/changeset/base/251857 Log: MFC: 248848 Commit a patch that fixes a problem in the #pragma statement when searching for and loading dependent modules. This addresses a bug seen with io.d where it was being doubly included. PR: 171678 Submitted by: Mark Johnston Modified: stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c Directory Properties: stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/ (props changed) Modified: stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c ============================================================================== --- stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c Mon Jun 17 15:34:22 2013 (r251856) +++ stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c Mon Jun 17 15:42:21 2013 (r251857) @@ -241,6 +241,8 @@ dt_pragma_depends(const char *prname, dt int found; dt_lib_depend_t *dld; char lib[MAXPATHLEN]; + size_t plen; + char *provs, *cpy, *tok; if (cnp == NULL || nnp == NULL || cnp->dn_kind != DT_NODE_IDENT || nnp->dn_kind != DT_NODE_IDENT) { @@ -248,9 +250,31 @@ dt_pragma_depends(const char *prname, dt "<class> <name>\n", prname); } - if (strcmp(cnp->dn_string, "provider") == 0) - found = dt_provider_lookup(dtp, nnp->dn_string) != NULL; - else if (strcmp(cnp->dn_string, "module") == 0) { + if (strcmp(cnp->dn_string, "provider") == 0) { + /* + * First try to get the provider list using the + * debug.dtrace.providers sysctl, since that'll work even if + * we're not running as root. + */ + provs = NULL; + if (sysctlbyname("debug.dtrace.providers", NULL, &plen, NULL, 0) || + ((provs = dt_alloc(dtp, plen)) == NULL) || + sysctlbyname("debug.dtrace.providers", provs, &plen, NULL, 0)) + found = dt_provider_lookup(dtp, nnp->dn_string) != NULL; + else { + found = B_FALSE; + for (cpy = provs; (tok = strsep(&cpy, " ")) != NULL; ) + if (strcmp(tok, nnp->dn_string) == 0) { + found = B_TRUE; + break; + } + if (found == B_FALSE) + found = dt_provider_lookup(dtp, + nnp->dn_string) != NULL; + } + if (provs != NULL) + dt_free(dtp, provs); + } else if (strcmp(cnp->dn_string, "module") == 0) { dt_module_t *mp = dt_module_lookup_by_name(dtp, nnp->dn_string); found = mp != NULL && dt_module_getctf(dtp, mp) != NULL; } else if (strcmp(cnp->dn_string, "library") == 0) { _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
State Changed From-To: patched->closed The fix for this PR has been committed and MFCed.