charlie-foxtrot / RTLSDR-Airband

Multichannel AM/NFM demodulator
GNU General Public License v3.0
754 stars 134 forks source link

[BUG] Segmentation fault on Alpine Linux #446

Open MarhyCZ opened 8 months ago

MarhyCZ commented 8 months ago

Hi, I tried to dockerize RTLSDR-Airband with alpine linux as a base image. It worked great using just librtlsdr driver. But when I also built it with SoapySDR support and then tried to use it, it segfaults just before starting the device.

The device works when I try to probe it inside alpine container and test rate using SoapySDRUtil. But RTLSDR-Airband segfaults. Can it be that Alpine uses smaller stack memory?

This works:

docker run --device="/dev/bus/usb:/dev/bus/usb" -it container_name sh
SoapySDRUtil --args=driver=airspy --rate=3000000 --direction=RX

But when starting RTLSDR-Airband -> Last 2 lines from debug:

SoapySDR: device 'driver=airspy,device_id=0': AGC on (requested: on)
SoapySDR: device 'driver=airspy,device_id=0' initialized 
Segmentation fault

First I tried to use multi-stage build to make more optimized images, but in order to minimize errors, I also built it in one go. Still same error. When I used much bigger debian as a base, it worked right away. The alpine is nice that it gives 18-20MB image size.

Alpine Linux Dockerfile (using just one stage)

# rtlsdr-airband/Dockerfile
FROM alpine:latest AS build

WORKDIR /app

# Install dependencies
RUN apk add --no-cache \
  build-base \
  cmake \
  libusb-dev \
  alsa-lib-dev \
  librtlsdr-dev \
  lame-dev \
  libshout-dev \
  libconfig-dev \
  fftw-dev \
  # SoapySDR dependencies
  git

# SoapySDR support
WORKDIR /app/
RUN git clone https://github.com/pothosware/SoapySDR.git
WORKDIR /app/SoapySDR
RUN mkdir build && cd build && cmake .. && make -j`nproc` && make install -j`nproc`

# Airspy Mini Driver
WORKDIR /app/
RUN git clone https://github.com/airspy/airspyone_host.git
WORKDIR /app/airspyone_host
RUN mkdir build && cd build && cmake ../ -DINSTALL_UDEV_RULES=ON && make -j`nproc` && make install -j`nproc`

# SoapySDR Airspy Support
WORKDIR /app/
RUN git clone https://github.com/pothosware/SoapyAirspy.git
WORKDIR /app/SoapyAirspy
RUN mkdir build && cd build && cmake .. && make -j`nproc` && make install -j`nproc`

# RTLSDR-Airband
WORKDIR /app
# Conf files for RTLSDR-Airband
COPY . ./

RUN wget -O RTLSDR-Airband.tar.gz https://github.com/charlie-foxtrot//RTLSDR-Airband/archive/v4.2.0.tar.gz
RUN tar xvfz RTLSDR-Airband.tar.gz
WORKDIR /app/RTLSDR-Airband-4.2.0
RUN mkdir build
# NFM flag enables 16kHz sampling rate
RUN cmake -DNFM=ON
# Build RTLSDR-Airband
RUN make
RUN make install

WORKDIR /app
ENTRYPOINT ["sh", "entrypoint.sh"]
# -e outputs logs to stdout, -f runs in foreground, -c config file
# https://github.com/charlie-foxtrot/RTLSDR-Airband/wiki/Running-the-program
CMD ["rtl_airband", "-e" , "-f", "-c", "rtl_airband.conf"]

Working debian base:

# rtlsdr-airband/Dockerfile
FROM debian:bookworm-slim AS build

WORKDIR /app

# Install dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
  build-essential \
  cmake \
  libusb-1.0-0-dev \
  libpulse-dev \
  librtlsdr-dev \
  libmp3lame-dev \
  libshout3-dev \
  libconfig++-dev \
  libfftw3-dev \
  # SoapySDR dependencies
  git \
  ca-certificates \
  wget \
  && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# SoapySDR support
WORKDIR /app/
RUN git clone https://github.com/pothosware/SoapySDR.git
WORKDIR /app/SoapySDR
RUN mkdir build && cd build && cmake .. && make -j`nproc` && make install -j`nproc`
RUN ldconfig

# Airspy Mini Driver
WORKDIR /app/
RUN git clone https://github.com/airspy/airspyone_host.git
WORKDIR /app/airspyone_host
RUN mkdir build && cd build && cmake ../ -DINSTALL_UDEV_RULES=ON && make -j`nproc` && make install -j`nproc`
RUN ldconfig

# SoapySDR Airspy Support
WORKDIR /app/
RUN git clone https://github.com/pothosware/SoapyAirspy.git
WORKDIR /app/SoapyAirspy
RUN mkdir build && cd build && cmake .. && make -j`nproc` && make install -j`nproc`
RUN ldconfig

# RTLSDR-Airband
WORKDIR /app
# Conf files for RTLSDR-Airband
COPY . ./

RUN wget -O RTLSDR-Airband.tar.gz https://github.com/szpajder/RTLSDR-Airband/archive/v4.2.0.tar.gz
RUN tar xvfz RTLSDR-Airband.tar.gz
WORKDIR /app/RTLSDR-Airband-4.2.0
RUN mkdir build
# NFM flag enables 16kHz sampling rate
RUN cmake -DNFM=ON
# Build RTLSDR-Airband
RUN make
RUN make install

WORKDIR /app
ENTRYPOINT ["sh", "entrypoint.sh"]
# -e outputs logs to stdout, -f runs in foreground, -c config file
# https://github.com/charlie-foxtrot/RTLSDR-Airband/wiki/Running-the-program
CMD ["rtl_airband", "-e" , "-f", "-c", "rtl_airband.conf"]

rtl_airband.conf

fft_size = 512;
devices: (
  {
    type = "soapysdr";
    device_string = "driver=airspy,device_id=0";
    mode = "scan";
    channels:
    (
      {
        freqs = ( #FREQUENCY ); - I load ENV variables into this string
        outputs: (
          {
            type = "udp_stream";
            dest_address = "127.0.0.1";
            dest_port = 8001;
            continuous = false;
          }
        );
      }
    )
  }
);
MarhyCZ commented 8 months ago

So I also tried to cmake RTLSDR-Airband with Debug flag -DCMAKE_BUILD_TYPE=Debug and run it with gdb.

SoapySDR: device 'driver=airspy,device_id=0' initialized
[New LWP 57]
[New LWP 58]
[LWP 58 exited]

Thread 6 "rtl_airband" received signal SIGSEGV, Segmentation fault.
[Switching to LWP 57]
0x0000007ff7e0c744 in SoapySDRDevice_setupStream () from /usr/local/lib/libSoapySDR.so.0.8-3

backtrace shows:

#0  0x0000007ff7e0c744 in SoapySDRDevice_setupStream () from /usr/local/lib/libSoapySDR.so.0.8-3
#1  0x000000555556b46c in soapysdr_rx_thread (ctx=0x7ff7f3ce70) at /app/RTLSDR-Airband-4.2.0/src/input-soapysdr.cpp:315
#2  0x0000007ff7f9f118 in start (p=0x7ff6aa96a0) at src/thread/pthread_create.c:207
#3  0x0000007ff7f9d4c8 in __clone () at src/thread/aarch64/clone.s:28
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
MarhyCZ commented 8 months ago

I also tried to build the SoapySDR libs with debug and run the Airband again:

(gdb) bt
#0  0x0000007ff7de3e9c in SoapySDRDevice_setupStream (device=<error reading variable: Cannot access memory at address 0x7ff6a1b368>, 
    direction=<error reading variable: Cannot access memory at address 0x7ff6a1b364>, 
    format=<error reading variable: Cannot access memory at address 0x7ff6a1b358>, 
    channels=<error reading variable: Cannot access memory at address 0x7ff6a1b350>, 
    numChans=<error reading variable: Cannot access memory at address 0x7ff6a1b348>, 
    args=<error reading variable: Cannot access memory at address 0x7ff6a1b340>) at /app/SoapySDR/lib/DeviceC.cpp:161
#1  0x000000555556b46c in soapysdr_rx_thread (ctx=0x7ff7f3ce70) at /app/RTLSDR-Airband-4.2.0/src/input-soapysdr.cpp:315
#2  0x0000007ff7f9f118 in start (p=0x7ff6a696b8) at src/thread/pthread_create.c:207
#3  0x0000007ff7f9d4c8 in __clone () at src/thread/aarch64/clone.s:28
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
charlie-foxtrot commented 8 months ago

I started something similar in #444 with debian:bookworm-slim and ran into issues with compile flags and different CPU support on the build vs run machine.

Are you building the docker container and running it on the same machine? What is the underlying hardware? One thing you can try is adding -DPLATFORM=native to the cmake command for rtl_airband, that will pass the -march=native flag to the compiler.

It's interesting that using debian:bookworm-slim is working for you but alpine:latest is not. It looks like alpine has a pre-built soapy-sdr package, it may be worth trying that one rather than building your own.

MarhyCZ commented 8 months ago

Thanks for a really quick reply! I will let you know after I try all of it.

Its true, that I am using github actions and compiling it for aarch64 (64 bit ARM for Raspberry PI..). But it is not cross compiling. The Actions create QEMU virtual machine with the same architecture.

But I will also try it in a Linux VM on x86.

I have already tried the prebuilt packages, that was my first try in "fixing it", but no fun.

Anyways its not dealbreaking when it works without issues on Debian base, but I will try to narrow the problem!