使用Apple Silicon M1的Docker内部Discord.py分段故障

2024-04-26 09:29:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试为discord.py bot设置Docker环境。我设法创建了一个Dockerfile,它使用python:3.9-slim-buster作为基本映像。当我在我的Ubuntu机器上运行Docker容器内的bot时,一切都很好。然而,如果我将MacBook与Apple Silicon M1芯片一起使用,它的行为会有所不同。运行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 bug还是有什么方法可以解决这个问题

编辑: 新增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"]

Tags: runinpyclientlibpackagesusrlocal
2条回答

尽管您呈现了一个复杂的情况(许多移动部件),但罪魁祸首似乎是ffmpegdocker包,它不是针对Apple Silicon M1/ARM处理器的代码签名

code signing workflow

苹果硅设备只能运行签名文件。

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

使用pre-fab脚本构建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

在苹果硅芯片上DIY编译FFMPEG(M1/ARM处理器)

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

注意:苹果硅的FFmpeg文件包括x265霓虹灯补丁。这使得x265的编码速度更快。

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

有几种编译FFmpeg的方法Homebrew是编译FFmpeg文件的一种简单方法,但遗憾的是它们不是静态的。
静态意味着您可以在任何地方复制FFmpeg文件。
与Homebrew那样的动态构建相比,它没有依赖性

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

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

^{tb1}$

当然,还有,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

由OSX专家提供:https://www.osxexperts.net

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

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

希望这有帮助:)

相关问题 更多 >