analogdevicesinc/libiio

iio_buffer_destroy segfault via usb

raccoman opened this issue · 13 comments

I'm having trouble closing and reopening a stream. During the execution of my application there is a possibility to change the n_blocks and block_size parameters. (the input parameters at the time of creating the stream).

Here is how I create the stream:

int sdr_create_stream(t_sdr *sdr) {
    sdr->rx_buf = iio_device_create_buffer(sdr->rx_stream_dev, 0, sdr->rx_mask);
    if (iio_err(sdr->rx_buf)) {
        logger_error("sdr", "sdr_create_stream() failed: iio_device_create_buffer() failed");
        return -1;
    }

    sdr->rx_stream = iio_buffer_create_stream(sdr->rx_buf, sdr->params.n_blocks, sdr->params.block_size);
    if (iio_err(sdr->rx_stream)) {
        logger_error("sdr", "sdr_create_stream() failed: iio_buffer_create_stream() failed");
        return -1;
    }

    if (pthread_create(&sdr->thread_rx, NULL, sdr_thread_rx, sdr) != 0) {
        logger_error("sdr", "sdr_init() failed: pthread_mutex_init() failed");
        return -1;
    }

    logger_debug("sdr", "sdr_create_stream() success");
    return 0;
}

Here is how I destroy it, before recreating it passing new parameters:

void sdr_destroy_stream(t_sdr *sdr) {

    pthread_cancel(sdr->thread_rx);
    pthread_join(sdr->thread_rx, NULL);

    iio_stream_destroy(sdr->rx_stream);

    iio_buffer_disable(sdr->rx_buf);
    iio_buffer_destroy(sdr->rx_buf);

    sdr_empty_data(sdr);
    logger_debug("sdr", "sdr_destroy_stream() success");
}

This should work fine, but quite always it segfault or freeze while calling iio_buffer_destroy

Can you upload your iio-config.h located in the build folder?

There you go, I hope I didn't miss anything, I took out practically all the options to lighten the library. I just need the communication via USB

#ifndef IIO_CONFIG_H
#define IIO_CONFIG_H

#define LIBIIO_VERSION_MAJOR	1
#define LIBIIO_VERSION_MINOR	0
#define LIBIIO_VERSION_GIT	"v1.0"

#define LOG_LEVEL Info_L
#define DEFAULT_LOG_LEVEL 4

#define IIO_MODULES_DIR ""
#define IIO_LIBRARY_SUFFIX ".so"

#define IF_ENABLED(cfg, ptr) ((cfg) ? (ptr) : NULL)

#define LIBIIO_SCAN_BACKENDS	"usb"

#define WITH_LOCAL_BACKEND 0
#define WITH_XML_BACKEND 1
#define WITH_NETWORK_BACKEND 0
#define WITH_USB_BACKEND 1
#define WITH_SERIAL_BACKEND 0

#define WITH_MODULES 0
#define WITH_NETWORK_BACKEND_DYNAMIC 0
#define WITH_SERIAL_BACKEND_DYNAMIC 0
#define WITH_USB_BACKEND_DYNAMIC 0

#define WITH_NETWORK_EVENTFD 0
#define WITH_IIOD_USBD 0
#define WITH_IIOD_SERIAL 0
#define WITH_LOCAL_CONFIG 0
#define WITH_LOCAL_DMABUF_API 0
#define WITH_LOCAL_MMAP_API 0
#define WITH_HWMON 0
#define WITH_AIO 0
#define HAVE_DNS_SD 0
#define HAVE_AVAHI 0
#define WITH_ZSTD 1

/* #undef HAS_PIPE2 */
#define HAS_STRDUP
#define HAS_STRNDUP
#define HAS_STRTOK_R
#define HAS_STRERROR_R
#define HAS_NEWLOCALE
/* #undef HAS_PTHREAD_SETNAME_NP */
/* #undef HAVE_IPV6 */
/* #undef NO_THREADS */

#define IF_ENABLED(cfg, ptr) ((cfg) ? (ptr) : NULL)

#endif /* IIO_CONFIG_H */

It looks like you are using an older version of the library, there are some macros missing here. Can you re-try with the latest "main"?

#ifndef IIO_CONFIG_H
#define IIO_CONFIG_H

#define LIBIIO_VERSION_MAJOR	1
#define LIBIIO_VERSION_MINOR	0
#define LIBIIO_VERSION_GIT	"v1.0"

#define LOG_LEVEL Info_L
#define DEFAULT_LOG_LEVEL 4
#define MAX_LOG_LEVEL 5

#define IIO_MODULES_DIR ""
#define IIO_LIBRARY_SUFFIX ".so"

#define IF_ENABLED(cfg, ptr) ((cfg) ? (ptr) : NULL)

#define LIBIIO_SCAN_BACKENDS	"usb"

#define WITH_LOCAL_BACKEND 0
#define WITH_XML_BACKEND 1
#define WITH_NETWORK_BACKEND 0
#define WITH_USB_BACKEND 1
#define WITH_SERIAL_BACKEND 0

#define WITH_MODULES 0
#define WITH_NETWORK_BACKEND_DYNAMIC 0
#define WITH_SERIAL_BACKEND_DYNAMIC 0
#define WITH_USB_BACKEND_DYNAMIC 0

#define WITH_NETWORK_EVENTFD 0
#define WITH_IIOD_NETWORK 0
#define WITH_IIOD_USBD 0
#define WITH_IIOD_SERIAL 0
#define WITH_IIOD_V0_COMPAT 0
#define WITH_LOCAL_CONFIG 0
#define WITH_LOCAL_DMABUF_API 0
#define WITH_LOCAL_MMAP_API 0
#define WITH_HWMON 0
#define WITH_AIO 0
#define HAVE_DNS_SD 0
#define HAVE_AVAHI 0
#define WITH_ZSTD 1

/* #undef HAS_PIPE2 */
#define HAS_STRDUP
#define HAS_STRNDUP
#define HAS_STRTOK_R
#define HAS_STRERROR_R
#define HAS_NEWLOCALE
/* #undef HAS_PTHREAD_SETNAME_NP */
/* #undef HAVE_IPV6 */
/* #undef NO_THREADS */

#define IF_ENABLED(cfg, ptr) ((cfg) ? (ptr) : NULL)

#endif /* IIO_CONFIG_H */

Now I'm using the latest one, but still segfault

I am trying to reproduce your segfault, running iio_rwdev, but it just works here.

I am trying to reproduce your segfault, running iio_rwdev, but it just works here.

What's iio_rwdev?

utils/iio_rwdev.c, it's part of the Libiio utilities.

@raccoman Can you maybe run it under GDB, and get a backtrace after it segfaults?

@raccoman Can you maybe run it under GDB, and get a backtrace after it segfaults?

Sure, I'll try on Monday

Any progress?

Can you try my pcercuei/try-to-fix-usb branch, see if it makes any difference?

Any progress?

Can you try my pcercuei/try-to-fix-usb branch, see if it makes any difference?

Thanks, I'll try as soon as I can. I was busy this week

@pcercuei Hi pcercuei/try-to-fix-usb seems to work properly, what's changed?

@pcercuei Nevermind, it seems to segfault less frequently, but still freeze on buffer clear