On Sun, Jun 13, 2010 at 06:11:08PM -0400, Dave Witbrodt wrote:

> *        vol = snd_mixer_find_selem(dev->handle, sid);

>         i = 530

> In stack frame #2, we clearly have a value of 530 in "i".  When did
> that happen, since last we saw "i" was just set to 0?

Weird.

> This must mean that the "for" loop has iterated 529 times, and
> dies the 530th time.  I'm not sure if that's bad or good.  Quite

Me neither.


I just read the code. Just an idea, everything is theoretical, given
that this seems to be local to your system:

The last fix was about line 199:

198 else if (snd_mixer_selem_is_enum_capture(elem)) {
199    int cnt = snd_mixer_selem_get_enum_items(elem);

We (you) discovered that this function returned a negative value. We
also know that snd_mixer_selem_is_enum_capture must be true, otherwise,
we wouldn't enter line 199 at all.

Ok, now let's go back with this knowledge to line 139:

138         else if (snd_mixer_selem_is_enum_capture(elem)) {
139            dev->numselems += snd_mixer_selem_get_enum_items(elem);

and later:

144   dev->selems = calloc(dev->numselems, sizeof(PxSelem));


I wonder what happens if snd_mixer_selem_get_enum_items in line 139
returns a negative value as in line 199. This would make dev->numselems
decrease and finally result in too few memory for dev->selems.

When traversing this memory later, the iterator would finally make an
out of bound access, perhaps causing a segfault.

It could also be the case that some end markers were already
overwritten, perhaps in your loop which increments i to 530.

Possible approaches:

   1. Change line 139 to always increment, never decrement

   2. Artificially increase the memory pool for dev->selems

   3. Add an assertion / check to the for loop comparing i against
      dev->numselems.

   4. Understand why things are like they are on your system, understand
      the code and handle the corner case correctly.


Find attached a "debug patch" that adds some noise to the output and
hopefully gives you an idea where things go wrong.

This is nothing for productive use, but it might move you a little
closer to the culprit. If it starts with this patch, try removing the
constant calloc size multiplier for line 144 and see if it fails again.
You can also play with the constant until you run out of memory. ;)

Things you could try, too: unload the kernel drivers for your various
soundcards, one at a time, until audacity starts.


> (At this point, it would be appropriate if someone could change the
> title of this bug in the BTS, since the complaint about JACK not
> running had nothing to do with the problem.  I don't know my way
> around the BTS well enough, yet, to do that -- not even sure if I
> have the permissions to do it.)

[x] done


HTH

-- 
mail: a...@thur.de      http://adi.thur.de      PGP/GPG: key via keyserver
diff --git a/lib-src/portmixer/src/px_linux_alsa.c b/lib-src/portmixer/src/px_linux_alsa.c
index 2b4e70f..e36bf7d 100644
--- a/lib-src/portmixer/src/px_linux_alsa.c
+++ b/lib-src/portmixer/src/px_linux_alsa.c
@@ -136,12 +136,14 @@ static int open_mixer(PxDev *dev, int card, int playback)
                dev->numselems++;
             }
             else if (snd_mixer_selem_is_enum_capture(elem)) {
-               dev->numselems += snd_mixer_selem_get_enum_items(elem);
+                if (0 < snd_mixer_selem_get_enum_items(elem)) {
+                    dev->numselems += snd_mixer_selem_get_enum_items(elem);
+                }
             }
          }
       }
 
-      dev->selems = calloc(dev->numselems, sizeof(PxSelem));
+      dev->selems = calloc(2*(dev->numselems), sizeof(PxSelem));
       if (dev->selems == NULL) {
          break;
       }
@@ -164,9 +166,13 @@ static int open_mixer(PxDev *dev, int card, int playback)
                         snd_mixer_selem_get_name(elem),
                         snd_mixer_selem_get_index(elem));
       
-               dev->selems[i].elem = elem;
-               dev->selems[i].index = snd_mixer_selem_get_index(elem);
-               dev->selems[i].name = strdup(name);
+               if (i < dev->numselems) {
+                   dev->selems[i].elem = elem;
+                   dev->selems[i].index = snd_mixer_selem_get_index(elem);
+                   dev->selems[i].name = strdup(name);
+               } else {
+                   printf ("broken: i larger than dev->numselems\n");
+               }
                if (!dev->selems[i].name) {
                   break;
                }
_______________________________________________
pkg-multimedia-maintainers mailing list
pkg-multimedia-maintainers@lists.alioth.debian.org
http://lists.alioth.debian.org/mailman/listinfo/pkg-multimedia-maintainers

Reply via email to