From 0267a3f3f13e16bc92b890e1d5bd49c5bd5c58e3 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 20 Feb 2011 17:01:15 +0100 Subject: [PATCH] Fix alsa_init() error path. If alsa_init() fails, alsa_write_post_select() removes the buffer tree node and sets t->error to a negative value. para_audiod (or para_write) then calls alsa->close() to deallocate any resources. At this point wn->private_data is non-NULL while pad->handle _is_ NULL. The subsequent call to snd_pcm_nonblock() therefore triggers the assertion para_audiod: pcm.c:724: snd_pcm_nonblock: Assertion `pcm' failed. which aborts para_audiod. Fix this bug by freeing the ->private_data pointer already in alsa_write_post_select() if alsa_init() fails. This way, ->private_data and pad->handle are either both NULL or both non-NULL, which meets the expectations of alsa_close(). --- alsa_write.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/alsa_write.c b/alsa_write.c index d6493418..ae3bbfba 100644 --- a/alsa_write.c +++ b/alsa_write.c @@ -231,10 +231,9 @@ again: if (!pad) { int32_t val; - pad = para_calloc(sizeof(*pad)); - wn->private_data = pad; if (bytes == 0) /* no data available */ return; + pad = para_calloc(sizeof(*pad)); get_btr_sample_rate(btrn, &val); pad->sample_rate = val; get_btr_channels(btrn, &val); @@ -245,8 +244,11 @@ again: PARA_INFO_LOG("%d channel(s), %dHz\n", pad->channels, pad->sample_rate); ret = alsa_init(pad, wn->conf); - if (ret < 0) + if (ret < 0) { + free(pad); goto err; + } + wn->private_data = pad; wn->min_iqs = pad->bytes_per_frame; goto again; } -- 2.30.2