【问题标题】:Discord.py segmentation fault inside Docker using Apple Silicon M1使用 Apple Silicon M1 在 Docker 中出现 Discord.py 分段错误
【发布时间】:2021-10-06 04:14:56
【问题描述】:

我正在尝试为我的 discord.py 机器人设置 Docker 环境。我设法创建了一个Dockerfile,它使用python:3.9-slim-buster 作为基础镜像。当我在我的 Ubuntu 机器上的 Docker 容器中运行机器人时,一切都运行良好。但是,如果我使用带有 Apple Silicon M1 芯片的 MacBook,它的行为会有所不同。在运行bot.py 脚本并使其加入语音通道后,它在message.author.voice.channel.connect() 上崩溃并出现分段错误。

from discord.ext import commands

bot = commands.Bot('!')

@bot.event
async def on_message(message):
    await message.author.voice.channel.connect()

bot.run(DISCORD_TOKEN)

结果是机器人加入了我的语音频道,然后立即崩溃。 这是我得到的输出:

Fatal Python error: Segmentation fault

Thread 0x0000ffffa6c071e0 (most recent call first):
  File "/usr/local/lib/python3.9/threading.py", line 316 in wait
  File "/usr/local/lib/python3.9/threading.py", line 574 in wait
  File "/usr/local/lib/python3.9/site-packages/discord/gateway.py", line 133 in run
  File "/usr/local/lib/python3.9/threading.py", line 973 in _bootstrap_inner
  File "/usr/local/lib/python3.9/threading.py", line 930 in _bootstrap

Thread 0x0000ffffa74a71e0 (most recent call first):
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 75 in _worker
  File "/usr/local/lib/python3.9/threading.py", line 910 in run
  File "/usr/local/lib/python3.9/threading.py", line 973 in _bootstrap_inner
  File "/usr/local/lib/python3.9/threading.py", line 930 in _bootstrap

Current thread 0x0000ffffa8e22010 (most recent call first):
  File "/usr/local/lib/python3.9/ssl.py", line 897 in write
  File "/usr/local/lib/python3.9/asyncio/sslproto.py", line 261 in feed_appdata
  File "/usr/local/lib/python3.9/asyncio/sslproto.py", line 674 in _process_write_backlog
  File "/usr/local/lib/python3.9/asyncio/sslproto.py", line 598 in _write_appdata
  File "/usr/local/lib/python3.9/asyncio/sslproto.py", line 386 in write
  File "/usr/local/lib/python3.9/site-packages/aiohttp/http_writer.py", line 68 in _write
  File "/usr/local/lib/python3.9/site-packages/aiohttp/http_writer.py", line 119 in write_headers
  File "/usr/local/lib/python3.9/site-packages/aiohttp/client_reqrep.py", line 668 in send
  File "/usr/local/lib/python3.9/site-packages/aiohttp/client.py", line 542 in _request
  File "/usr/local/lib/python3.9/site-packages/aiohttp/client.py", line 754 in _ws_connect
  File "/usr/local/lib/python3.9/site-packages/discord/http.py", line 132 in ws_connect
  File "/usr/local/lib/python3.9/site-packages/discord/gateway.py", line 765 in from_client
  File "/usr/local/lib/python3.9/site-packages/discord/voice_client.py", line 321 in connect_websocket
  File "/usr/local/lib/python3.9/site-packages/discord/voice_client.py", line 353 in connect
  File "/usr/local/lib/python3.9/site-packages/discord/abc.py", line 1285 in connect
  File "/workspace/bot.py", line 7 in on_message
  File "/usr/local/lib/python3.9/site-packages/discord/client.py", line 343 in _run_event
  File "/usr/local/lib/python3.9/asyncio/events.py", line 80 in _run
  File "/usr/local/lib/python3.9/asyncio/base_events.py", line 1890 in _run_once
  File "/usr/local/lib/python3.9/asyncio/base_events.py", line 596 in run_forever
  File "/usr/local/lib/python3.9/site-packages/discord/client.py", line 713 in run
  File "/workspace/bot.py", line 9 in <module>
Segmentation fault

Docker 容器不应该在不同的机器上表现相同吗?你认为这是一个 Docker 错误还是有什么方法可以解决这个问题?

编辑: 已添加Dockerfile

FROM python:3.9-slim-buster

ENV PYTHONFAULTHANDLER=1 \
  PYTHONUNBUFFERED=1 \
  PYTHONHASHSEED=random \
  PIP_NO_CACHE_DIR=off \
  PIP_DISABLE_PIP_VERSION_CHECK=on \
  PIP_DEFAULT_TIMEOUT=100

RUN apt-get update && apt-get install -y \
    build-essential libpq-dev git \
    ca-certificates ffmpeg libopus-dev libsodium-dev ansible gcc git libffi-dev libsodium-dev make musl-dev
RUN pip install poetry

WORKDIR /app
COPY poetry.lock pyproject.toml /app/

RUN poetry config virtualenvs.create false && poetry install

COPY . /app

CMD ["python3", "bot.py"]

【问题讨论】:

  • 你能把Dockerfile也发完整个吗?
  • Dockerfile 已添加。
  • @mredy 你解决了吗?我在构建另一个使用ssl 的机器人时遇到了完全相同的问题。我试过 docker python images v3.9.7 甚至 3.10.0rc2-buster 但似乎没有帮助。在ssl do_handshake 期间仍然出现分段错误
  • @IljaLeiko,我花了更多的时间,我想花时间弄清楚,所以放弃并继续在我的 Linux 机器上进行开发。对不起。
  • 没关系,谢谢@mredy。我实际上已经为我的情况解决了这个问题。发现问题确实在我的ssl 中(就像在分段错误之前的回溯显示一样)。问题是,无论我使用哪个python docker 映像,它总是放置openssl 的过时版本,因此python 也在使用它。所以我不得不修改我的DockerFile 以从源代码构建最新的openssl,删除现有的二进制文件,然后我的python 项目将使用最新的openssl 版本。这为我解决了问题:) 奇怪的是,问题只在 M1 上对我来说:)

标签: python docker discord.py apple-m1


【解决方案1】:

我在另一个项目中遇到了同样的问题。

我不知道到底是什么问题,也不知道我是如何解决这个问题的,但我的热门猜测是新的 python 更新于 2021-08-30 [例如 v3.9.7 (https://docs. python.org/release/3.9.7/whatsnew/changelog.html)] 用 OpenSSL 1.1.1 for mac 修复了它,这对我来说毫无意义,因为这不应该影响 docker 容器,但谁知道呢。 只需重建您的图像(使用新版本),看看它是否有效。它对我有用。

希望这会有所帮助:)

【讨论】:

    【解决方案2】:

    虽然您提出了一个复杂的情况(许多活动部件),但罪魁祸首似乎很可能是 ffmpeg docker 包,它没有为 Apple Silicon M1/ARM 处理器进行代码签名。

    Apple Silicon 设备只能运行签名文件。

    以下是使ffmpeg 工作的一些选项:

    使用预制脚本构建ffmpeg

    在开始之前,您必须将install arm64-based Homebrew 转为/opt/homebrew

    1. 克隆the helper repository
      1. git clone https://github.com/mavaddat/ffmpeg-on-apple-silicon.git
      2. cd ffmpeg-on-apple-silicon
      3. chmod +x ./build.bash
    2. 运行./build.bash

    在 Apple Silicon(M1/ARM 处理器)上 DIY 编译 FFMPEG

    Download FFmpeg 4.4 (With ARM Neon patch) for Apple Silicon macOS 11.0 and Higher

    SHA256 校验和:5371a20db551b3e04593a052305eb97da3558b1d60271a4fc8f1763a37a6ac43

    您可以在终端中对下载的文件进行临时签名:

    xattr -cr <pathtotheffmpegfile>  
    codesign -s - ~/Downloads/ffmpeg44arm.zip
    

    注意:Apple Silicon 的 FFmpeg 文件包含 x265 NEON 补丁。这使得 x265 的编码速度更快。

    如何为macOS编译一个真正的静态FFmpeg文件

    编译 FFmpeg 有几种方法。 Homebrew 是一种编译 FFmpeg 文件的简单方法,但遗憾的是它们不是静态的。
    静态意味着您可以将 FFmpeg 文件复制到任何您想要的位置。
    与 Homebrew 这样的动态构建相比,它没有依赖项。

    下面的脚本将构建一个实际静态的 FFmpeg 文件。它没有涵盖所有可能的外部库,但它会给你一个良好的开端。当然,您可以自己添加更多的库,例如 TheoraVorbisVPX 等。

    首先,下载所有源文件(版本链接可能已过时):

    当然还有FFmpeggit clone git://git.ffmpeg.org/ffmpeg.git

    您还需要安装Apple Xcode

    为 ARM(M1 处理器)构建

    ? 如果您下载了较新版本的库,请在下面的脚本中相应地更新版本号。 ⚠️

    echo '♻️ ' Create Ramdisk
        
        if df | grep Ramdisk > /dev/null ; then tput bold ; echo ; echo ⏏ Eject Ramdisk ; tput sgr0 ; fi
        
        if df | grep Ramdisk > /dev/null ; then diskutil eject Ramdisk ; sleep 1 ; fi
        
        DISK_ID=$(hdid -nomount ram://6000000)
        
        newfs_hfs -v tempdisk ${DISK_ID}
        
        diskutil mount ${DISK_ID}
        
        sleep 1
        
        SRC="/Volumes/tempdisk/sw"
        
        CMPLD="/Volumes/tempdisk/compile"
        
        mkdir ${SRC}
        
        mkdir ${CMPLD}
        
        export PATH=${SRC}/bin:$PATH
        
        export CC=clang && export PKG_CONFIG_PATH="${SRC}/lib/pkgconfig"
        
        #
        # ask user to copy all files to ramdisk
        #
        
        echo
        echo Copy all files to ramdisk and press a key when ready
        read -s 
        
        # echo '♻️ ' Start compiling YASM
        
        #
        # compile YASM
        #
        
        cd ${CMPLD}
        
        cd yasm-1.3.0
        
        ./configure --prefix=${SRC}
        
        make -j 16
        
        make install
        
        sleep 1
        
        echo '♻️ ' Start compiling NASM
        
        #
        # compile NASM
        #
        
        cd ${CMPLD}
        
        cd nasm-2.16
        
        ./configure --prefix=${SRC}
        
        make -j 16
        
        make install
        
        sleep 1
        
        echo '♻️ ' Start compiling PKG
        
        #
        # compile PKG
        #
        
        cd ${CMPLD}
        
        cd pkg-config-0.29.2
        
        export LDFLAGS="-framework Foundation -framework Cocoa"
        
        ./configure --prefix=${SRC} --with-pc-path=${SRC}/lib/pkgconfig --with-internal-glib --disable-shared --enable-static
        
        make -j 16
        
        make install
        
        unset LDFLAGS
        
        sleep 1
        
        echo '♻️ ' Start compiling CMAKE
        
        #
        # compile CMAKE
        #
        
        cd ${CMPLD}
        
        cd cmake-3.21.1
        
        ./configure --prefix=${SRC}
        
        make -j 16
        
        make install
        
        sleep 1
        
        echo '♻️ ' Start compiling Lame
        
        #
        # compile Lame
        #
        
        cd ${CMPLD}
        
        cd lame
        
        ./configure --prefix=${SRC} --disable-shared --enable-static
        
        make -j 16
        
        make install
        
        echo '♻️ ' Start compiling X264
        
        #
        # x264
        #
        
        cd ${CMPLD}
        
        cd x264
        
        ./configure --prefix=${SRC} --disable-shared --enable-static
        
        make -j 16
        
        make install
        
        make install-lib-static
        
        # echo
        # echo continue
        # read -s 
        
        sleep 1
        
        echo '♻️ ' Start compiling X265
        
        #
        # x265
        #
        
        rm -f ${SRC}/include/x265*.h 2>/dev/null
        
        rm -f ${SRC}/lib/libx265.a 2>/dev/null
        
        echo '♻️ ' X265 12bit
        
        cd ${CMPLD}
        
        cd /Volumes/tempdisk/compile/x265/source
        
        cmake -DCMAKE_INSTALL_PREFIX:PATH=${SRC} -DHIGH_BIT_DEPTH=ON -DMAIN12=ON -DENABLE_SHARED=NO -DEXPORT_C_API=NO -DENABLE_CLI=OFF .
        
        make -j 16
        
        mv libx265.a libx265_main12.a
        
        make clean-generated
        
        rm CMakeCache.txt
        
        echo '♻️ ' X265 10bit
        
        cd ${CMPLD}
        
        cd /Volumes/tempdisk/compile/x265/source
        
        cmake -DCMAKE_INSTALL_PREFIX:PATH=${SRC} -DHIGH_BIT_DEPTH=ON -DMAIN10=ON -DENABLE_SHARED=NO -DEXPORT_C_API=NO -DENABLE_CLI=OFF .
        
        make clean
        
        make -j 16
        
        mv libx265.a libx265_main10.a
        
        make clean-generated && rm CMakeCache.txt
        
        echo '♻️ ' X265 full
        
        cd ${CMPLD}
        
        cd /Volumes/tempdisk/compile/x265/source
        
        cmake -DCMAKE_INSTALL_PREFIX:PATH=${SRC} -DEXTRA_LIB="x265_main10.a;x265_main12.a" -DEXTRA_LINK_FLAGS=-L. -DLINKED_10BIT=ON -DLINKED_12BIT=ON -DENABLE_SHARED=OFF -DENABLE_CLI=OFF .
        
        make clean
        
        make -j 16
        
        mv libx265.a libx265_main.a
        
        libtool -static -o libx265.a libx265_main.a libx265_main10.a libx265_main12.a 2>/dev/null
        
        make install
        
        sleep 1
        
        echo '♻️ ' Start compiling VPX
        
        #
        # VPX
        #
        
        cd ${CMPLD}
        
        cd libvpx
        
        ./configure --prefix=${SRC} --enable-vp8 --enable-postproc --enable-vp9-postproc --enable-vp9-highbitdepth --disable-examples --disable-docs --enable-multi-res-encoding --disable-unit-tests --enable-pic --disable-shared
        
        make -j 16
        
        make install
        
        echo '♻️ ' Start compiling ZLIB
        
        #
        # ZLIB
        #
        
        cd ${CMPLD}
        
        cd zlib-1.2.11
        
        ./configure --prefix=${SRC}
        
        make -j 16
        
        make install
        
        rm ${SRC}/lib/libz.so*
        
        rm ${SRC}/lib/libz.*
        
        echo '♻️ ' Start compiling EXPAT
        
        #
        # EXPAT
        #
        
        cd ${CMPLD}
        
        cd expat-2.2.10
        
        ./configure --prefix=${SRC} --disable-shared --enable-static
        
        make -j 16
        
        make install
        
        echo '♻️ ' Start compiling LIBICONV
        
        #
        # libiconv
        #
        
        cd ${CMPLD}
        
        cd libiconv-1.16
        
        ./configure --prefix=${SRC} --disable-shared --enable-static
        
        make -j 16
        
        make install
        
        echo '♻️ ' Start compiling ENCA
        
        #
        # ENCA
        #
        
        cd ${CMPLD}
        
        cd enca-1.5
        
        ./configure --prefix=${SRC} --disable-shared --enable-static
        
        make -j 16
        
        make install
        
        echo '♻️ ' Start compiling FREETYPE
        
        #
        # FREETYPE
        #
        
        cd ${CMPLD}
        
        cd freetype-2.10.4
        
        ./configure --prefix=${SRC} --disable-shared --enable-static
        
        make -j 16
        
        make install
        
        echo '♻️ ' Start compiling FONTCONFIG
        
        #
        # FONTCONFIG
        #
        
        cd ${CMPLD}
        
        cd fontconfig-2.13.93
        
        ./configure --prefix=${SRC} --enable-iconv --disable-libxml2 --disable-shared --enable-static --disable-docs
        
        make -j 16
        
        make install
        
        echo '♻️ ' Start compiling FRIBIDI
        
        #
        # FRIBIDI
        #
        
        cd ${CMPLD}
        
        cd fribidi-1.0.5
        
        ./configure --prefix=${SRC} --disable-shared --enable-static
        
        make -j 16
        
        make install
        
        echo '♻️ ' Start compiling HARFBUZZ
        
        #
        # HARFBUZZ
        #
        
        cd ${CMPLD}
        
        cd harfbuzz-2.7.2
        
        ./configure --prefix=${SRC} --disable-shared --enable-static
        
        make -j 16
        
        make install
        
        sleep 1
        
        echo '♻️ ' Start compiling OPUS
        
        echo '♻️ ' Start compiling LIBASS
        
        #
        # LIBASS
        #
        
        cd ${CMPLD}
        
        cd libass-0.15.0
        
        ./configure --prefix=${SRC} --disable-fontconfig --disable-shared --enable-static
        
        make -j 16
        
        make install
        
        sleep 1
        
        echo '♻️ ' Start compiling OPUS
        
        #
        # OPUS
        #
        
        cd ${CMPLD}
        
        cd opus-1.3.1
        
        ./configure --prefix=${SRC} --disable-shared --enable-static
        
        make -j 16
        
        make install
        
        sleep 1
        
        #
        # LIBOGG
        #
        
        cd ${CMPLD}
        
        cd libogg-1.3.4
        
        ./configure --prefix=${SRC} --disable-shared --enable-static
        
        make -j 16
        
        make install
        
        sleep 1
        
        #
        # LIBVORBIS
        #
        
        cd ${CMPLD}
        
        cd libvorbis-1.3.7
        
        ./configure --prefix=${SRC} --with-ogg-libraries=${SRC}/lib --with-ogg-includes=${SRC}/include/ --enable-static --disable-shared
        
        make -j 16
        
        make install
        
        sleep 1
        
        #
        # THEORA
        #
        
        cd ${CMPLD}
        
        cd libtheora-1.1.1
        
        ./configure --prefix=${SRC} --disable-asm --with-ogg-libraries=${SRC}/lib --with-ogg-includes=${SRC}/include/ --with-vorbis-libraries=${SRC}/lib --with-vorbis-includes=${SRC}/include/ --enable-static --disable-shared
        
        make -j 16
        
        make install
        
        sleep 1
        
        #
        # SNAPPY
        #
        
        cd ${CMPLD}
        
        cd snappy
        
        cmake -DCMAKE_INSTALL_PREFIX:PATH=${SRC} -DENABLE_SHARED=OFF -DENABLE_CLI=OFF
        
        make -j 16
        
        make install
        
        sleep 1
        
        echo '♻️ ' Start compiling Vid-stab
        
        #
        # Vidstab
        #
        
        cd ${CMPLD}
        
        cd vidstab-master
        
        cmake -DCMAKE_INSTALL_PREFIX:PATH=${SRC} -DLIBTYPE=STATIC -DBUILD_SHARED_LIBS=OFF -DUSE_OMP=OFF -DENABLE_SHARED=off .
        
        make -j 16
        
        make install
        
        sleep 1
        
        echo '♻️ ' Start compiling AOM
        
        #
        # AOM
        #
        
        cd ${CMPLD}
        
        cd aom
        
        mkdir aom_build
        
        cd aom_build
        
        cmake ${CMPLD}/aom -DENABLE_TESTS=0 -DCMAKE_INSTALL_PREFIX:PATH=${SRC} -DLIBTYPE=STATIC -DAOM_TARGET_CPU=ARM64 -DCONFIG_RUNTIME_CPU_DETECT=0
        
        make -j 16
        
        make install
        
        sleep 1
        
        echo '♻️ ' Start compiling FFMPEG
        
        cd ${CMPLD}
        
        cd ffmpeg
        
        export LDFLAGS="-L${SRC}/lib"
        
        export CFLAGS="-I${SRC}/include"
        
        export LDFLAGS="$LDFLAGS -framework VideoToolbox"
        
        ./configure --prefix=${SRC} --extra-cflags="-fno-stack-check" --arch=arm64 --cc=/usr/bin/clang --enable-fontconfig --enable-libaom --enable-gpl --enable-libopus --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libvpx --enable-libass --enable-libfreetype --enable-libtheora --enable-libvorbis --enable-libsnappy --enable-libvidstab --enable-version3 --pkg-config-flags=--static --disable-ffplay --enable-postproc --enable-nonfree --enable-neon --enable-runtime-cpudetect --disable-indev=qtkit --disable-indev=x11grab_xcb
        
        make -j 16
        
        make install
    

    感谢 OS X 专家:https://www.osxexperts.net

    【讨论】:

    • 你答错了吗?这似乎无关
    • 哇,这是在 arm64 架构上运行 ffmpeg 的相当详细的安装指南。不幸的是,问题出在其他地方。我尝试了多个版本的 Dockerfiles,试图让它尽可能轻,但我得到了同样的错误。到目前为止,我已经尝试将arm64v8/python:3.9.6-slim-busteralpine(我什至无法构建)和buster 作为基础镜像。我删除了除 build-essential 之外的所有软件包。诗歌仅包含python = "^3.9"PyNaCl = "^1.4.0"discord.py = "^1.7.3" 依赖项。
    • @mredy 你是如何绕过 ffmpeg 对 discordpy 的要求的?
    • @MavaddatJavid 我仍然需要ffmpeg,但我认为,这不是它崩溃的主要原因,因为正如我在上面的评论中提到的那样,我得到了没有安装ffmpeg 的相同段错误。
    猜你喜欢
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-04
    • 1970-01-01
    • 2021-05-11
    • 2021-08-30
    • 1970-01-01
    相关资源
    最近更新 更多