Hi Takashi, i think mix is same as ext->data instead ext. ext is of extplug_priv_t *; so it is definitely not mix which is of snd_pcm_upmix_t 33 struct snd_pcm_upmix { 34 snd_pcm_extplug_t ext; typedef struct snd_pcm_extplug_priv { snd_pcm_plugin_t plug; snd_pcm_extplug_t *data; between upmix and extplug_priv, there is a gap plug, which forbid ext to be converted to mix directly. so free(ext) in snd_pcm_extplug_close does NOT promise it will free mix too. 2017-08-30 15:02 GMT+08:00 Takashi Iwai <tiwai@xxxxxxx>: > On Wed, 30 Aug 2017 07:51:59 +0200, > boozer asm wrote: > > > > eg. > > in function:SND_PCM_PLUGIN_DEFINE_FUNC(upmix) > > 487 mix = calloc(1, sizeof(*mix)); > > 488 if (mix == NULL) > > 489 return -ENOMEM; > > > > mix is allocated here. but at close function, it is not freed, and no > > __destructor function available to free it. > > > > and in alsa-lib/src/pcm/pcm_extplug.c > > static int snd_pcm_extplug_close(snd_pcm_t *pcm) > > { > > extplug_priv_t *ext = pcm->private_data; > > > > snd_pcm_close(ext->plug.gen.slave); > > clear_ext_params(ext); > > if (ext->data->callback->close) > > { > > ext->data->callback->close(ext->data); > > } > > free(ext); > > return 0; > > } > > this function does NOT free ext->data. > > and > > 366 static int upmix_close(snd_pcm_extplug_t *ext) > > 367 { > > 368 snd_pcm_upmix_t *mix = (snd_pcm_upmix_t *)ext; > > 369 free(mix->delayline[0]); > > 370 free(mix->delayline[1]); > > 371 return 0; > > 372 } > > > > and this function does NOT free mix itself. > > > > so I think there is memory leak. > > It's freed in snd_pcm_extplug_close(). > mix is identical with ext in the case of upmix. > > > Takashi > _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel