Bug 74213

Summary: alsa: hctl memory leak
Product: PulseAudio Reporter: Tanu Kaskinen <tanuk>
Component: alsaAssignee: pulseaudio-bugs
Status: RESOLVED FIXED QA Contact: pulseaudio-bugs
Severity: normal    
Priority: medium CC: lennart
Version: unspecified   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description Tanu Kaskinen 2014-01-30 09:14:12 UTC
Valgrind reports a memory leak in alsa-lib (but this may also be a PulseAudio bug):

==8634== HEAP SUMMARY:
==8634==     in use at exit: 52,492 bytes in 461 blocks
==8634==   total heap usage: 39,922 allocs, 39,461 frees, 5,539,674 bytes allocated
==8634== 
==8634== 80 bytes in 5 blocks are definitely lost in loss record 55 of 92
==8634==    at 0x4A06409: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==8634==    by 0x37596463BD: ??? (in /usr/lib64/libasound.so.2.0.0)
==8634==    by 0x3759646549: ??? (in /usr/lib64/libasound.so.2.0.0)
==8634==    by 0x375963C11C: snd_hctl_load (in /usr/lib64/libasound.so.2.0.0)
==8634==    by 0x37596470D8: snd_mixer_load (in /usr/lib64/libasound.so.2.0.0)
==8634==    by 0xD60B306: prepare_mixer (alsa-util.c:1506)
==8634==    by 0xD60B474: pa_alsa_open_mixer (alsa-util.c:1529)
==8634==    by 0xDC5968A: init_jacks (module-alsa-card.c:503)
==8634==    by 0xDC5A588: module_alsa_card_LTX_pa__init (module-alsa-card.c:754)
==8634==    by 0x1017998A: pa_module_load (module.c:174)
==8634==    by 0xE691E33: verify_access (module-udev-detect.c:341)
==8634==    by 0xE692393: card_changed (module-udev-detect.c:430)
==8634== 
==8634== LEAK SUMMARY:
==8634==    definitely lost: 80 bytes in 5 blocks
==8634==    indirectly lost: 0 bytes in 0 blocks
==8634==      possibly lost: 0 bytes in 0 blocks
==8634==    still reachable: 52,412 bytes in 456 blocks
==8634==         suppressed: 0 bytes in 0 blocks

This may be a PulseAudio bug too, I'm not sure. The reason why I think
it's an alsa-lib bug is this comment in prepare_mixer():

    /* Note: The hctl handle returned should not be freed.
       It is closed/freed by alsa-lib on snd_mixer_close/free */
    if (hctl && (err = snd_mixer_get_hctl(mixer, dev, hctl)) < 0) {
        pa_log_info("Unable to get hctl of mixer %s: %s", dev, pa_alsa_strerror(err));
        return -1;
    }

As far as I can tell, we close all mixer handles when we don't need them
anymore, so based on that comment, all hctl resources should get
released too. But maybe the comment is wrong or I don't understand it
correctly. I don't know the relationships between snd_mixer_open(),
snd_mixer_load(), snd_mixer_close() and snd_mixer_free(). We call both
snd_mixer_open() and snd_mixer_load(), but we never call
snd_mixer_free().
Comment 1 poljar 2014-01-30 11:50:47 UTC
I found this as well a while back. I investigated a little further. Pulseaudio's
handling seems to be fine since mixer_close() also calls free on the mixer.

Here is a valgrind report with full debugging symbols.

==12209== HEAP SUMMARY:
==12209==     in use at exit: 54,987 bytes in 175 blocks
==12209==   total heap usage: 61,729 allocs, 61,554 frees, 8,849,995 bytes allocated
==12209== 
==12209== 80 bytes in 5 blocks are definitely lost in loss record 20 of 29
==12209==    at 0x4C27730: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12209==    by 0x1063B06E: bag_new (bag.c:26)
==12209==    by 0x1063B6B7: hctl_event_handler (mixer.c:177)
==12209==    by 0x1062DC0E: snd_hctl_throw_event (hcontrol.c:205)
==12209==    by 0x1062EA94: snd_hctl_load (hcontrol.c:614)
==12209==    by 0x1063C24B: snd_mixer_load (mixer.c:576)
==12209==    by 0x103BAFE2: prepare_mixer (alsa-util.c:1506)
==12209==    by 0x103BB374: pa_alsa_open_mixer (alsa-util.c:1529)
==12209==    by 0x101A5868: module_alsa_card_LTX_pa__init (module-alsa-card.c:503)
==12209==    by 0x4E5E184: pa_module_load (module.c:174)
==12209==    by 0xFD8B8D6: verify_access (module-udev-detect.c:341)
==12209==    by 0xFD8CB2E: module_udev_detect_LTX_pa__init (module-udev-detect.c:489)
==12209== 
==12209== LEAK SUMMARY:
==12209==    definitely lost: 80 bytes in 5 blocks
==12209==    indirectly lost: 0 bytes in 0 blocks
==12209==      possibly lost: 0 bytes in 0 blocks
==12209==    still reachable: 54,907 bytes in 170 blocks
==12209==         suppressed: 0 bytes in 0 blocks

So in this Pulseaudio run, alsa-lib calls bag_new 177 times, but it frees only 
172 bags (this was checked by adding printf statements after a bag was added/removed,
if anyone wonders).

Now there is a nice warning file about leaks in the alsa-lib source tree:

> The biggest reported leak is that the global configuration is cached for
> next usage. If you do not want this feature, simply, call
> snd_config_update_free_global() after all snd_*_open*() calls. This function
> will free the cache.

I haven't investigated if this warning applies to us.
Comment 2 Raymond 2014-02-01 02:35:39 UTC
http://cgit.freedesktop.org/pulseaudio/pulseaudio/commit/src/modules/alsa/alsa-mixer.c?id=dedf1340c611c3d9b17a08e0ee18ae22afac623c


this patch mention "+/* We can listen to either a snd_hctl_t or a snd_mixer_t, but not both */" 

do this mean the mixer events from other mixer applications were no longer received after jack detection using hctl ?
Comment 3 David Henningsson 2014-09-01 14:11:28 UTC
Patch set posted here:

http://lists.freedesktop.org/archives/pulseaudio-discuss/2014-September/021422.html
Comment 4 David Henningsson 2014-09-01 14:13:56 UTC
(In reply to comment #1)
> > The biggest reported leak is that the global configuration is cached for
> > next usage. If you do not want this feature, simply, call
> > snd_config_update_free_global() after all snd_*_open*() calls. This function
> > will free the cache.
> 
> I haven't investigated if this warning applies to us.

We call snd_config_update_free_global when we quit PulseAudio (see alsa-util.c, function pa_alsa_refcnt_dec), so this should be okay.
Comment 5 Tanu Kaskinen 2015-01-15 14:40:24 UTC
David, is this bug fixed?
Comment 6 David Henningsson 2015-01-20 07:35:30 UTC
I believe it is fixed now - I pushed the patch set a few months ago. Feel free to reopen if you still see it.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.