使用自定义openssl版本编译python时的Coredump

edd*_*eek 8 python openssl makefile

使用本地openssl-1.0.1f共享安装编译python-3.4.0rc3时,make打印没有错误但是我在make install或make test上得到以下核心转储:

Program terminated with signal 11, Segmentation fault.
(gdb) bt
#0  0x00007f131dd10510 in EVP_PKEY_CTX_dup () from /data2/soft/openssl/lib/libcrypto.so.1.0.0
#1  0x00007f131dd0284f in EVP_MD_CTX_copy_ex () from /data2/soft/openssl/lib/libcrypto.so.1.0.0
#2  0x00007f131e256ab5 in EVPnew (name_obj=0x7f131e46a500, digest=0x0, initial_ctx=0x7f131e459a40, cp=0x0, len=0) at /data2/soft/python3/Python-3.4.0rc3/Modules/_hashopenssl.c:410
#3  0x00007f131e25726e in EVP_new_md5 (self=<value optimized out>, args=<value optimized out>) at /data2/soft/python3/Python-3.4.0rc3/Modules/_hashopenssl.c:799
#4  0x00000000004c7eef in ?? ()
Run Code Online (Sandbox Code Playgroud)

以下是使用的完整命令列表

tar -axf Python-3.4.0rc3.tgz
cd Python-3*
# For lzma and a pip-compatible openssl
export CFLAGS='-I/data2/soft/openssl/include/openssl -I/data2/local/include/'
export LDFLAGS='-L/data2/soft/openssl/lib -L/data2/local/lib/'
export LD_LIBRARY_PATH="/data2/soft/openssl/lib:/data2/local/lib/:$LD_LIBRARY_PATH"
# Ready !
./configure --prefix=/data2/soft/python3
make
make install
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 操作系统是SUSE Linux Enterprise Server 11(x86_64)
  • 将python指向位于的lzma lib的自定义位置
  • openssl是用 ./config shared --openssldir=/data2/soft/openssl
  • openssl make test打印所有测试成功.
  • 没有自定义openssl*FLAGS,make install是成功的,我得到这些结果进行make test: 71 tests OK. tests failed: test_cmd_line test_gdb test_smtpnet test_ssl

我该如何解决这个问题,或者至少调查一下发生了什么?

编辑1--5:

共享库是正确生成的:

> ls /data2/soft/openssl/lib
drwxr-xr-x engines
-rw-r--r-- libcrypto.a
lrwxrwxrwx libcrypto.so -> libcrypto.so.1.0.0
-r-xr-xr-x libcrypto.so.1.0.0
-rw-r--r-- libssl.a
lrwxrwxrwx libssl.so -> libssl.so.1.0.0
-r-xr-xr-x libssl.so.1.0.0
drwxr-xr-x pkgconfig
Run Code Online (Sandbox Code Playgroud)

所以我在安装程序中更改了

SSL=/data2/soft/openssl/
_ssl _ssl.c \                               
    -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
    $(SSL)/lib/libssl.a $(SSL)/lib/libcrypto.a -ldl
Run Code Online (Sandbox Code Playgroud)

我相应地改变了LDFLAGS/CFLAGS.但是当我运行make clean && make时,仍然有一个-lssl,因为_hashopen模块:

gcc -pthread -shared -L/data2/local/lib/ -L/data2/local/lib/ -L/data2/local/lib/ -I/data2/local/include/ build/temp.linux-x86_64-3.4/data2/soft/python3/Python-3.4.0rc3/Modules/_hashopenssl.o -L/data2/local/lib/ -L/usr/local/lib -lssl -lcrypto -o build/lib.linux-x86_64-3.4/_hashlib.cpython-34m.so
Run Code Online (Sandbox Code Playgroud)

我想这是导致核心的那个,因为它们仍然存在...我尝试在安装文件中添加类似的东西,但是没有这个注释项目并且创建它会导致另一个更加神秘的失败:

gcc -pthread   -Xlinker -export-dynamic -o python Modules/python.o libpython3.4m.a -lpthread -ldl  -lutil /data2/eoubrayrie/soft/openssl/lib/libssl.a /data2/eoubrayrie/soft/openssl/lib/libcrypto.a -ldl   /data2/eoubrayrie/soft/openssl/lib/libssl.a /data2/eoubrayrie/soft/openssl/lib/libcrypto.a -ldl   -lm  
libpython3.4m.a(config.o):(.data+0x158): undefined reference to `PyInit__hashopenssl'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

编辑6:

  • 我无论如何都无法修改如何生成_hashlib.so,因为涉及太多的Makefile魔法(它不会出现在任何地方,'-lssl'也不会同时神奇地结束在同一条线上
  • 但我可以通过良好的旧-I/-L动态链接到我自己的openssl:

    ldd build/lib.linux-x86_64-3.4/_hashlib.cpython-34m.so libssl.so.1.0.0 => /data2/soft/openssl/lib/libssl.so.1.0.0 (0x00007f5605799000) libcrypto.so.1.0.0 => /data2/soft/openssl/lib/libcrypto.so.1.0.0 (0x00007f56053bd000)

  • 现在唯一的问题是,gdb info shared仍然告诉我另一个在核心时间使用......但是如何?

    From To Syms Read Shared Object Library 0x00007ffff5465930 0x00007ffff5466e98 Yes /data2/soft/python3/Python-3.4.0rc3/build/lib.linux-x86_64-3.4/_hashlib.cpython-34m.so 0x00007ffff5321220 0x00007ffff5351878 Yes /opt/python-2.6-64/lib/libssl.so.1.0.0 0x00007ffff50d3100 0x00007ffff519b118 Yes /opt/python-2.6-64/lib/libcrypto.so.1.0.0

    • env | grep -F 'python-2.6-64' - >什么都没显示!
    • grep -RF 'python-2.6-64' /etc/ld.so.* - >同上
    • gcc -print-search-dirs | sed 's/:/\n/g' | grep python - >同上
    • find . -name '*.so*' | xargs ldd | grep ssl - >只给我好的
    • 1级依赖项也不需要任何错误的ssl版本.检查结果如下:
      find . -name '*.so*' | xargs ldd | awk '/\t+[[:alnum:].]+ => [[:alnum:]./]+ \(/ {print $3}' | sort | uniq | xargs ldd | grep ssl
    • strace ./python ./Tools/scripts/run_tests.py 2>&1 | grep python-2.6-64 - >什么都没显示

那么ld如果他不能知道如何选择这个错误的库呢?它不在任何标准位置(如果它在/ lib中我能理解......)

解:

由于这个OpenOffice错误,发现如何静态链接_hashlib :虽然该-Wl,--exclude-libs=ALL"选项也不起作用,但它指向了setup.py中的右侧行.

TL; DR这是我应用的setup.py补丁.

最后......它有效!

@noloader我接受你最完整的答案,因为你的帮助是非常宝贵的,尽管遇到这个问题的人的"确切"答案是使用上面的补丁进行编译.

jww*_*jww 4

How can I fix this, or at least investigate what is going on ?
...
export LDFLAGS='-L/data2/soft/openssl/lib -L/data2/local/lib/'
export LD_LIBRARY_PATH="/data2/soft/openssl/lib:/data2/local/lib/
Run Code Online (Sandbox Code Playgroud)

我也经常遇到这些问题,因为我避免使用 Debian、Ubuntu、Fedora 等提供的 OpenSSL 版本。例如,Ubuntu 附带了禁用 TLSv1.1 和 TLS v1.2 的 OpenSSL(参见Ubuntu 12.04 LTS:OpenSSL 下级版本,不支持 TLS 1.2)。

您可能加载了错误版本的 OpenSSL 库。如果您可以在调试器下找到行为不当的程序,请发出命令info shared以查看您实际正在加载哪个libcrypto程序libssl

ldd也可能有帮助。在 Pyhton 可执行文件上运行它:ldd /data2/soft/python3/python. 我只能说它“可能”有帮助,因为 OpenSSL 是二进制兼容的,因此您可能只会看到对(在 Mac OS X 上libcrypto.so.1.0.0使用otool -L)等的依赖。下面我使用了一个rpath来强制链接到/usr/local/ssl/lib/.

$ ldd my-test.exe 
    linux-vdso.so.1 =>  (0x00007fffd61ff000)
    libssl.so.1.0.0 => /usr/local/ssl/lib/libssl.so.1.0.0 (0x00007f151528e000)
    libcrypto.so.1.0.0 => /usr/local/ssl/lib/libcrypto.so.1.0.0 (0x00007f1514e74000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f1514c42000)
    ...
Run Code Online (Sandbox Code Playgroud)

作为修复,您可以尝试添加rpath

LDFLAGS='-L/data2/soft/openssl/lib -L/data2/local/lib/ -Wl,-rpath,/data2/soft/openssl/lib'
Run Code Online (Sandbox Code Playgroud)

更好的解决方法是链接到 OpenSSL 库的静态版本,以避免这些问题。我相信你可以用以下方法做到这一点-Bstatic -lssl -lcrypto -Bdynamic -ldl

-Bstatic就我个人而言,由于不同的一次性问题,我什至不使用。我打开 Makefiles,删除 的所有实例-lssl -lcrypto,并添加存档的完整路径以消除所有歧义。例如,/data2/soft/openssl/lib/libssl.a/data2/soft/openssl/lib/libcrypto.a

请注意rpathMac OS X 上不支持 an。Mac OS X 需要采取更极端的措施,因为链接器也不支持-Bstatic这两者。您必须使用完整路径技巧。


openssl was built with ./config shared --openssldir=/data2/soft/openssl
Run Code Online (Sandbox Code Playgroud)

另一件事......在 Fedora 上,仅指定shared. 您还需要添加以下内容:

export CFLAGS="-fPIC"
Run Code Online (Sandbox Code Playgroud)

否则,不会构建共享对象。如果未构建 1.0.1f 共享对象,您可能会获得发行版提供的低级版本。您可以使用以下命令检查安装构建的内容:

./config shared --openssldir=/data2/soft/openssl
make all

# Verify artifacts
find . -iname -libcrypto.*
find . -iname -libssl.*

# Proceed if OK
sudo make install
Run Code Online (Sandbox Code Playgroud)

最后,确保所有Python 依赖项也使用您的 OpenSSL 版本,而不是系统的 OpenSSL 版本。

我最近在我的程序使用 OpenSSL 时遇到了这个问题;但我的程序也使用libeventlibevent使用了系统版本的OpenSSL。我通过重建libevent并强制它静态链接到我的 OpenSSL 版本来修复它。