1. 程式人生 > 其它 >pip總是報Segmentation fault (core dumped)的問題(安裝python新版本3.9.6後)

pip總是報Segmentation fault (core dumped)的問題(安裝python新版本3.9.6後)

問題描述

一開始使用pyenv安裝了python 3.9.6版本之後,pyenv居然失靈了,切換不到任何版本去了,一氣之下,刪掉pyenv(rm -rf ~/.pyenv)直接原始碼安裝。

步驟如下:

  1. 到官網https://www.python.org/downloads/下載最新的tar包

  2. 解壓後執行:

     ./configure --prefix=/opt/python-3.9.6
     make
     make install
    
  3. 安裝完成後,pip不能正常使用,即便是檢視已安裝包都會出現core dump

     $ python3 -V
     Python 3.9.6
     $ pip3 list
     Package    Version
     ---------- -------
     pip        21.1.3
     setuptools 56.0.0
     Segmentation fault (core dumped)
     $ python3 -m pip list
     Package    Version
     ---------- -------
     pip        21.1.3
     setuptools 56.0.0
     Segmentation fault (core dumped)
    

解決方法

找了半天沒有找到答案,最後只能硬著頭皮去除錯pip3的程式碼,結果發現跟SSL有關(後面會描述如何發現的,這裡先說解決方法)。

官網https://www.python.org/dev/peps/pep-0644/也說了要求OpenSSL 1.1.1及以上版本(“Require OpenSSL 1.1.1 or newer”),而我自己機器上的是1.1.0版本的。

$ openssl version
OpenSSL 1.1.0h-fips  27 Mar 2018

解決辦法:

  1. 到OpenSSL官網https://www.openssl.org/source/下載1.1.1版本的tar包

  2. 解壓後執行:

     ./config
     make
     make install
    
  3. 安裝完成後,檢視OpenSSL版本報錯:

     $ openssl version
     openssl: /usr/lib64/libssl.so.1.1: version `OPENSSL_1_1_1' not found (required by openssl)
     openssl: /usr/lib64/libcrypto.so.1.1: version `OPENSSL_1_1_1' not found (required by openssl)
    

    解決辦法:

     export LD_LIBRARY_PATH=/usr/local/lib64    # 最好寫入 ~/.bashrc 或 /etc/profile 中去
     $ openssl version
     OpenSSL 1.1.1k  25 Mar 2021
    
  4. 這個時候以為問題解決了,重新執行 pip3 list 仍然會出現 core dump,折騰了一天,差點都想放棄了,後來一想,python編譯時連結的還是原來的舊庫,所有需要重新編譯python。回到 python 原始碼解壓目錄執行:

     make distclean    # 把上一次編譯過程中留下的餘孽清理乾淨
     ./configure --prefix=/opt/python-3.9.6
     make
     make install
    
  5. 完事後,再試,大功告成!

     $ pip3 list
     Package    Version
     ---------- -------
     pip        21.2.1
     setuptools 56.0.0
     $ python3 -m pip list
     Package    Version
     ---------- -------
     pip        21.2.1
     setuptools 56.0.0
     $ pip list
     Package    Version
     ---------- -------
     pip        21.2.1
     setuptools 56.0.0
    

分析過程

  1. 網上搜答案,沒有雷同的,苦惱!

  2. 想嘗試去除錯Core dump吧,即便執行了 ulimit -c unlimited ,也不會在當前目錄中生成 core file,最後發現 core file 在下面這個目錄,汗!

     /var/lib/systemd/coredump
    
  3. 有了 core file,咋除錯? 執行 gdb /opt/python-3.9.6/bin/pip3 core-file 根本就打印不出 backtrace 出來,因為 pip3 本身是個 python 文字檔案,而不是二進位制可執行程式。

  4. 好吧,除錯 pip3 這個 python 檔案:

     $ python -m pdb /opt/python-3.9.6/bin/pip3 list
     > /opt/python-3.9.6/bin/pip3(3)<module>()
     -> import re
     (Pdb) b /opt/python-3.9.6/lib/python3.9/ssl.py:483
     Breakpoint 1 at /opt/python-3.9.6/lib/python3.9/ssl.py:483
     (Pdb) c
     Package    Version
     ---------- -------
     pip        21.1.3
     setuptools 56.0.0
     > /opt/python-3.9.6/lib/python3.9/ssl.py(483)__new__()
     -> self = _SSLContext.__new__(cls, protocol)
     (Pdb) where
       /opt/python-3.9.6/lib/python3.9/bdb.py(580)run()
     -> exec(cmd, globals, locals)
       <string>(1)<module>()
       /opt/python-3.9.6/bin/pip3(8)<module>()
     -> sys.exit(main())
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_internal/cli/main.py(71)main()
     -> return command.main(cmd_args)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_internal/cli/base_command.py(104)main()
     -> return self._main(args)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_internal/cli/base_command.py(221)_main()
     -> self.handle_pip_version_check(options)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_internal/cli/req_command.py(147)handle_pip_version_check()
     -> pip_self_version_check(session, options)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_internal/self_outdated_check.py(152)pip_self_version_check()
     -> best_candidate = finder.find_best_candidate("pip").best_candidate
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_internal/index/package_finder.py(879)find_best_candidate()
     -> candidates = self.find_all_candidates(project_name)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_internal/index/package_finder.py(824)find_all_candidates()
     -> page_candidates = list(page_candidates_it)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_internal/index/sources.py(134)page_candidates()
     -> yield from self._candidates_from_page(self._link)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_internal/index/package_finder.py(783)process_project_url()
     -> html_page = self._link_collector.fetch_page(project_url)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_internal/index/collector.py(512)fetch_page()
     -> return _get_html_page(location, session=self.session)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_internal/index/collector.py(422)_get_html_page()
     -> resp = _get_html_response(url, session=session)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_internal/index/collector.py(120)_get_html_response()
     -> resp = session.get(
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_vendor/requests/sessions.py(555)get()
     -> return self.request('GET', url, **kwargs)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_internal/network/session.py(449)request()
     -> return super().request(method, url, *args, **kwargs)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_vendor/requests/sessions.py(542)request()
     -> resp = self.send(prep, **send_kwargs)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_vendor/requests/sessions.py(655)send()
     -> r = adapter.send(request, **kwargs)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_vendor/cachecontrol/adapter.py(53)send()
     -> resp = super(CacheControlAdapter, self).send(request, **kw)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_vendor/requests/adapters.py(439)send()
     -> resp = conn.urlopen(
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_vendor/urllib3/connectionpool.py(699)urlopen()
     -> httplib_response = self._make_request(
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_vendor/urllib3/connectionpool.py(382)_make_request()
     -> self._validate_conn(conn)
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_vendor/urllib3/connectionpool.py(1010)_validate_conn()
     -> conn.connect()
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_vendor/urllib3/connection.py(392)connect()
     -> self.ssl_context = create_urllib3_context(
       /opt/python-3.9.6/lib/python3.9/site-packages/pip/_vendor/urllib3/util/ssl_.py(281)create_urllib3_context()
     -> context = SSLContext(ssl_version or PROTOCOL_TLS)
     > /opt/python-3.9.6/lib/python3.9/ssl.py(483)__new__()
     -> self = _SSLContext.__new__(cls, protocol)    <=========== 這裡已經進不去了,core就出現在這一步,看名字就是跟SSL有關吧
     (Pdb) p cls
     <class 'ssl.SSLContext'>
     (Pdb) p protocol
     <_SSLMethod.PROTOCOL_TLS: 2>
     (Pdb) s
     Segmentation fault (core dumped)
    
  5. 看到SSL立馬去搜 python +SSL 關鍵字,才發現官網的這個說明https://www.python.org/dev/peps/pep-0644/,也就有了去嘗試安裝 OpenSSL 1.1.1 的想法。

這一切的一切都源於本來想安裝 pypiwin32 這個包,想用它來分析windows系統日誌,windows上裝成功了,linux上沒有裝成功,然後以為是舊版本的問題去裝新版本,折騰了一天,燒死多少腦細胞,就搞個環境問題,不過,生命在於折騰嘛!