[alsa-devel] amixer cget :Assertion `ctl && info && (info->id.name[0] || info->id.numid)' failed. Aborted

Takashi Iwai tiwai at suse.de
Mon Oct 10 14:29:31 CEST 2011


At Mon, 10 Oct 2011 09:12:53 +0800,
Raymond Yau wrote:
> 
> 2011/10/5 Takashi Iwai <tiwai at suse.de>:
> > At Wed, 5 Oct 2011 15:25:44 +0800,
> > Raymond Yau wrote:
> >>
> >> 2011/10/3 Takashi Iwai <tiwai at suse.de>:
> >> > At Sat, 1 Oct 2011 11:30:44 +0800,
> >> > Raymond Yau wrote:
> >> >>
> >> >> There is assertion when specify iface=PCM  or iface=PCM,name='' when
> >> >> using amixer -c0 cget
> >> >>
> >> >> according to the synthax
> >> >>
> >> >> [[iface=<iface>,][name='name',][index=<index>,][device=<device>,][subdevice=<subdevice>]]|[numid=<numid>]
> >> >>
> >> >>
> >> >> amixer -c0 cget iface=PCM
> >> >> amixer: control.c:258: snd_ctl_elem_info: Assertion `ctl && info &&
> >> >> (info->id.name[0] || info->id.numid)' failed.
> >> >> Aborted
> >> >>
> >> >> amixer -c0 cget iface=PCM,name=''
> >> >> amixer: control.c:258: snd_ctl_elem_info: Assertion `ctl && info &&
> >> >> (info->id.name[0] || info->id.numid)' failed.
> >> >> Aborted
> >> >
> >> > So, the empty string isn't checked before assert().  It's bad.
> >> > It must be easy to fix.  Care to create and send a patch?
> >> >
> >> >
> >>
> >> The syntax seem also wrong.
> >>
> >> [[iface=<iface>,][name='name',][index=<index>,][device=<device>,][subdevice=subdevice>]]|[numid=<numid>]
> >>
> >>
> >> it should be
> >>  [numid=<numid>] |
> >>  [[iface=<iface>,name='name'][,index=<index>][,device=<device>]] |
> >>  [[iface=<iface>,name='name'][,device=<device>][,subdevice=<subdevice>]]
> >>
> >> since you cannot specify index and subdevice at the same time
> >
> > The index and subdevice are different things.
> > Typically, the index is set > 0 when multiple elements with the same
> > iface and name are present.  The subdevice is rather specification of
> > the device itself, e.g. PCM substream number.
> >
> >
> > Takashi
> >
> 
> Please ignore the previous patch
> 
> Attach the correct patch which fix the assertion
> 
> However it report error when
> 
> amixer -c0 cget iface=PCM,
> 
> amixer -c0 cget iface=PCM,name='ITD',

Thanks for the patch!

> diff --git a/amixer/amixer.c b/amixer/amixer.c
> index 9d2855d..99160be 100644
> --- a/amixer/amixer.c
> +++ b/amixer/amixer.c
> @@ -1122,6 +1122,8 @@ static int parse_control_id(const char *str, snd_ctl_elem_id_t *id)
>  				}
>  			}
>  			*ptr = '\0';
> +			if (ptr == buf)
> +				return -EINVAL;
>  			snd_ctl_elem_id_set_name(id, buf);

This should be more intuitive such as
			if (!*buf)
				return -EINVAL;

> @@ -1145,7 +1147,13 @@ static int parse_control_id(const char *str, snd_ctl_elem_id_t *id)
>  			if (*str)
>  				return -EINVAL;
>  		}
> -	}			
> +	}
> +	if (*(str-1) == ',')
> +		return -EINVAL;

Maybe better to check the empty field iteself, such as

@@ -1138,13 +1138,10 @@ static int parse_control_id(const char *str, snd_ctl_elem_id_t *id)
 			snd_ctl_elem_id_set_subdevice(id, atoi(str));
 			while (isdigit(*str))
 				str++;
-		}
-		if (*str == ',') {
+		} else if (*str)
+			return -EINVAL;
+		if (*str == ',')
 			str++;
-		} else {
-			if (*str)
-				return -EINVAL;
-		}
 	}			
 	return 0;
 }


> +	if (numid > 0)
> +		return 0;
> +	if (size == 0)
> +		return -EINVAL;

It'd be more understandable by using snd_ctl_elem_id_*() like:

	if (!snd_ctl_elem_id_get_numd(id) &&
	    !snd_ctl_elem_id_get_name(id))
		return -EINVAL;


Takashi


More information about the Alsa-devel mailing list