LoginSignup
53
29

More than 3 years have passed since last update.

pythonを三行でセグフォらせる

Last updated at Posted at 2020-06-26

多分これが一番早いと思います。

$ docker run -ti python:3.8-slim bash
# pip install mysql-connector-python==8.0.20
# python
>>> import random
>>> import mysql.connector
Segmentation fault

何が起こっているのか。

前提

mysql-connector-pythonは8.0.20からlibcrypto.so.1.1libssl.so.1.1をbundleするようになりました。

$ pip show -f mysql-connector-python  | grep lib
Location: /usr/local/lib/python3.8/site-packages
  mysql-vendor/libcrypto.so.1.1
  mysql-vendor/libssl.so.1.1

解説

import random

randomをインポートすると libcrypto.so.1.1をロードします。
この時はシステムにインストールされた libcrypto.so.1.1をロードします。

import mysql.connector

このimport文でlibssl.so.1.1libcrypto.so.1.1をロードしようとします。
その際、libssl.so.1.1はバンドルされた独自のものをロードするのですが、
libcrypto.so.1.1はすでにロード済みなので、ロードしません。

したがって以下のような状態になります。

libcrypto.so.1.1 --> /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
libssl.so.1.1 --> /usr/local/lib/python3.8/site-packages/mysql-vendor/libssl.so.1.1

libcrypto.so.1.1に互換性がないため、segmentation faultとなります。

すでにbugとして報告されています。
https://bugs.mysql.com/bug.php?id=97220

回避策

  1. LD_PRELOADで /usr/local/lib/python3.8/site-packages/mysql-vendor/libssl.so.1.1等を読み込む
  2. 8.0.19以前のバージョンを使う。

追記

別にrandomを読み込まなくてもセグフォすることがわかりました。

>>> import mysql.connector
Segmentation Fault

上記の理屈だと若干説明がつかないので原因は別にあるようです。
LD_PRELOADで回避できるのでバンドルされたライブラリに読み込み順序に何か問題があることは確かだと思います。

ちなみに、不思議なのですが、 python:3.8-slimイメージでは発生しますが、 python:3.8イメージでは発生しません。

53
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
53
29