python-sounddevice
python-sounddevice copied to clipboard
Segmentation fault (core dumped) on Alpine Linux
I can't make that running with Alpine Linux.
Here is the dockerfile to reproduce it:
FROM alpine:3.6
# Setup base
RUN apk add --no-cache jq bash portaudio \
python3 python3-dev \
gcc libgcc \
musl-dev musl \
libffi-dev libffi \
&& pip3 install --no-cache --upgrade setuptools \
&& pip3 install --no-cache --upgrade sounddevice
CMD ["python3", "-m", "sounddevice"]
What's "that"?
That is a docker that make a development environment that can run python3 -m sounddevice
.
I was not able to locate it but I think it can help to have a docker env for run the debuger. It should be easy as to setup a device with alpine linux to debug it.
@pvizeli
It would be helpful if you could at least provide a log of what errors you're getting and possibly a hosted docker file for us to test with. Help us help you...
@pvizeli Any more information? Any news?
I'm closing this due to lack of response. Feel free to re-open with more information.
This sadly is still an issue.
To reproduce using docker here's everything you need:
# $ cat Dockerfile
FROM alpine:3.11
RUN apk add --no-cache \
python3 \
python3-dev \
gcc \
musl-dev \
libffi-dev \
portaudio-dev
RUN python3 -m pip install sounddevice
Next build the image:
docker build -t sounddevice .
Finally execute it:
docker run -it sounddevice /bin/sh
This will give you a shell in which you run:
python3 -c 'import sounddevice'
If you need anything else, please let me know
Thanks for the update.
If you need anything else, please let me know
It would probably be helpful to know where exactly the segmentation fault happens (that information should be in the core file).
It might be interesting to know whether other versions of PortAudio work.
It might be interesting to know whether other modules using PortAudio (e.g. PyAudio) work.
It might also be interesting to know whether other modules using CFFI (e.g. soundfile
) work.
If the segfault happens during import sounddevice
, the problem is most likely in the function _initialize()
.
You could randomly un-comment a few lines to further isolate the cause of the error.
The line with Pa_Initialize
and the line with fopen
(plus the following line) would be good candidates.
Edit: This was not meant to sound rude but kinda does. Sorry
Sorry but I don't really have time to fully debug the issue (I'd have done so if I had)
I however managed to get a core dump which I've attached.
Here are the steps necessary to produce one yourself if necessary... First create the image as outline before, then:
$ docker run --device=/dev/snd:/dev/snd -v '/tmp/sounddevice:/data' --privileged -it sounddevice /bin/sh
$ echo '/data/core' > /proc/sys/kernel/core_pattern
$ python3 -c 'import sounddevice'
After that a core dump is located in the hosts /tmp/sounddevice
directory
Commenting stuff within _initialize
I found that setattr(stdio, stderr_name, devnull)
is causing the first segfault.
Another one follows soon after though.
The attached core-dump is without any modifications
Edit: This was not meant to sound rude but kinda does. Sorry
Don't worry, I didn't perceive any of this as rude.
Sorry but I don't really have time to fully debug the issue (I'd have done so if I had)
No problem. It's totally OK to report an issue and not having the time to fix it.
As long as you don't expect me to have the time to do it.
I however managed to get a core dump which I've attached.
Thanks, but I think I can only get meaningful information out if I have the corresponding executable. Anyway, I don't really know how to diagnose these kinds of problems ...
Commenting stuff within
_initialize
I found thatsetattr(stdio, stderr_name, devnull)
is causing the first segfault. Another one follows soon after though.
OK, cool, that's probably helpful.
We could create a minimal example that only contains the necessary code to generate the segfault.
This would not need the full sounddevice
module and not even the PortAudio library.
We could then ask the CFFI people what could be the problem, they are normally very helpful and I'm sure they know how to diagnose such a thing.
Hello I'm facing the similar issue on alpine linux i try to build docker image for the LedFx project when i try to import sounddevice module i get this error
bash-5.1$ python
Python 3.9.6 (default, Jun 29 2021, 19:45:46)
[GCC 10.2.1 20201203] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sounddevice
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/LedFx/venv/lib/python3.9/site-packages/sounddevice.py", line 71, in <module>
raise OSError('PortAudio library not found')
OSError: PortAudio library not found
>>>
i have alse and portaudio lib installed
bash-5.1$ ldd /usr/lib/libportaudi*
/lib/ld-musl-x86_64.so.1 (0x7f1f3c5ea000)
libasound.so.2 => /usr/lib/libasound.so.2 (0x7f1f3c4f8000)
libjack.so.0 => /usr/lib/libjack.so.0 (0x7f1f3c4bc000)
libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f1f3c5ea000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7f1f3c31a000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7f1f3c300000)
bash-5.1# find . -name libportaudi*
./usr/lib/libportaudio.so.2
./usr/lib/libportaudio.so.2.0.0
./usr/lib/libportaudiocpp.so
./usr/lib/libportaudiocpp.so.0
./usr/lib/libportaudio.so
./usr/lib/libportaudiocpp.so.0.0.12
bash-5.1# ls -l /usr/lib/libportaudio*
lrwxrwxrwx 1 root root 21 Aug 11 07:26 /usr/lib/libportaudio.so -> libportaudio.so.2.0.0
lrwxrwxrwx 1 root root 21 Aug 11 07:26 /usr/lib/libportaudio.so.2 -> libportaudio.so.2.0.0
-rwxr-xr-x 1 root root 171176 Sep 18 2019 /usr/lib/libportaudio.so.2.0.0
lrwxrwxrwx 1 root root 25 Aug 11 07:26 /usr/lib/libportaudiocpp.so -> libportaudiocpp.so.0.0.12
lrwxrwxrwx 1 root root 25 Aug 11 07:26 /usr/lib/libportaudiocpp.so.0 -> libportaudiocpp.so.0.0.12
-rwxr-xr-x 1 root root 55184 Sep 18 2019 /usr/lib/libportaudiocpp.so.0.0.12
@spiro-c This is a different issue (no segmentation fault).
It looks like ctypes.util.find_library('portaudio')
doesn't find the library.
right, you need a patched python executable for alpine that includes some patches from the alpine repository. The vanilla python will not work. You can use our https://github.com/home-assistant/docker-base
Sorry for pinging to old issue. I have the similar segmentation fault on alpine, so I'm interested in this.
While googling about 'alpine segmentation fault', I found many issues on other repositories. And it seems like some of them was because of musl that is used as standard c library on alpine. (e.g. https://github.com/lovell/sharp/issues/2570)
So I run alpine image with build-base
package installed:
$ sudo docker pull alpine
$ sudo docker run -ti alpine /bin/sh
# # inside alpine
$ apk add build-base
$ find / -name 'stdio.h'
/usr/include/stdio.h
/usr/include/fortify/stdio.h
/usr/include/c++/11.2.1/tr1/stdio.h
Read /usr/include/stdio.h
, and I found that stderr
is defined as FILE *const stderr
(on git.musl-libc.org):
...
extern FILE *const stderr;
...
#define stderr (stderr)
...
whereas in GNU C library on my archlinux it is defined as FILE *stderr
(on sourceware.org):
...
extern FILE *stderr; /* Standard error output stream. */
...
#define stderr stderr
And sounddevice_build.py
of this library have comment about GNU C library
definition, but not about musl
.
https://github.com/spatialaudio/python-sounddevice/blob/80d8930ea3cca16537df99ba57ad3692ebd90356/sounddevice_build.py#L314-L320
I'm totally newbie to C and doesn't know how things are working around there, but I thought those differences might be the problem. Sorry if it's already considered. Hope it helps. Thanks
As a quick workaround, It seems like removing forwarding stderr codes makes it work. It's not tested and all logs will be displayed to normal stderr(e.g. terminal), but here's my workaround code.
https://github.com/Cj-bc/python-sounddevice/tree/workaround/i90/remove-stderr-fowarding
I wrote some code and (almost) confirmed that changing stderr causes segmentation fault.
Full code and documentation are at Cj-bc/alpine-stderr-changing-test. I wrote C version, and it worked. So it's possible to change stderr to /dev/null
in C, but I couldn't find any way to do it in python.
would you mind to review this, @mgeier? Note that this isn't problem for me now, so I don't need fast reaction. If there's something unclear, let me know.
Thanks.
Docker environment that I tested
FROM python:3.9-alpine
WORKDIR workdir
RUN pip install cffi
COPY _ffi_test.py requirements.txt ./
RUN pip install -r requirements.txt && python _ffi_test.py
COPY stderr-changing.py ./
CMD python stderr-changing.py
Minimum code to reproduce segmentation fault
Minimum ffi definition is:
from cffi import FFI
ffibuilder = FFI()
ffibuilder.set_source("_ffi_test", None)
ffibuilder.cdef("""
FILE* fopen(const char* path, const char* mode);
extern FILE* stderr;
""")
if __name__ == '__main__':
ffibuilder.compile(verbose=True)
executable is:
from _ffi_test import ffi as _ffi
import os as _os
stdio = _ffi.dlopen(None)
getattr(stdio, 'stderr')
devnull = stdio.fopen(_os.devnull.encode(), b'w')
setattr(stdio, 'stderr', devnull)
What is problem?
My opinion is same as my previous comment, I think difference between GNU C library and musl is the problem.
I tried to use musl's stderr
definition in ffi, but it gives me error in some way.(Details are in README of my test code repo)
As far as I tried, I think it's impossible to change stderr to /dev/null in python.
Thanks @Cj-bc for the detailed informations, that's very interesting!
I found this link, suggesting to use freopen()
:
https://wiki.gentoo.org/wiki/Musl_porting_notes#error:assignment_of_read-only_variable.27.5Bstdout.7Cstdin.7Cstderr.5D.27
I think this might work for redirecting, but I didn't find a way to restore the original stderr
after the redirection.
Then I found https://stackoverflow.com/questions/7664788/freopen-stdout-and-console and https://stackoverflow.com/questions/1908687/how-to-redirect-the-output-back-to-the-screen-after-freopenout-txt-a-stdo, where some of the answers suggest using dup2()
.
I created #444 for trying this, but I have the feeling that this might not work on Alpine either ...
I've tried #444 with Docker, and it seems to work, it doesn't segfault!
Can somebody please confirm?
I haven't tried if it still works on Windows.