From owner-svn-src-head@FreeBSD.ORG Wed Apr 8 02:36:40 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id B6FB5D91; Wed, 8 Apr 2015 02:36:40 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9E3516ED; Wed, 8 Apr 2015 02:36:40 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t382aeLr012115; Wed, 8 Apr 2015 02:36:40 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t382acCL012107; Wed, 8 Apr 2015 02:36:38 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201504080236.t382acCL012107@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Wed, 8 Apr 2015 02:36:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r281257 - in head: cddl/contrib/opensolaris/lib/libdtrace/common cddl/lib/libdtrace sys/cddl/contrib/opensolaris/uts/common/dtrace sys/cddl/contrib/opensolaris/uts/common/sys sys/cddl/d... X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Apr 2015 02:36:40 -0000 Author: markj Date: Wed Apr 8 02:36:37 2015 New Revision: 281257 URL: https://svnweb.freebsd.org/changeset/base/281257 Log: 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 Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c head/cddl/lib/libdtrace/libproc_compat.h head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h head/sys/cddl/dev/dtrace/dtrace_ioctl.c Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c ============================================================================== --- head/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c Wed Apr 8 02:21:44 2015 (r281256) +++ head/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c Wed Apr 8 02:36:37 2015 (r281257) @@ -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 } Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c ============================================================================== --- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c Wed Apr 8 02:21:44 2015 (r281256) +++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c Wed Apr 8 02:36:37 2015 (r281257) @@ -1785,11 +1785,17 @@ dtrace_program_link(dtrace_hdl_t *dtp, d "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 /* Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c ============================================================================== --- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c Wed Apr 8 02:21:44 2015 (r281256) +++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c Wed Apr 8 02:36:37 2015 (r281257) @@ -44,10 +44,15 @@ #include #include #include +#include + #ifndef illumos +#include +#include #include +#include +#include #endif -#include typedef struct dt_pid_probe { dtrace_hdl_t *dpp_dtp; @@ -566,6 +571,12 @@ dt_pid_usdt_mapping(void *data, const pr 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 pr 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 pr #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_probede 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_probede (int)proc_getpid(P), strerror(errno)); #endif } -#else - ret = 0; -#endif /* * Put the module name in its canonical form. Modified: head/cddl/lib/libdtrace/libproc_compat.h ============================================================================== --- head/cddl/lib/libdtrace/libproc_compat.h Wed Apr 8 02:21:44 2015 (r281256) +++ head/cddl/lib/libdtrace/libproc_compat.h Wed Apr 8 02:36:37 2015 (r281257) @@ -59,6 +59,6 @@ #define Pstate proc_state #define Psymbol_iter_by_addr proc_iter_symbyaddr #define Punsetflags proc_clearflags -#define Pupdate_maps(p) do { } while (0) +#define Pupdate_maps proc_rdagent #define Pupdate_syms proc_updatesyms #define Pxecbkpt proc_bkptexec Modified: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c Wed Apr 8 02:21:44 2015 (r281256) +++ head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c Wed Apr 8 02:36:37 2015 (r281257) @@ -15374,13 +15374,15 @@ dtrace_helper_action_destroy(dtrace_help } static int -dtrace_helper_destroygen(int gen) +dtrace_helper_destroygen(dtrace_helpers_t *help, int gen) { proc_t *p = curproc; - dtrace_helpers_t *help = p->p_dtrace_helpers; dtrace_vstate_t *vstate; int i; + if (help == NULL) + help = p->p_dtrace_helpers; + ASSERT(MUTEX_HELD(&dtrace_lock)); if (help == NULL || gen > help->dthps_generation) @@ -15478,9 +15480,9 @@ dtrace_helper_validate(dtrace_helper_act } static int -dtrace_helper_action_add(int which, dtrace_ecbdesc_t *ep) +dtrace_helper_action_add(int which, dtrace_ecbdesc_t *ep, + dtrace_helpers_t *help) { - dtrace_helpers_t *help; dtrace_helper_action_t *helper, *last; dtrace_actdesc_t *act; dtrace_vstate_t *vstate; @@ -15490,7 +15492,6 @@ dtrace_helper_action_add(int which, dtra if (which < 0 || which >= DTRACE_NHELPER_ACTIONS) return (EINVAL); - help = curproc->p_dtrace_helpers; last = help->dthps_actions[which]; vstate = &help->dthps_vstate; @@ -15614,15 +15615,12 @@ dtrace_helper_provider_register(proc_t * } static int -dtrace_helper_provider_add(dof_helper_t *dofhp, int gen) +dtrace_helper_provider_add(dof_helper_t *dofhp, dtrace_helpers_t *help, int gen) { - dtrace_helpers_t *help; dtrace_helper_provider_t *hprov, **tmp_provs; uint_t tmp_maxprovs, i; ASSERT(MUTEX_HELD(&dtrace_lock)); - - help = curproc->p_dtrace_helpers; ASSERT(help != NULL); /* @@ -15914,13 +15912,28 @@ dtrace_helper_slurp(dof_hdr_t *dof, dof_ dtrace_helpers_t *help; dtrace_vstate_t *vstate; dtrace_enabling_t *enab = NULL; + proc_t *p = curproc; int i, gen, rv, nhelpers = 0, nprovs = 0, destroy = 1; uintptr_t daddr = (uintptr_t)dof; ASSERT(MUTEX_HELD(&dtrace_lock)); - if ((help = curproc->p_dtrace_helpers) == NULL) - help = dtrace_helpers_create(curproc); +#ifdef __FreeBSD__ + if (dhp->dofhp_pid != p->p_pid) { + if ((p = pfind(dhp->dofhp_pid)) == NULL) + return (-1); + if (!P_SHOULDSTOP(p) || + (p->p_flag & P_TRACED) == 0 || + p->p_pptr->p_pid != curproc->p_pid) { + PROC_UNLOCK(p); + return (-1); + } + PROC_UNLOCK(p); + } +#endif + + if ((help = p->p_dtrace_helpers) == NULL) + help = dtrace_helpers_create(p); vstate = &help->dthps_vstate; @@ -15968,12 +15981,13 @@ dtrace_helper_slurp(dof_hdr_t *dof, dof_ continue; if ((rv = dtrace_helper_action_add(DTRACE_HELPER_ACTION_USTACK, - ep)) != 0) { + ep, help)) != 0) { /* * Adding this helper action failed -- we are now going * to rip out the entire generation and return failure. */ - (void) dtrace_helper_destroygen(help->dthps_generation); + (void) dtrace_helper_destroygen(help, + help->dthps_generation); dtrace_enabling_destroy(enab); dtrace_dof_destroy(dof); return (-1); @@ -15990,9 +16004,9 @@ dtrace_helper_slurp(dof_hdr_t *dof, dof_ if (dhp != NULL && nprovs > 0) { dhp->dofhp_dof = (uint64_t)(uintptr_t)dof; - if (dtrace_helper_provider_add(dhp, gen) == 0) { + if (dtrace_helper_provider_add(dhp, help, gen) == 0) { mutex_exit(&dtrace_lock); - dtrace_helper_provider_register(curproc, help, dhp); + dtrace_helper_provider_register(p, help, dhp); mutex_enter(&dtrace_lock); destroy = 0; @@ -16956,7 +16970,7 @@ dtrace_ioctl_helper(int cmd, intptr_t ar case DTRACEHIOC_REMOVE: { mutex_enter(&dtrace_lock); - rval = dtrace_helper_destroygen(arg); + rval = dtrace_helper_destroygen(NULL, arg); mutex_exit(&dtrace_lock); return (rval); Modified: head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h Wed Apr 8 02:21:44 2015 (r281256) +++ head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h Wed Apr 8 02:36:37 2015 (r281257) @@ -1423,8 +1423,9 @@ typedef struct dof_helper { char dofhp_mod[DTRACE_MODNAMELEN]; /* executable or library name */ uint64_t dofhp_addr; /* base address of object */ uint64_t dofhp_dof; /* address of helper DOF */ -#ifndef illumos - int gen; +#ifdef __FreeBSD__ + pid_t dofhp_pid; /* target process ID */ + int dofhp_gen; #endif } dof_helper_t; Modified: head/sys/cddl/dev/dtrace/dtrace_ioctl.c ============================================================================== --- head/sys/cddl/dev/dtrace/dtrace_ioctl.c Wed Apr 8 02:21:44 2015 (r281256) +++ head/sys/cddl/dev/dtrace/dtrace_ioctl.c Wed Apr 8 02:36:37 2015 (r281257) @@ -32,9 +32,9 @@ static int dtrace_ioctl_helper(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td) { - int rval; dof_helper_t *dhp = NULL; dof_hdr_t *dof = NULL; + int rval; switch (cmd) { case DTRACEHIOC_ADDDOF: @@ -51,7 +51,7 @@ dtrace_ioctl_helper(struct cdev *dev, u_ mutex_enter(&dtrace_lock); if ((rval = dtrace_helper_slurp((dof_hdr_t *)dof, dhp)) != -1) { if (dhp) { - dhp->gen = rval; + dhp->dofhp_gen = rval; copyout(dhp, addr, sizeof(*dhp)); } rval = 0; @@ -59,10 +59,11 @@ dtrace_ioctl_helper(struct cdev *dev, u_ rval = EINVAL; } mutex_exit(&dtrace_lock); + return (rval); case DTRACEHIOC_REMOVE: mutex_enter(&dtrace_lock); - rval = dtrace_helper_destroygen((int)*addr); + rval = dtrace_helper_destroygen(NULL, (int)*addr); mutex_exit(&dtrace_lock); return (rval);