段错误,但为什么呢?它只发生在 debian:stretch+mysql.connector+tox 和 Python3.x 上。只需几行即可重现:
FROM debian:stretch
RUN apt update -y && apt install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev gcc wget tox vim python-pip python3-pip
RUN wget https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz
RUN tar xvf Python-3.6.9.tgz && cd Python-3.6.9 &&./configure --enable-optimizations --enable-shared --with-ssl --with-ensurepip=install && make -j8 && make altinstall
RUN mkdir /tox-test && echo "[tox]" >> /tox-test/tox.ini && echo "envlist = py36" >> /tox-test/tox.ini && echo "[testenv]" >> /tox-test/tox.ini && echo "deps=" >> /tox-test/tox.ini
RUN echo " mysql-connector-python" >> /tox-test/tox.ini && echo "commands=python3.6 setup.py test" >> /tox-test/tox.ini
RUN mkdir /tox-test/tests && touch /tox-test/tests/__init__.py && echo "import faulthandler\nfaulthandler.enable()\nimport mysql.connector as mysql" >> /tox-test/tests/test_segfault.py
RUN echo "mysql.connect(host='localhost', user='joe', password='bloggs')" >> /tox-test/tests/test_segfault.py
RUN mkdir /tox-test/foo && echo "print('foo')" >> /tox-test/foo/foo.py
RUN echo "from setuptools import setup" >> /tox-test/setup.py && echo "setup( name='foo',version='1.0',description='A module',author='Niklas R.',author_email='[email protected]',packages=['foo'],test_suite='tests',)" >> /tox-test/setup.py
RUN cd /tox-test && export LD_LIBRARY_PATH=/Python-3.6.9 && tox
上面生成了一个段错误。对于 Ubuntu 和 Debian Jessie,它可以工作或可以解决。我不明白为什么 Stretch 会发生这种情况,而且我无法修复它。段错误似乎与网络有关,因为如果我写“127.0.0.1”而不是“localhost”,那么它就不会崩溃。请帮助我理解。我的猜测是导入正在隐藏或使用某些自己版本的 ssl 或类似版本。这是相当牵强的。它在 Ubuntu 上也可以重现,甚至更奇怪的故事是,在 Ubuntu 上,如果我在werkzeug.exceptions import BadRequestKeyError
不使用导入的情况下添加到 python,只导入它而不使用它,那么段错误就会被修复。如果我用 PyMySQL 替换 mysql-connector-python 那么它就可以工作。所以它一定是来自 mysql-connector-python 的东西。有关于该连接器的类似错误报告:https://bugs.mysql.com/bug.php?id=97220
如果我更改一个字符串“localhost”并改为“127.0.0.1”,则不再存在段错误:
FROM debian:stretch
RUN apt update -y && apt install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev gcc wget tox vim python-pip python3-pip
RUN wget https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz
RUN tar xvf Python-3.6.9.tgz && cd Python-3.6.9 &&./configure --enable-optimizations --enable-shared --with-ssl --with-ensurepip=install && make -j8 && make altinstall
RUN mkdir /tox-test && echo "[tox]" >> /tox-test/tox.ini && echo "envlist = py36" >> /tox-test/tox.ini && echo "[testenv]" >> /tox-test/tox.ini && echo "deps=" >> /tox-test/tox.ini
RUN echo " mysql-connector-python" >> /tox-test/tox.ini && echo "commands=python3.6 setup.py test" >> /tox-test/tox.ini
RUN mkdir /tox-test/tests && touch /tox-test/tests/__init__.py && echo "import faulthandler\nfaulthandler.enable()\nimport mysql.connector as mysql" >> /tox-test/tests/test_segfault.py
RUN echo "mysql.connect(host='127.0.0.1', user='joe', password='bloggs')" >> /tox-test/tests/test_segfault.py
RUN mkdir /tox-test/foo && echo "print('foo')" >> /tox-test/foo/foo.py
RUN echo "from setuptools import setup" >> /tox-test/setup.py && echo "setup( name='foo',version='1.0',description='A module',author='Niklas R.',author_email='[email protected]',packages=['foo'],test_suite='tests',)" >> /tox-test/setup.py
RUN cd /tox-test && export LD_LIBRARY_PATH=/Python-3.6.9 && tox
答案1
起初,它看起来像是套接字问题,但 socket.gethostbyname(host_name) 有效。经过一番挖掘,我发现问题被隔离到“mysql-connector-python”,如果您在 tox.ini 中将其更改为“mysql-connector-python-rf”,错误就会消失。这意味着 mysql-connector-python 中的某个位置无法将 dns 解析为 ip。