From: Takashi Iwai Date: Tue, 21 Dec 2004 14:11:00 +0000 (+0000) Subject: Change error message handling X-Git-Tag: v1.0.8~25 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=2b54677fdb34cca314f5b9560ccbafbf784590f5;p=alsa-lib.git Change error message handling Change the handling of non-fatal errors. Now the non-fatal error messages are not shown in stderr and no assert() as default. The behavior can be changed with LIBASOUND_DEBUG environment variable. --- diff --git a/NOTES b/NOTES index 2630638b..9a862ae5 100644 --- a/NOTES +++ b/NOTES @@ -14,3 +14,17 @@ this API, because they are no longer used: #define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_SW_PARAMS_API + + +Verbose Error Messages +====================== + +Since version 1.0.8, assert() for some non-fatal errors are removed +and error messages are no longer shown to stderr as default. Instead, +the error messages appear only when the environment variable +LIBASOUND_DEBUG is set. When LIBASOUND_DEBUG=assert is set, the +default error message handler calls assert() to catch with a +debugger. + +This feature is disabled when --with-debug=no is passed to configure, +i.e. no strict checking is done in alsa-lib. diff --git a/include/local.h b/include/local.h index f57cc182..539c36ac 100644 --- a/include/local.h +++ b/include/local.h @@ -155,6 +155,22 @@ int safe_strtol(const char *str, long *val); int snd_send_fd(int sock, void *data, size_t len, int fd); int snd_receive_fd(int sock, void *data, size_t len, int *fd); +/* + * error messages + */ +#ifndef NDEBUG +#define CHECK_SANITY(x) x +extern snd_lib_error_handler_t snd_err_msg; +#define SNDMSG(args...) snd_err_msg(__FILE__, __LINE__, __FUNCTION__, 0, ##args) +#define SYSMSG(args...) snd_err_msg(__FILE__, __LINE__, __FUNCTION__, errno, ##args) +#else +#define CHECK_SANITY(x) 0 /* not evaluated */ +#define SNDMSG(args...) /* nop */ +#define SYSMSG(args...) /* nop */ +#endif + +/* + */ #define HAVE_GNU_LD #define HAVE_ELF #define HAVE_ASM_PREVIOUS_DIRECTIVE diff --git a/src/error.c b/src/error.c index 3595ed21..30beb331 100644 --- a/src/error.c +++ b/src/error.c @@ -100,6 +100,10 @@ snd_lib_error_handler_t snd_lib_error = snd_lib_error_default; int snd_lib_error_set_handler(snd_lib_error_handler_t handler) { snd_lib_error = handler == NULL ? snd_lib_error_default : handler; +#ifndef NDEBUG + if (snd_lib_error != snd_lib_error_default) + snd_err_msg = snd_lib_error; +#endif return 0; } @@ -111,3 +115,30 @@ const char *snd_asoundlib_version(void) { return SND_LIB_VERSION_STR; } + +#ifndef NDEBUG +/* + * internal error handling + */ +static void snd_err_msg_default(const char *file, int line, const char *function, int err, const char *fmt, ...) +{ + va_list arg; + const char *verbose; + + verbose = getenv("LIBASOUND_DEBUG"); + if (! verbose || ! *verbose) + return; + va_start(arg, fmt); + fprintf(stderr, "ALSA lib %s:%i:(%s) ", file, line, function); + vfprintf(stderr, fmt, arg); + if (err) + fprintf(stderr, ": %s", snd_strerror(err)); + putc('\n', stderr); + va_end(arg); + if (! strcmp(verbose, "assert")) + assert(0); +} + +snd_lib_error_handler_t snd_err_msg = snd_err_msg_default; + +#endif diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 1998ef4a..503e89a6 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -797,7 +797,8 @@ int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) int snd_pcm_hw_free(snd_pcm_t *pcm) { int err; - assert(pcm->setup); + if (! pcm->setup) + return 0; if (pcm->mmap_channels) { err = snd_pcm_munmap(pcm); if (err < 0) @@ -820,17 +821,21 @@ int snd_pcm_hw_free(snd_pcm_t *pcm) int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params) { int err; - assert(pcm->setup); /* the hw_params must be set at first!!! */ + /* the hw_params must be set at first!!! */ + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } if (! params->avail_min || ! params->xfer_align) return -EINVAL; if (params->start_threshold <= pcm->buffer_size && params->start_threshold > (pcm->buffer_size / params->avail_min) * params->avail_min) { - SNDERR("snd_pcm_sw_params: params->avail_min problem for start_threshold"); + SNDMSG("params->avail_min problem for start_threshold"); return -EINVAL; } if (params->start_threshold <= pcm->buffer_size && params->start_threshold > (pcm->buffer_size / params->xfer_align) * params->xfer_align) { - SNDERR("snd_pcm_sw_params: params->xfer_align problem for start_threshold"); + SNDMSG("params->xfer_align problem for start_threshold"); return -EINVAL; } err = pcm->ops->sw_params(pcm->op_arg, params); @@ -887,7 +892,10 @@ snd_pcm_state_t snd_pcm_state(snd_pcm_t *pcm) int snd_pcm_hwsync(snd_pcm_t *pcm) { assert(pcm); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } return pcm->fast_ops->hwsync(pcm->fast_op_arg); } @@ -910,7 +918,10 @@ int snd_pcm_hwsync(snd_pcm_t *pcm) int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp) { assert(pcm); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } return pcm->fast_ops->delay(pcm->fast_op_arg, delayp); } @@ -929,7 +940,10 @@ int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp) int snd_pcm_resume(snd_pcm_t *pcm) { assert(pcm); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } return pcm->fast_ops->resume(pcm->fast_op_arg); } @@ -941,7 +955,10 @@ int snd_pcm_resume(snd_pcm_t *pcm) int snd_pcm_prepare(snd_pcm_t *pcm) { assert(pcm); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } return pcm->fast_ops->prepare(pcm->fast_op_arg); } @@ -955,7 +972,10 @@ int snd_pcm_prepare(snd_pcm_t *pcm) int snd_pcm_reset(snd_pcm_t *pcm) { assert(pcm); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } return pcm->fast_ops->reset(pcm->fast_op_arg); } @@ -967,7 +987,10 @@ int snd_pcm_reset(snd_pcm_t *pcm) int snd_pcm_start(snd_pcm_t *pcm) { assert(pcm); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } return pcm->fast_ops->start(pcm->fast_op_arg); } @@ -985,7 +1008,10 @@ int snd_pcm_start(snd_pcm_t *pcm) int snd_pcm_drop(snd_pcm_t *pcm) { assert(pcm); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } return pcm->fast_ops->drop(pcm->fast_op_arg); } @@ -1005,7 +1031,10 @@ int snd_pcm_drop(snd_pcm_t *pcm) int snd_pcm_drain(snd_pcm_t *pcm) { assert(pcm); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } return pcm->fast_ops->drain(pcm->fast_op_arg); } @@ -1022,7 +1051,10 @@ int snd_pcm_drain(snd_pcm_t *pcm) int snd_pcm_pause(snd_pcm_t *pcm, int enable) { assert(pcm); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } return pcm->fast_ops->pause(pcm->fast_op_arg, enable); } @@ -1036,8 +1068,12 @@ int snd_pcm_pause(snd_pcm_t *pcm, int enable) snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames) { assert(pcm); - assert(pcm->setup); - assert(frames > 0); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } + if (frames == 0) + return 0; return pcm->fast_ops->rewind(pcm->fast_op_arg, frames); } @@ -1055,8 +1091,12 @@ snd_pcm_sframes_t snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames) #endif { assert(pcm); - assert(pcm->setup); - assert(frames > 0); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } + if (frames == 0) + return 0; return pcm->fast_ops->forward(pcm->fast_op_arg, frames); } use_default_symbol_version(__snd_pcm_forward, snd_pcm_forward, ALSA_0.9.0rc8); @@ -1082,8 +1122,14 @@ snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_ufr { assert(pcm); assert(size == 0 || buffer); - assert(pcm->setup); - assert(pcm->access == SND_PCM_ACCESS_RW_INTERLEAVED); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } + if (pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED) { + SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access)); + return -EINVAL; + } return _snd_pcm_writei(pcm, buffer, size); } @@ -1108,8 +1154,14 @@ snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t { assert(pcm); assert(size == 0 || bufs); - assert(pcm->setup); - assert(pcm->access == SND_PCM_ACCESS_RW_NONINTERLEAVED); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } + if (pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) { + SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access)); + return -EINVAL; + } return _snd_pcm_writen(pcm, bufs, size); } @@ -1134,8 +1186,14 @@ snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t { assert(pcm); assert(size == 0 || buffer); - assert(pcm->setup); - assert(pcm->access == SND_PCM_ACCESS_RW_INTERLEAVED); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } + if (pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED) { + SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access)); + return -EINVAL; + } return _snd_pcm_readi(pcm, buffer, size); } @@ -1160,8 +1218,14 @@ snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t s { assert(pcm); assert(size == 0 || bufs); - assert(pcm->setup); - assert(pcm->access == SND_PCM_ACCESS_RW_NONINTERLEAVED); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } + if (pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) { + SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access)); + return -EINVAL; + } return _snd_pcm_readn(pcm, bufs, size); } @@ -1180,7 +1244,7 @@ int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2) if (fd1 < 0 || fd2 < 0) return -ENOSYS; if (ioctl(fd1, SNDRV_PCM_IOCTL_LINK, fd2) < 0) { - SYSERR("SNDRV_PCM_IOCTL_LINK failed"); + SYSMSG("SNDRV_PCM_IOCTL_LINK failed"); return -errno; } return 0; @@ -1196,7 +1260,7 @@ int snd_pcm_unlink(snd_pcm_t *pcm) int fd; fd = _snd_pcm_link_descriptor(pcm); if (ioctl(fd, SNDRV_PCM_IOCTL_UNLINK) < 0) { - SYSERR("SNDRV_PCM_IOCTL_UNLINK failed"); + SYSMSG("SNDRV_PCM_IOCTL_UNLINK failed"); return -errno; } return 0; @@ -1248,7 +1312,10 @@ int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int s if (err < 0) return err; } - assert(pcm->poll_fd >= 0); + if (! pcm->poll_fd < 0) { + SNDMSG("poll_fd < 0"); + return -EIO; + } if (space >= 1 && pfds) { pfds->fd = pcm->poll_fd; pfds->events = pcm->poll_events | POLLERR | POLLNVAL; @@ -1470,7 +1537,8 @@ static const char *snd_pcm_tstamp_mode_names[] = { */ const char *snd_pcm_stream_name(snd_pcm_stream_t stream) { - assert(stream <= SND_PCM_STREAM_LAST); + if (stream > SND_PCM_STREAM_LAST) + return NULL; return snd_pcm_stream_names[stream]; } @@ -1564,7 +1632,8 @@ const char *snd_pcm_subformat_description(snd_pcm_subformat_t subformat) */ const char *snd_pcm_start_mode_name(snd_pcm_start_t mode) { - assert(mode <= SND_PCM_START_LAST); + if (mode > SND_PCM_START_LAST) + return NULL; return snd_pcm_start_mode_names[mode]; } @@ -1579,7 +1648,8 @@ link_warning(snd_pcm_start_mode_name, "Warning: start_mode is deprecated, consid */ const char *snd_pcm_xrun_mode_name(snd_pcm_xrun_t mode) { - assert(mode <= SND_PCM_XRUN_LAST); + if (mode > SND_PCM_XRUN_LAST) + return NULL; return snd_pcm_xrun_mode_names[mode]; } @@ -1638,7 +1708,10 @@ int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, snd_output_t *out) { assert(pcm); assert(out); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } snd_output_printf(out, "stream : %s\n", snd_pcm_stream_name(pcm->stream)); snd_output_printf(out, "access : %s\n", snd_pcm_access_name(pcm->access)); snd_output_printf(out, "format : %s\n", snd_pcm_format_name(pcm->format)); @@ -1664,7 +1737,10 @@ int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, snd_output_t *out) { assert(pcm); assert(out); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } snd_output_printf(out, "tstamp_mode : %s\n", snd_pcm_tstamp_mode_name(pcm->tstamp_mode)); snd_output_printf(out, "period_step : %d\n", pcm->period_step); snd_output_printf(out, "sleep_min : %d\n", pcm->sleep_min); @@ -1734,7 +1810,10 @@ int snd_pcm_dump(snd_pcm_t *pcm, snd_output_t *out) snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes) { assert(pcm); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } return bytes * 8 / pcm->frame_bits; } @@ -1747,7 +1826,10 @@ snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes) ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames) { assert(pcm); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } return frames * pcm->frame_bits / 8; } @@ -1760,7 +1842,10 @@ ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames) long snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes) { assert(pcm); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } return bytes * 8 / pcm->sample_bits; } @@ -1773,7 +1858,10 @@ long snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes) ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, long samples) { assert(pcm); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } return samples * pcm->sample_bits / 8; } @@ -1819,7 +1907,10 @@ int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm, */ snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler) { - assert(handler->type == SND_ASYNC_HANDLER_PCM); + if (handler->type == SND_ASYNC_HANDLER_PCM) { + SNDMSG("invalid handler type %d", handler->type); + return NULL; + } return handler->u.pcm; } @@ -2099,7 +2190,10 @@ int snd_pcm_wait(snd_pcm_t *pcm, int timeout) err = snd_pcm_poll_descriptors(pcm, &pfd, 1); if (err < 0) return err; - assert(err == 1); + if (err != 1) { + SNDMSG("invalid poll descriptors %d\n", err); + return -EIO; + } __retry: err_poll = poll(&pfd, 1, timeout); if (err_poll < 0) @@ -2250,7 +2344,8 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes break; } default: - assert(0); + SNDMSG("invalid format width %d", width); + return -EINVAL; } return 0; } @@ -2417,7 +2512,8 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t break; } default: - assert(0); + SNDMSG("invalid format width %d", width); + return -EINVAL; } return 0; } @@ -2440,8 +2536,14 @@ int snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_ int width = snd_pcm_format_physical_width(format); assert(dst_areas); assert(src_areas); - assert(channels > 0); - assert(frames > 0); + if (! channels) { + SNDMSG("invalid channels %d", channels); + return -EINVAL; + } + if (! frames) { + SNDMSG("invalid frames %ld", frames); + return -EINVAL; + } while (channels > 0) { unsigned int step = src_areas->step; void *src_addr = src_areas->addr; @@ -2524,7 +2626,11 @@ int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, snd_output_t *out) */ int snd_pcm_hw_params_can_mmap_sample_resolution(const snd_pcm_hw_params_t *params) { - assert(params && params->info != ~0U); + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return 0; /* FIXME: should be a negative error? */ + } return !!(params->info & SNDRV_PCM_INFO_MMAP_VALID); } @@ -2541,7 +2647,11 @@ int snd_pcm_hw_params_can_mmap_sample_resolution(const snd_pcm_hw_params_t *para */ int snd_pcm_hw_params_is_double(const snd_pcm_hw_params_t *params) { - assert(params && params->info != ~0U); + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return 0; /* FIXME: should be a negative error? */ + } return !!(params->info & SNDRV_PCM_INFO_DOUBLE); } @@ -2558,7 +2668,11 @@ int snd_pcm_hw_params_is_double(const snd_pcm_hw_params_t *params) */ int snd_pcm_hw_params_is_batch(const snd_pcm_hw_params_t *params) { - assert(params && params->info != ~0U); + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return 0; /* FIXME: should be a negative error? */ + } return !!(params->info & SNDRV_PCM_INFO_BATCH); } @@ -2575,7 +2689,11 @@ int snd_pcm_hw_params_is_batch(const snd_pcm_hw_params_t *params) */ int snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params) { - assert(params && params->info != ~0U); + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return 0; /* FIXME: should be a negative error? */ + } return !!(params->info & SNDRV_PCM_INFO_BLOCK_TRANSFER); } @@ -2592,7 +2710,11 @@ int snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params) */ int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params) { - assert(params && params->info != ~0U); + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return 0; /* FIXME: should be a negative error? */ + } return !!(params->info & SNDRV_PCM_INFO_OVERRANGE); } @@ -2609,7 +2731,11 @@ int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params) */ int snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params) { - assert(params && params->info != ~0U); + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return 0; /* FIXME: should be a negative error? */ + } return !!(params->info & SNDRV_PCM_INFO_PAUSE); } @@ -2626,7 +2752,11 @@ int snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params) */ int snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params) { - assert(params && params->info != ~0U); + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return 0; /* FIXME: should be a negative error? */ + } return !!(params->info & SNDRV_PCM_INFO_RESUME); } @@ -2643,7 +2773,11 @@ int snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params) */ int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params) { - assert(params && params->info != ~0U); + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return 0; /* FIXME: should be a negative error? */ + } return !!(params->info & SNDRV_PCM_INFO_HALF_DUPLEX); } @@ -2660,7 +2794,11 @@ int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params) */ int snd_pcm_hw_params_is_joint_duplex(const snd_pcm_hw_params_t *params) { - assert(params && params->info != ~0U); + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return 0; /* FIXME: should be a negative error? */ + } return !!(params->info & SNDRV_PCM_INFO_JOINT_DUPLEX); } @@ -2677,7 +2815,11 @@ int snd_pcm_hw_params_is_joint_duplex(const snd_pcm_hw_params_t *params) */ int snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params) { - assert(params && params->info != ~0U); + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return 0; /* FIXME: should be a negative error? */ + } return !!(params->info & SNDRV_PCM_INFO_SYNC_START); } @@ -2695,7 +2837,11 @@ int snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params) int snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params, unsigned int *rate_num, unsigned int *rate_den) { - assert(params && params->rate_den != 0); + assert(params); + if (CHECK_SANITY(params->rate_den == 0)) { + SNDMSG("invalid rate_den value"); + return -EINVAL; + } *rate_num = params->rate_num; *rate_den = params->rate_den; return 0; @@ -2712,7 +2858,11 @@ int snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params, */ int snd_pcm_hw_params_get_sbits(const snd_pcm_hw_params_t *params) { - assert(params && params->msbits != 0); + assert(params); + if (CHECK_SANITY(params->msbits == 0)) { + SNDMSG("invalid msbits value"); + return -EINVAL; + } return params->msbits; } @@ -2727,7 +2877,11 @@ int snd_pcm_hw_params_get_sbits(const snd_pcm_hw_params_t *params) */ int snd_pcm_hw_params_get_fifo_size(const snd_pcm_hw_params_t *params) { - assert(params && params->info != ~0U); + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return -EINVAL; + } return params->fifo_size; } @@ -4978,7 +5132,10 @@ int snd_pcm_hw_params_get_min_align(const snd_pcm_hw_params_t *params, snd_pcm_u int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params) { assert(pcm && params); - assert(pcm->setup); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } params->tstamp_mode = pcm->tstamp_mode; params->period_step = pcm->period_step; params->sleep_min = pcm->sleep_min; @@ -5087,8 +5244,8 @@ int snd_pcm_sw_params_set_start_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params params->start_threshold = pcm->boundary; break; default: - assert(0); - break; + SNDMSG("invalid start mode value %d\n", val); + return -EINVAL; } return 0; } @@ -5135,8 +5292,8 @@ int snd_pcm_sw_params_set_xrun_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, params->stop_threshold = pcm->boundary; break; default: - assert(0); - break; + SNDMSG("invalid xrun mode value %d\n", val); + return -EINVAL; } return 0; } @@ -5175,7 +5332,10 @@ int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *param #endif { assert(pcm && params); - assert(val <= SND_PCM_TSTAMP_LAST); + if (CHECK_SANITY(val > SND_PCM_TSTAMP_LAST)) { + SNDMSG("invalid tstamp_mode value %d", val); + return -EINVAL; + } params->tstamp_mode = val; return 0; } @@ -5291,7 +5451,10 @@ int snd_pcm_sw_params_set_xfer_align(snd_pcm_t *pcm, snd_pcm_sw_params_t *params #endif { assert(pcm && params); - assert(val % pcm->min_align == 0); + if (CHECK_SANITY(val % pcm->min_align)) { + SNDMSG("xfer_align (%ld) is not aligned to min_align (%ld)", val, pcm->min_align); + return -EINVAL; + } params->xfer_align = val; return 0; } @@ -5420,7 +5583,11 @@ int snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t #endif { assert(pcm && params); - assert(val < pcm->buffer_size); + if (CHECK_SANITY(val >= pcm->buffer_size)) { + SNDMSG("invalid silent_threshold value %ld (buffer_size = %ld)", + val, pcm->buffer_size); + return -EINVAL; + } params->silence_threshold = val; return 0; } @@ -5470,7 +5637,11 @@ int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm, snd_pcm_sw_params_t *para #endif { assert(pcm && params); - assert(val >= pcm->boundary || val <= pcm->buffer_size); + if (CHECK_SANITY(val < pcm->boundary && val > pcm->buffer_size)) { + SNDMSG("invalid silence_size %ld (boundary %ld, buffer_size %ld)", + val, pcm->boundary, pcm->buffer_size); + return -EINVAL; + } params->silence_size = val; return 0; } @@ -5961,8 +6132,16 @@ snd_pcm_sframes_t snd_pcm_mmap_commit(snd_pcm_t *pcm, snd_pcm_uframes_t frames) { assert(pcm); - assert(offset == *pcm->appl.ptr % pcm->buffer_size); - assert(frames <= snd_pcm_mmap_avail(pcm)); + if (CHECK_SANITY(offset != *pcm->appl.ptr % pcm->buffer_size)) { + SNDMSG("commit offset (%ld) doesn't match with appl_ptr (%ld) %% buf_size (%ld)", + offset, *pcm->appl.ptr, pcm->buffer_size); + return -EPIPE; + } + if (CHECK_SANITY(frames > snd_pcm_mmap_avail(pcm))) { + SNDMSG("commit frames (%ld) overflow (avail = %ld)", frames, + snd_pcm_mmap_avail(pcm)); + return -EPIPE; + } return pcm->fast_ops->mmap_commit(pcm->fast_op_arg, offset, frames); } @@ -6065,7 +6244,8 @@ snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_ frames = size; if (frames > (snd_pcm_uframes_t) avail) frames = avail; - assert(frames != 0); + if (! frames) + break; err = func(pcm, areas, offset, frames); if (err < 0) break; @@ -6136,7 +6316,8 @@ snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area frames = size; if (frames > (snd_pcm_uframes_t) avail) frames = avail; - assert(frames != 0); + if (! frames) + break; err = func(pcm, areas, offset, frames); if (err < 0) break; diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index 9aa315f1..cf6abe66 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -113,19 +113,6 @@ typedef struct { ((hw)->mmap_status->tstamp) #endif /* DOC_HIDDEN */ -static inline int check_std_error(int error) -{ - switch (error) { - case -EAGAIN: - case -EPIPE: - case -ESTRPIPE: - case -ENXIO: - case -ENOSYS: - return 0; - } - return 1; -} - struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm) { struct timespec res; @@ -143,7 +130,7 @@ static int sync_ptr1(snd_pcm_hw_t *hw, unsigned int flags) err = ioctl((hw)->fd, SNDRV_PCM_IOCTL_SYNC_PTR, (hw)->sync_ptr); if (err < 0) { err = -errno; - SYSERR("SNDRV_PCM_IOCTL_SYNC_PTR failed"); + SYSMSG("SNDRV_PCM_IOCTL_SYNC_PTR failed"); return err; } return 0; @@ -162,7 +149,7 @@ static int snd_pcm_hw_nonblock(snd_pcm_t *pcm, int nonblock) if ((flags = fcntl(fd, F_GETFL)) < 0) { err = -errno; - SYSERR("F_GETFL failed"); + SYSMSG("F_GETFL failed"); return err; } if (nonblock) @@ -171,7 +158,7 @@ static int snd_pcm_hw_nonblock(snd_pcm_t *pcm, int nonblock) flags &= ~O_NONBLOCK; if (fcntl(fd, F_SETFL, flags) < 0) { err = -errno; - SYSERR("F_SETFL for O_NONBLOCK failed"); + SYSMSG("F_SETFL for O_NONBLOCK failed"); return err; } return 0; @@ -185,7 +172,7 @@ static int snd_pcm_hw_async(snd_pcm_t *pcm, int sig, pid_t pid) if ((flags = fcntl(fd, F_GETFL)) < 0) { err = -errno; - SYSERR("F_GETFL failed"); + SYSMSG("F_GETFL failed"); return err; } if (sig >= 0) @@ -194,19 +181,19 @@ static int snd_pcm_hw_async(snd_pcm_t *pcm, int sig, pid_t pid) flags &= ~O_ASYNC; if (fcntl(fd, F_SETFL, flags) < 0) { err = -errno; - SYSERR("F_SETFL for O_ASYNC failed"); + SYSMSG("F_SETFL for O_ASYNC failed"); return err; } if (sig < 0) return 0; if (fcntl(fd, F_SETSIG, (long)sig) < 0) { err = -errno; - SYSERR("F_SETSIG failed"); + SYSMSG("F_SETSIG failed"); return err; } if (fcntl(fd, F_SETOWN, (long)pid) < 0) { err = -errno; - SYSERR("F_SETOWN failed"); + SYSMSG("F_SETOWN failed"); return err; } return 0; @@ -218,7 +205,7 @@ static int snd_pcm_hw_info(snd_pcm_t *pcm, snd_pcm_info_t * info) int fd = hw->fd, err; if (ioctl(fd, SNDRV_PCM_IOCTL_INFO, info) < 0) { err = -errno; - SYSERR("SNDRV_PCM_IOCTL_INFO failed"); + SYSMSG("SNDRV_PCM_IOCTL_INFO failed"); return err; } return 0; @@ -300,7 +287,7 @@ static int snd_pcm_hw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) } else { if (hw_refine_call(hw, params) < 0) { err = -errno; - // SYSERR("SNDRV_PCM_IOCTL_HW_REFINE failed"); + // SYSMSG("SNDRV_PCM_IOCTL_HW_REFINE failed"); return err; } } @@ -353,7 +340,7 @@ static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) if (hw_params_call(hw, params) < 0) { _err: err = -errno; - SYSERR("SNDRV_PCM_IOCTL_HW_PARAMS failed"); + SYSMSG("SNDRV_PCM_IOCTL_HW_PARAMS failed"); return err; } } @@ -379,7 +366,7 @@ static int snd_pcm_hw_hw_free(snd_pcm_t *pcm) int fd = hw->fd, err; if (ioctl(fd, SNDRV_PCM_IOCTL_HW_FREE) < 0) { err = -errno; - SYSERR("SNDRV_PCM_IOCTL_HW_FREE failed"); + SYSMSG("SNDRV_PCM_IOCTL_HW_FREE failed"); return err; } return 0; @@ -402,7 +389,7 @@ static int snd_pcm_hw_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params) } if (ioctl(fd, SNDRV_PCM_IOCTL_SW_PARAMS, params) < 0) { err = -errno; - SYSERR("SNDRV_PCM_IOCTL_SW_PARAMS failed"); + SYSMSG("SNDRV_PCM_IOCTL_SW_PARAMS failed"); return err; } hw->mmap_control->avail_min = params->avail_min; @@ -417,7 +404,7 @@ static int snd_pcm_hw_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info i.channel = info->channel; if (ioctl(fd, SNDRV_PCM_IOCTL_CHANNEL_INFO, &i) < 0) { err = -errno; - SYSERR("SNDRV_PCM_IOCTL_CHANNEL_INFO failed"); + SYSMSG("SNDRV_PCM_IOCTL_CHANNEL_INFO failed"); return err; } info->channel = i.channel; @@ -439,7 +426,7 @@ static int snd_pcm_hw_status(snd_pcm_t *pcm, snd_pcm_status_t * status) int fd = hw->fd, err; if (ioctl(fd, SNDRV_PCM_IOCTL_STATUS, status) < 0) { err = -errno; - SYSERR("SNDRV_PCM_IOCTL_STATUS failed"); + SYSMSG("SNDRV_PCM_IOCTL_STATUS failed"); return err; } if (SNDRV_PROTOCOL_VERSION(2, 0, 5) > hw->version) { @@ -486,8 +473,7 @@ static int snd_pcm_hw_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp) } if (ioctl(fd, SNDRV_PCM_IOCTL_DELAY, delayp) < 0) { err = -errno; - if (check_std_error(err)) - SYSERR("SNDRV_PCM_IOCTL_DELAY failed"); + SYSMSG("SNDRV_PCM_IOCTL_DELAY failed"); return err; } return 0; @@ -505,8 +491,7 @@ static int snd_pcm_hw_hwsync(snd_pcm_t *pcm) } else { if (ioctl(fd, SNDRV_PCM_IOCTL_HWSYNC) < 0) { err = -errno; - if (check_std_error(err)) - SYSERR("SNDRV_PCM_IOCTL_HWSYNC failed"); + SYSMSG("SNDRV_PCM_IOCTL_HWSYNC failed"); return err; } } @@ -532,7 +517,7 @@ static int snd_pcm_hw_prepare(snd_pcm_t *pcm) int fd = hw->fd, err; if (ioctl(fd, SNDRV_PCM_IOCTL_PREPARE) < 0) { err = -errno; - SYSERR("SNDRV_PCM_IOCTL_PREPARE failed"); + SYSMSG("SNDRV_PCM_IOCTL_PREPARE failed"); return err; } return sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL); @@ -544,7 +529,7 @@ static int snd_pcm_hw_reset(snd_pcm_t *pcm) int fd = hw->fd, err; if (ioctl(fd, SNDRV_PCM_IOCTL_RESET) < 0) { err = -errno; - SYSERR("SNDRV_PCM_IOCTL_RESET failed"); + SYSMSG("SNDRV_PCM_IOCTL_RESET failed"); return err; } return sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL); @@ -560,7 +545,7 @@ static int snd_pcm_hw_start(snd_pcm_t *pcm) #endif if (ioctl(hw->fd, SNDRV_PCM_IOCTL_START) < 0) { err = -errno; - SYSERR("SNDRV_PCM_IOCTL_START failed"); + SYSMSG("SNDRV_PCM_IOCTL_START failed"); #if 0 if (err == -EBADFD) SNDERR("PCM state = %s", snd_pcm_state_name(snd_pcm_hw_state(pcm))); @@ -576,7 +561,7 @@ static int snd_pcm_hw_drop(snd_pcm_t *pcm) int err; if (ioctl(hw->fd, SNDRV_PCM_IOCTL_DROP) < 0) { err = -errno; - SYSERR("SNDRV_PCM_IOCTL_DROP failed"); + SYSMSG("SNDRV_PCM_IOCTL_DROP failed"); return err; } return 0; @@ -588,8 +573,7 @@ static int snd_pcm_hw_drain(snd_pcm_t *pcm) int err; if (ioctl(hw->fd, SNDRV_PCM_IOCTL_DRAIN) < 0) { err = -errno; - if (check_std_error(err)) - SYSERR("SNDRV_PCM_IOCTL_DRAIN failed"); + SYSMSG("SNDRV_PCM_IOCTL_DRAIN failed"); return err; } return 0; @@ -601,8 +585,7 @@ static int snd_pcm_hw_pause(snd_pcm_t *pcm, int enable) int err; if (ioctl(hw->fd, SNDRV_PCM_IOCTL_PAUSE, enable) < 0) { err = -errno; - if (check_std_error(err)) - SYSERR("SNDRV_PCM_IOCTL_PAUSE failed"); + SYSMSG("SNDRV_PCM_IOCTL_PAUSE failed"); return err; } return 0; @@ -614,8 +597,7 @@ static snd_pcm_sframes_t snd_pcm_hw_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t fra int err; if (ioctl(hw->fd, SNDRV_PCM_IOCTL_REWIND, &frames) < 0) { err = -errno; - if (check_std_error(err)) - SYSERR("SNDRV_PCM_IOCTL_REWIND failed"); + SYSMSG("SNDRV_PCM_IOCTL_REWIND failed"); return err; } return frames; @@ -628,8 +610,7 @@ static snd_pcm_sframes_t snd_pcm_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t fr if (SNDRV_PROTOCOL_VERSION(2, 0, 4) <= hw->version) { if (ioctl(hw->fd, SNDRV_PCM_IOCTL_FORWARD, &frames) < 0) { err = -errno; - if (check_std_error(err)) - SYSERR("SNDRV_PCM_IOCTL_FORWARD failed"); + SYSMSG("SNDRV_PCM_IOCTL_FORWARD failed"); return err; } return frames; @@ -669,8 +650,7 @@ static int snd_pcm_hw_resume(snd_pcm_t *pcm) int fd = hw->fd, err; if (ioctl(fd, SNDRV_PCM_IOCTL_RESUME) < 0) { err = -errno; - if (check_std_error(err)) - SYSERR("SNDRV_PCM_IOCTL_RESUME failed"); + SYSMSG("SNDRV_PCM_IOCTL_RESUME failed"); return err; } return 0; @@ -768,7 +748,7 @@ static int snd_pcm_hw_mmap_status(snd_pcm_t *pcm) err = ioctl(hw->fd, SNDRV_PCM_IOCTL_SYNC_PTR, &sync_ptr); if (err < 0) { err = -errno; - SYSERR("SNDRV_PCM_IOCTL_SYNC_PTR failed"); + SYSMSG("SNDRV_PCM_IOCTL_SYNC_PTR failed"); return err; } hw->sync_ptr = calloc(1, sizeof(struct sndrv_pcm_sync_ptr)); @@ -795,7 +775,7 @@ static int snd_pcm_hw_mmap_control(snd_pcm_t *pcm) hw->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL); if (ptr == MAP_FAILED || ptr == NULL) { err = -errno; - SYSERR("control mmap failed"); + SYSMSG("control mmap failed"); return err; } hw->mmap_control = ptr; @@ -818,7 +798,7 @@ static int snd_pcm_hw_munmap_status(snd_pcm_t *pcm) } else { if (munmap((void*)hw->mmap_status, page_align(sizeof(*hw->mmap_status))) < 0) { err = -errno; - SYSERR("status munmap failed"); + SYSMSG("status munmap failed"); return err; } } @@ -837,7 +817,7 @@ static int snd_pcm_hw_munmap_control(snd_pcm_t *pcm) } else { if (munmap(hw->mmap_control, page_align(sizeof(*hw->mmap_control))) < 0) { err = -errno; - SYSERR("control munmap failed"); + SYSMSG("control munmap failed"); return err; } } @@ -860,7 +840,7 @@ static int snd_pcm_hw_close(snd_pcm_t *pcm) int err; if (close(hw->fd)) { err = -errno; - SYSERR("close failed\n"); + SYSMSG("close failed\n"); return err; } snd_pcm_hw_munmap_status(pcm); @@ -888,7 +868,6 @@ static snd_pcm_sframes_t snd_pcm_hw_mmap_commit(snd_pcm_t *pcm, } while (size > 0); return result; } else { - snd_pcm_hw_t *hw = pcm->private_data; assert(hw->shadow_appl_ptr); } } @@ -917,7 +896,8 @@ static snd_pcm_sframes_t snd_pcm_hw_avail_update(snd_pcm_t *pcm) hw->avail_update_flag = 0; if (err < 0) return err; - assert((snd_pcm_uframes_t)err == avail); + if ((snd_pcm_uframes_t)err != avail) + SNDMSG("short read %ld for avail %ld", err, avail); return err; } } @@ -946,7 +926,10 @@ static void snd_pcm_hw_dump(snd_pcm_t *pcm, snd_output_t *out) snd_pcm_hw_t *hw = pcm->private_data; char *name; int err = snd_card_get_name(hw->card, &name); - assert(err >= 0); + if (err < 0) { + SNDERR("cannot get card name"); + return; + } snd_output_printf(out, "Hardware PCM card %d '%s' device %d subdevice %d\n", hw->card, name, hw->device, hw->subdevice); free(name); @@ -1021,7 +1004,7 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, memset(&info, 0, sizeof(info)); if (ioctl(fd, SNDRV_PCM_IOCTL_INFO, &info) < 0) { ret = -errno; - SYSERR("SNDRV_PCM_IOCTL_INFO failed"); + SYSMSG("SNDRV_PCM_IOCTL_INFO failed"); close(fd); return ret; @@ -1044,7 +1027,7 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, */ if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) { ret = -errno; - SYSERR("fcntl FD_CLOEXEC failed"); + SYSMSG("fcntl FD_CLOEXEC failed"); close(fd); return ret; } @@ -1052,7 +1035,7 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, if (ioctl(fd, SNDRV_PCM_IOCTL_PVERSION, &ver) < 0) { ret = -errno; - SYSERR("SNDRV_PCM_IOCTL_PVERSION failed"); + SYSMSG("SNDRV_PCM_IOCTL_PVERSION failed"); close(fd); return ret; } @@ -1063,7 +1046,7 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, int on = 1; if (ioctl(fd, SNDRV_PCM_IOCTL_TSTAMP, &on) < 0) { ret = -errno; - SNDERR("TSTAMP failed\n"); + SNDMSG("TSTAMP failed\n"); return ret; } } @@ -1152,7 +1135,8 @@ int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, filefmt = SNDRV_FILE_PCM_STREAM_CAPTURE; break; default: - assert(0); + SNDERR("invalid stream %d", stream); + return -EINVAL; } sprintf(filename, filefmt, card, device); @@ -1171,14 +1155,14 @@ int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, fmode |= O_ASYNC; if ((fd = open(filename, fmode)) < 0) { ret = -errno; - SYSERR("open %s failed", filename); + SYSMSG("open %s failed", filename); goto _err; } if (subdevice >= 0) { memset(&info, 0, sizeof(info)); if (ioctl(fd, SNDRV_PCM_IOCTL_INFO, &info) < 0) { ret = -errno; - SYSERR("SNDRV_PCM_IOCTL_INFO failed"); + SYSMSG("SNDRV_PCM_IOCTL_INFO failed"); goto _err; } if (info.subdevice != (unsigned int) subdevice) { diff --git a/src/pcm/pcm_mmap.c b/src/pcm/pcm_mmap.c index 6cf1ff1a..e67ade73 100644 --- a/src/pcm/pcm_mmap.c +++ b/src/pcm/pcm_mmap.c @@ -105,7 +105,10 @@ static snd_pcm_sframes_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm, { snd_pcm_uframes_t xfer = 0; - assert(snd_pcm_mmap_playback_avail(pcm) >= size); + if (snd_pcm_mmap_playback_avail(pcm) < size) { + SNDMSG("too short avail %ld to size %ld", snd_pcm_mmap_playback_avail(pcm), size); + return -EPIPE; + } while (size > 0) { const snd_pcm_channel_area_t *pcm_areas; snd_pcm_uframes_t pcm_offset; @@ -134,7 +137,10 @@ static snd_pcm_sframes_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, { snd_pcm_uframes_t xfer = 0; - assert(snd_pcm_mmap_capture_avail(pcm) >= size); + if (snd_pcm_mmap_capture_avail(pcm) < size) { + SNDMSG("too short avail %ld to size %ld", snd_pcm_mmap_capture_avail(pcm), size); + return -EPIPE; + } while (size > 0) { const snd_pcm_channel_area_t *pcm_areas; snd_pcm_uframes_t pcm_offset; @@ -275,8 +281,8 @@ int snd_pcm_channel_info_shm(snd_pcm_t *pcm, snd_pcm_channel_info_t *info, int s info->step = pcm->sample_bits; break; default: - assert(0); - break; + SNDMSG("invalid access type %d", pcm->access); + return -EINVAL; } info->addr = 0; info->type = SND_PCM_AREA_SHM; @@ -290,8 +296,14 @@ int snd_pcm_mmap(snd_pcm_t *pcm) int err; unsigned int c; assert(pcm); - assert(pcm->setup); - assert(!pcm->mmap_channels); + if (CHECK_SANITY(! pcm->setup)) { + SNDMSG("PCM not set up"); + return -EIO; + } + if (CHECK_SANITY(pcm->mmap_channels || pcm->running_areas)) { + SNDMSG("Already mmapped"); + return -EBUSY; + } err = pcm->ops->mmap(pcm); if (err < 0) return err; @@ -300,7 +312,6 @@ int snd_pcm_mmap(snd_pcm_t *pcm) pcm->mmap_channels = calloc(pcm->channels, sizeof(pcm->mmap_channels[0])); if (!pcm->mmap_channels) return -ENOMEM; - assert(!pcm->running_areas); pcm->running_areas = calloc(pcm->channels, sizeof(pcm->running_areas[0])); if (!pcm->running_areas) { free(pcm->mmap_channels); @@ -433,7 +444,10 @@ int snd_pcm_munmap(snd_pcm_t *pcm) int err; unsigned int c; assert(pcm); - assert(pcm->mmap_channels); + if (CHECK_SANITY(! pcm->mmap_channels)) { + SNDMSG("Not mmapped"); + return -ENXIO; + } if (pcm->mmap_shadow) return pcm->ops->munmap(pcm); for (c = 0; c < pcm->channels; ++c) { @@ -499,7 +513,8 @@ snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size) { snd_pcm_uframes_t xfer = 0; snd_pcm_sframes_t err = 0; - assert(size > 0); + if (! size) + return 0; while (xfer < size) { snd_pcm_uframes_t frames = size - xfer; snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm); @@ -532,9 +547,8 @@ snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size) break; } default: - assert(0); - err = -EINVAL; - break; + SNDMSG("invalid access type %d", pcm->access); + return -EINVAL; } if (err < 0) break; @@ -549,7 +563,8 @@ snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size) { snd_pcm_uframes_t xfer = 0; snd_pcm_sframes_t err = 0; - assert(size > 0); + if (! size) + return 0; while (xfer < size) { snd_pcm_uframes_t frames = size - xfer; snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm); @@ -581,9 +596,8 @@ snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size) frames = err; } default: - assert(0); - err = -EINVAL; - break; + SNDMSG("invalid access type %d", pcm->access); + return -EINVAL; } if (err < 0) break; diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c index f5972911..d8a5a028 100644 --- a/src/pcm/pcm_plugin.c +++ b/src/pcm/pcm_plugin.c @@ -373,7 +373,11 @@ static snd_pcm_sframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm, break; frames = plugin->write(pcm, areas, offset, frames, slave_areas, slave_offset, &slave_frames); - assert(slave_frames <= snd_pcm_mmap_playback_avail(slave)); + if (CHECK_SANITY(slave_frames > snd_pcm_mmap_playback_avail(slave))) { + SNDMSG("write overflow %ld > %ld", slave_frames, + snd_pcm_mmap_playback_avail(slave)); + return -EPIPE; + } snd_atomic_write_begin(&plugin->watom); snd_pcm_mmap_appl_forward(pcm, frames); result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames); @@ -415,7 +419,11 @@ static snd_pcm_sframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm, break; frames = plugin->read(pcm, areas, offset, frames, slave_areas, slave_offset, &slave_frames); - assert(slave_frames <= snd_pcm_mmap_capture_avail(slave)); + if (CHECK_SANITY(slave_frames > snd_pcm_mmap_capture_avail(slave))) { + SNDMSG("read overflow %ld > %ld", slave_frames, + snd_pcm_mmap_playback_avail(slave)); + return -EPIPE; + } snd_atomic_write_begin(&plugin->watom); snd_pcm_mmap_appl_forward(pcm, frames); result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames); @@ -531,7 +539,10 @@ snd_pcm_sframes_t snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm, slave_size -= frames; xfer += frames; } - assert(size == 0); + if (CHECK_SANITY(size)) { + SNDMSG("short commit: %ld", size); + return -EPIPE; + } return xfer; } diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c index 605cb49f..13c96310 100644 --- a/src/pcm/pcm_rate.c +++ b/src/pcm/pcm_rate.c @@ -166,7 +166,10 @@ static void snd_pcm_rate_expand(const snd_pcm_channel_area_t *dst_areas, src_frames1++; states->u.linear.init = 2; /* get a new sample */ //printf("new_src_pos = %i\n", (src - (char *)snd_pcm_channel_area_addr(src_area, src_offset)) / src_step); - assert(src_frames1 <= src_frames); + if (CHECK_SANITY(src_frames1 > src_frames)) { + SNDERR("src_frames overflow"); + break; + } } } if (dst_frames != dst_frames1) { @@ -243,7 +246,10 @@ static void snd_pcm_rate_shrink(const snd_pcm_channel_area_t *dst_areas, after_put: dst += dst_step; dst_frames1++; - assert(dst_frames1 <= dst_frames); + if (CHECK_SANITY(dst_frames1 > dst_frames)) { + SNDERR("dst_frames overflow"); + break; + } } old_sample = new_sample; } @@ -501,8 +507,10 @@ static int snd_pcm_rate_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) /* pitch is get_increment */ } rate->pitch = (((u_int64_t)dst_rate * LINEAR_DIV) + (src_rate / 2)) / src_rate; - assert(!rate->states); - assert(!rate->pareas); + if (CHECK_SANITY(rate->states || rate->pareas)) { + SNDMSG("rate plugin already in use"); + return -EBUSY; + } rate->states = malloc(channels * sizeof(*rate->states)); if (rate->states == NULL) return -ENOMEM; @@ -616,7 +624,11 @@ static int snd_pcm_rate_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params) } } } while (1); - assert((snd_pcm_uframes_t)snd_pcm_rate_client_frames(pcm, slave->period_size ) == pcm->period_size ); + if ((snd_pcm_uframes_t)snd_pcm_rate_client_frames(pcm, slave->period_size ) != pcm->period_size) { + SNDERR("invalid slave period_size %ld for pcm period_size %ld", + slave->period_size, pcm->period_size); + return -EIO; + } } else { rate->pitch = (((u_int64_t)pcm->period_size * LINEAR_DIV) + (slave->period_size/2) ) / slave->period_size; do { @@ -639,7 +651,11 @@ static int snd_pcm_rate_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params) } } } while (1); - assert((snd_pcm_uframes_t)snd_pcm_rate_slave_frames(pcm, pcm->period_size ) == slave->period_size ); + if ((snd_pcm_uframes_t)snd_pcm_rate_slave_frames(pcm, pcm->period_size ) != slave->period_size) { + SNDERR("invalid pcm period_size %ld for slave period_size", + pcm->period_size, slave->period_size); + return -EIO; + } } recalc(pcm, &sparams->avail_min); rate->orig_avail_min = sparams->avail_min; @@ -1044,7 +1060,10 @@ static int snd_pcm_rate_commit_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t app result = snd_pcm_mmap_begin(rate->slave, &slave_areas, &slave_offset, &slave_frames); if (result < 0) return result; - assert(slave_offset == 0); + if (slave_offset) { + SNDERR("non-zero slave_offset %ld", slave_offset); + return -EIO; + } snd_pcm_areas_copy(slave_areas, slave_offset, rate->sareas, xfer, pcm->channels, cont, @@ -1124,7 +1143,10 @@ static int snd_pcm_rate_grab_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t hw_of result = snd_pcm_mmap_begin(rate->slave, &slave_areas, &slave_offset, &slave_frames); if (result < 0) return result; - assert(slave_offset == 0); + if (slave_offset) { + SNDERR("non-zero slave_offset %ld", slave_offset); + return -EIO; + } snd_pcm_areas_copy(rate->sareas, xfer, slave_areas, slave_offset, pcm->channels, cont, diff --git a/src/pcm/pcm_share.c b/src/pcm/pcm_share.c index 46fe4262..7e363049 100644 --- a/src/pcm/pcm_share.c +++ b/src/pcm/pcm_share.c @@ -238,8 +238,13 @@ static snd_pcm_uframes_t _snd_pcm_share_missing(snd_pcm_t *pcm) missing = 1; } err = snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), frames); - assert(err == frames); - slave_avail -= frames; + if (err < 0) { + SYSMSG("snd_pcm_mmap_commit error"); + return INT_MAX; + } + if (err != frames) + SYSMSG("commit returns %ld for size %ld", err, frames); + slave_avail -= err; } else { if (safety_missing == 0) missing = 1; @@ -278,8 +283,8 @@ static snd_pcm_uframes_t _snd_pcm_share_missing(snd_pcm_t *pcm) running = 1; break; default: - assert(0); - break; + SNDERR("invalid shared PCM state %d", share->state); + return INT_MAX; } update_poll: @@ -357,10 +362,16 @@ static void *snd_pcm_share_thread(void *data) pfd[0].fd = slave->poll[0]; pfd[0].events = POLLIN; err = snd_pcm_poll_descriptors(spcm, &pfd[1], 1); - assert(err == 1); + if (err != 1) { + SNDERR("invalid poll descriptors %d", err); + return NULL; + } Pthread_mutex_lock(&slave->mutex); err = pipe(slave->poll); - assert(err >= 0); + if (err < 0) { + SYSERR("can't create a pipe"); + return NULL; + } while (slave->open_count > 0) { snd_pcm_uframes_t missing; // printf("begin min_missing\n"); @@ -383,7 +394,10 @@ static void *snd_pcm_share_thread(void *data) if ((snd_pcm_uframes_t)avail_min != spcm->avail_min) { snd_pcm_sw_params_set_avail_min(spcm, &slave->sw_params, avail_min); err = snd_pcm_sw_params(spcm, &slave->sw_params); - assert(err >= 0); + if (err < 0) { + SYSERR("snd_pcm_sw_params error"); + return NULL; + } } slave->polling = 1; Pthread_mutex_unlock(&slave->mutex); @@ -433,7 +447,10 @@ static void _snd_pcm_share_update(snd_pcm_t *pcm) int err; snd_pcm_sw_params_set_avail_min(spcm, &slave->sw_params, avail_min); err = snd_pcm_sw_params(spcm, &slave->sw_params); - assert(err >= 0); + if (err < 0) { + SYSERR("snd_pcm_sw_params error"); + return; + } } } } @@ -818,7 +835,14 @@ static snd_pcm_sframes_t _snd_pcm_share_mmap_commit(snd_pcm_t *pcm, if (frames > 0) { snd_pcm_sframes_t err; err = snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), frames); - assert(err == frames); + if (err < 0) { + SYSMSG("snd_pcm_mmap_commit error"); + return err; + } + if (err != frames) { + SYSMSG("commit returns %ld for size %ld", err, frames); + return err; + } } _snd_pcm_share_update(pcm); }