summaryrefslogtreecommitdiffstats
path: root/cddl/contrib/opensolaris/lib/libdtrace
diff options
context:
space:
mode:
authormarkj <markj@FreeBSD.org>2015-04-08 02:36:37 +0000
committermarkj <markj@FreeBSD.org>2015-04-08 02:36:37 +0000
commit1d6ffde4f49799c1d95f31875779237c214fc09c (patch)
tree48267c7be89f3f03d035711a7b82b3453bab848e /cddl/contrib/opensolaris/lib/libdtrace
parent245de71cf80d02d4ff02fcf352fb7f056c686821 (diff)
downloadFreeBSD-src-1d6ffde4f49799c1d95f31875779237c214fc09c.zip
FreeBSD-src-1d6ffde4f49799c1d95f31875779237c214fc09c.tar.gz
libdtrace: add support for lazyload mode.
Passing "-x lazyload" to dtrace -G during compilation causes dtrace(1) to not link drti.o into the output object file, so the USDT probes are not created during process startup. Instead, dtrace(1) will automatically discover and create probes on the process' behalf when attaching. Differential Revision: https://reviews.freebsd.org/D2203 Reviewed by: rpaulo MFC after: 1 month
Diffstat (limited to 'cddl/contrib/opensolaris/lib/libdtrace')
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/drti.c5
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c16
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c75
3 files changed, 79 insertions, 17 deletions
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c
index a75dc02..5fab935 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c
@@ -147,6 +147,9 @@ dtrace_dof_init(void)
dh.dofhp_dof = (uintptr_t)dof;
dh.dofhp_addr = elf->e_type == ET_DYN ? (uintptr_t) lmp->l_addr : 0;
+#ifdef __FreeBSD__
+ dh.dofhp_pid = getpid();
+#endif
if (lmid == 0) {
(void) snprintf(dh.dofhp_mod, sizeof (dh.dofhp_mod),
@@ -184,7 +187,7 @@ dtrace_dof_init(void)
else {
dprintf(1, "DTrace ioctl succeeded for DOF at %p\n", dof);
#ifdef __FreeBSD__
- gen = dh.gen;
+ gen = dh.dofhp_gen;
#endif
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
index ae41269..eaf0961 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
@@ -1785,11 +1785,17 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
"failed to open %s: %s", file, strerror(errno)));
}
#else
- snprintf(tfile, sizeof(tfile), "%s.XXXXXX", file);
- if ((fd = mkstemp(tfile)) == -1)
- return (dt_link_error(dtp, NULL, -1, NULL,
- "failed to create temporary file %s: %s",
- tfile, strerror(errno)));
+ if (dtp->dt_lazyload) {
+ if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0)
+ return (dt_link_error(dtp, NULL, -1, NULL,
+ "failed to open %s: %s", file, strerror(errno)));
+ } else {
+ snprintf(tfile, sizeof(tfile), "%s.XXXXXX", file);
+ if ((fd = mkstemp(tfile)) == -1)
+ return (dt_link_error(dtp, NULL, -1, NULL,
+ "failed to create temporary file %s: %s",
+ tfile, strerror(errno)));
+ }
#endif
/*
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c
index e628e62..c61a710 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c
@@ -44,10 +44,15 @@
#include <dt_program.h>
#include <dt_pid.h>
#include <dt_string.h>
+#include <dt_module.h>
+
#ifndef illumos
+#include <sys/sysctl.h>
+#include <unistd.h>
#include <libproc_compat.h>
+#include <libelf.h>
+#include <gelf.h>
#endif
-#include <dt_module.h>
typedef struct dt_pid_probe {
dtrace_hdl_t *dpp_dtp;
@@ -566,6 +571,12 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname)
prsyminfo_t sip;
dof_helper_t dh;
GElf_Half e_type;
+#ifdef __FreeBSD__
+ dof_hdr_t hdr;
+ size_t sz;
+ uint64_t dofmax;
+ void *dof;
+#endif
const char *mname;
const char *syms[] = { "___SUNW_dof", "__SUNW_dof" };
int i, fd = -1;
@@ -595,17 +606,61 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname)
continue;
}
- dh.dofhp_dof = sym.st_value;
+#ifdef __FreeBSD__
dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr;
+ if (Pread(P, &hdr, sizeof (hdr), sym.st_value) !=
+ sizeof (hdr)) {
+ dt_dprintf("read of DOF header failed\n");
+ continue;
+ }
+
+ sz = sizeof(dofmax);
+ if (sysctlbyname("kern.dtrace.dof_maxsize", &dofmax, &sz,
+ NULL, 0) != 0) {
+ dt_dprintf("failed to read dof_maxsize: %s\n",
+ strerror(errno));
+ continue;
+ }
+ if (dofmax < hdr.dofh_loadsz) {
+ dt_dprintf("DOF load size exceeds maximum\n");
+ continue;
+ }
+
+ if ((dof = malloc(hdr.dofh_loadsz)) == NULL)
+ return (-1);
+
+ if (Pread(P, dof, hdr.dofh_loadsz, sym.st_value) !=
+ hdr.dofh_loadsz) {
+ free(dof);
+ dt_dprintf("read of DOF section failed\n");
+ continue;
+ }
+
+ dh.dofhp_dof = (uintptr_t)dof;
+ dh.dofhp_pid = proc_getpid(P);
dt_pid_objname(dh.dofhp_mod, sizeof (dh.dofhp_mod),
-#ifdef illumos
sip.prs_lmid, mname);
+
+ if (fd == -1 &&
+ (fd = open("/dev/dtrace/helper", O_RDWR, 0)) < 0) {
+ dt_dprintf("open of helper device failed: %s\n",
+ strerror(errno));
+ free(dof);
+ return (-1); /* errno is set for us */
+ }
+
+ if (ioctl(fd, DTRACEHIOC_ADDDOF, &dh, sizeof (dh)) < 0)
+ dt_dprintf("DOF was rejected for %s\n", dh.dofhp_mod);
+
+ free(dof);
#else
- 0, mname);
-#endif
+ dh.dofhp_dof = sym.st_value;
+ dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr;
+
+ dt_pid_objname(dh.dofhp_mod, sizeof (dh.dofhp_mod),
+ sip.prs_lmid, mname);
-#ifdef illumos
if (fd == -1 &&
(fd = pr_open(P, "/dev/dtrace/helper", O_RDWR, 0)) < 0) {
dt_dprintf("pr_open of helper device failed: %s\n",
@@ -618,8 +673,10 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname)
#endif
}
-#ifdef illumos
if (fd != -1)
+#ifdef __FreeBSD__
+ (void) close(fd);
+#else
(void) pr_close(P, fd);
#endif
@@ -634,7 +691,6 @@ dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp,
int ret = 0;
assert(DT_MUTEX_HELD(&dpr->dpr_lock));
-#ifdef illumos
(void) Pupdate_maps(P);
if (Pobject_iter(P, dt_pid_usdt_mapping, P) != 0) {
ret = -1;
@@ -646,9 +702,6 @@ dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp,
(int)proc_getpid(P), strerror(errno));
#endif
}
-#else
- ret = 0;
-#endif
/*
* Put the module name in its canonical form.
OpenPOWER on IntegriCloud