Re: [PATCH] Fix various memory leaks related to stapsdt and usdt probes

Kris Van Hees <[email protected]>
Newsgroups dev.linux.lists.dtrace
Message-ID <[email protected]>
On Wed, Aug 06, 2025 at 05:02:44PM +0100, Alan Maguire wrote:
> On 06/08/2025 14:58, Kris Van Hees wrote:
> > Signed-off-by: Kris Van Hees <[email protected]>
> 
> Reviewed-by: Alan Maguire <[email protected]>
> Tested-by: Alan Maguire <[email protected]>
> 
> All stapsdt, expected USDT tests pass for me. One question at the end..
> 
> > ---
> >  libdtrace/dt_pid.c         | 14 ++++++++++----
> >  libdtrace/dt_prov_uprobe.c | 13 +++++++++++++
> >  2 files changed, 23 insertions(+), 4 deletions(-)
> > 
> > diff --git a/libdtrace/dt_pid.c b/libdtrace/dt_pid.c
> > index 42f667fe1..4af9141aa 100644
> > --- a/libdtrace/dt_pid.c
> > +++ b/libdtrace/dt_pid.c
> > @@ -1282,6 +1282,7 @@ dt_stapsdt_parse(dtrace_hdl_t *dtp, dt_proc_t *dpr, dtrace_probedesc_t *pdp,
> >  	int i, err = 0;
> >  	int fd = -1;
> >  	char *mod;
> > +	char *no_fun = "";
> >  
> >  	fd = open(path, O_RDONLY);
> >  	if (fd < 0) {
> > @@ -1415,7 +1416,7 @@ dt_stapsdt_parse(dtrace_hdl_t *dtp, dt_proc_t *dpr, dtrace_probedesc_t *pdp,
> >  				       &fun, &sym) == 0)
> >  			psp.pps_fun = (char *)fun;
> >  		else
> > -			psp.pps_fun = "";
> > +			psp.pps_fun = no_fun;
> >  		psp.pps_dev = pmp->pr_dev;
> >  		psp.pps_inum = pmp->pr_inum;
> >  		psp.pps_pid = dpr->dpr_pid;
> > @@ -1430,6 +1431,9 @@ dt_stapsdt_parse(dtrace_hdl_t *dtp, dt_proc_t *dpr, dtrace_probedesc_t *pdp,
> >  		}
> >  		if (err == -1)
> >  			break;
> > +
> > +		if (psp.pps_fun != no_fun)
> > +			free(psp.pps_fun);
> >  	}
> >  
> >  out:
> > @@ -1513,7 +1517,6 @@ dt_pid_create_stapsdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_
> >  	const dt_provider_t *pvp;
> >  	dt_proc_t *dpr = NULL;
> >  	const char *pidstr;
> > -	char *path = NULL;
> >  	pid_t pid;
> >  
> >  	assert(pcb != NULL);
> > @@ -1525,8 +1528,6 @@ dt_pid_create_stapsdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_
> >  	if (strlen(pidstr) == 0)
> >  		return 0;
> >  
> > -	asprintf(&path, "/proc/%s/maps", pidstr);
> > -
> >  	pvp = dt_provider_lookup(dtp, "stapsdt");
> >  	assert(pvp != NULL);
> >  
> > @@ -1542,8 +1543,13 @@ dt_pid_create_stapsdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_
> >  	}
> >  	dpr = dt_proc_lookup(dtp, pid);
> >  	if (dpr) {
> > +		char *path = NULL;
> > +
> > +		if (asprintf(&path, "/proc/%s/maps", pidstr) == -1)
> > +			longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
> >  		dt_pid_create_stapsdt_probes_proc(pdp, dtp, pcb,
> >  						  pvp, dpr, path);
> > +		free(path);
> >  		dt_proc_release_unlock(dtp, pid);
> >  	}
> >  
> > diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
> > index 8c8dcae0c..986ac0ead 100644
> > --- a/libdtrace/dt_prov_uprobe.c
> > +++ b/libdtrace/dt_prov_uprobe.c
> > @@ -795,6 +795,10 @@ static int populate_args(dtrace_hdl_t *dtp, const pid_probespec_t *psp,
> >  	char	*nptr = NULL, *xptr = NULL;
> >  	size_t	i;
> >  
> > +	/* Nothing to do if we already populated the arguments. */
> > +	if (upp->argc >= 0)
> > +		return 0;
> > +
> >  	upp->argc = psp->pps_xargc;
> >  
> >  	/* Copy argument value source string data (if any). */
> > @@ -941,6 +945,7 @@ static dt_probe_t *create_underlying(dtrace_hdl_t *dtp,
> >  		upp->refcntr_off = psp->pps_refcntr_off;
> >  		upp->fn = strdup(psp->pps_fn);
> >  		upp->func = NULL;
> > +		upp->argc = -1;			/* no argument data yet */
> >  		upp->tp = dt_tp_alloc(dtp);
> >  		if (upp->tp == NULL)
> >  			goto fail;
> > @@ -1716,6 +1721,7 @@ static char *uprobe_create(dev_t dev, ino_t ino, const char *mapping_fn,
> >  	rc = dprintf(fd, "%c:%s %s\n", flags & PP_IS_RETURN ? 'r' : 'p', name, spec);
> >  
> >  out:
> > +	free(spec);
> >  	if (fd != -1)
> >  		close(fd);
> >  	if (rc < 0) {
> > @@ -1975,6 +1981,12 @@ static void detach(dtrace_hdl_t *dtp, const dt_probe_t *uprp)
> >  	uprobe_delete(upp->dev, upp->inum, upp->off, upp->flags);
> >  }
> >  vi l
> > +/* Clean up the private provider data. */
> > +static void destroy(dtrace_hdl_t *dtp, void *arg)
> > +{
> > +	dt_htab_destroy((dt_htab_t *)arg);
> > +}
> > +
> >  /*
> >   * Used for underlying probes (uprobes).
> >   */
> > @@ -2014,6 +2026,7 @@ dt_provimpl_t	dt_usdt = {
> >  	.probe_destroy	= &probe_destroy,
> >  	.discover	= &discover,
> >  	.add_probe	= &add_probe_usdt,
> > +	.destroy	= &destroy,
> >  };
> >  
> 
> Do we need destroy for dt_stapsdt too, since the htab is used by the
> trampoline via copy_args() there too?

Tne hashtable is stored as part of the USDT provider, and used by stapsdt
provider probes as well.  The copy_args() function explicitly performs a
lookup for the USDT provider to get access to its private data (the htab).
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.