【发布时间】:2014-04-19 23:39:37
【问题描述】:
当使用本地 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 ?? ()
这里是使用的命令的完整列表
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
注意事项:
- 操作系统是 SUSE Linux Enterprise Server 11 (x86_64)
- 将 python 指向 lzma 库的自定义位置
- 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
所以我在设置中更改了这个:
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
我相应地改回了 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
我猜这是导致内核的原因,因为它们仍然存在...我尝试将类似的内容添加到安装文件中,但没有对此进行评论的项目,并且创建它会导致另一个更神秘的失败:
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
编辑 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 我可以理解...)
解决方案:
感谢this OpenOffice bug,找到了如何静态链接_hashlib:虽然-Wl,--exclude-libs=ALL" 选项也不起作用,但它为我指出了setup.py 中的正确行。
TL;DR 这是我申请的patch to setup.py。
最后......它起作用了!
@noloader 我接受您最完整的答案,因为您的帮助非常宝贵,但对于遇到此问题的任何人来说,“确切”答案是使用上面的补丁进行编译。
【问题讨论】:
-
“但是 gdb 确实向我显示使用了错误的 libssl/libcrypto(系统的)” - 这通常表明首先加载了依赖项,并且该依赖项使用了错误的 OpenSSL 库。然后,当您的程序被加载时,OpenSSL 符号已从已加载的不正确版本的 OpenSSL 中得到满足。 LZMA 库是否需要
libcrypto? -
从顶级目录尝试
grep -R -lssl *和grep -R -lcrypto *。您也可以尝试跟踪_ssl.c和_ssl.o。如果正在使用-lssl,那么grep会找到它。就其价值而言,带有递归 makefile 的 autotools 项目给我带来的问题最多。 -
“所以我想我不明白你是如何给出完整路径的” - 请参阅下面的第二个答案(抱歉 - 第一个太长了,第二个更有针对性)。
-
"找不到 -l/data2/soft/openssl/lib/libssl.a" - 指定存档时删除
-l/data2/.../libssla.;并添加-ldl(OpenSSL 在此配置中将需要它)。 -
你是怎么看出来的?