链接器错误疯狂的 Python lua.require('socket') ->未定义的符号:lua_getmetatable
我有一个 python 项目依赖于一些 lua 文件,其中之一需要“socket”。当我尝试从 python 2.7 请求该 lua 文件时,加载 socket.core“未定义符号:lua_getmetatable”时出现错误。
简单的重现器:
$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import lua
>>> lua.require('socket')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception: error: error loading module 'socket.core' from file
'/usr/lib/lua/5.1/socket/core.so':
/usr/lib/lua/5.1/socket/core.so: undefined symbol: lua_getmetatable
我正在使用 最近的 Lunatic Python 分支,我在其中清理了 Py_ssize_t 警告和 liblua5 Ubuntu 11.04 上的 .1-socket2
如果我使用主要的 lunatic-python 源代码和/或升级到 luasocket 2.0.2。
编辑: 是什么导致了这个错误,如何修复它?
编辑#2:这是构建 luasocket-2.0.2 的输出。默认的 make 没有构建 unix.so,我也编辑了它来构建它,所以我没有将 2.0.0 与 2.0.2 混合和匹配:
$ make
cd src; make all
make[1]: Entering directory `/sandbox/luasocket/luasocket-2.0.2/src'
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o luasocket.o luasocket.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o timeout.o timeout.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o buffer.o buffer.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o io.o io.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o auxiliar.o auxiliar.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o options.o options.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o inet.o inet.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o tcp.o tcp.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o udp.o udp.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o except.o except.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o select.o select.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o usocket.o usocket.c
gcc -O -shared -fpic -o socket.so.2.0.2 luasocket.o timeout.o buffer.o io.o auxiliar.o options.o inet.o tcp.o udp.o except.o select.o usocket.o
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o mime.o mime.c
gcc -O -shared -fpic -o mime.so.1.0.2 mime.o
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o unix.o unix.c
gcc -O -shared -fpic -o unix.so buffer.o auxiliar.o options.o timeout.o io.o usocket.o unix.o
make[1]: Leaving directory `/sandbox/luasocket/luasocket-2.0.2/src'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题不在于
luasocket
,而在于处理共享库中的符号的方式。问题是,虽然
lua.so
(Python 模块)链接到liblua5.1.so
,但require
加载的共享模块却没有链接到liblua5.1.so
。可以访问 liblua5.1.so 中的符号。在 Mac OS X 上,这是可行的,因为来自dlopen
的符号默认加载为RTLD_GLOBAL
。我尝试过修改Lua源代码(
lua-5.1.4/src/loadlib.c:69
),但是它没有帮助,因为当require
是从lua.so
调用,来自liblua5.1.so
的符号已经在本地加载到lua.so
。这就是为什么luasocket
看不到它们。幸运的是,Python 允许您使用 sys 模块更改 dlopen 语义。这允许您强制使用
RTLD_GLOBAL
加载模块,这正是所需要的。尝试运行以下代码,看看它是否适合您:The problem is not in
luasocket
, but in the way symbols from shared libraries are handled.The problem is that the while the
lua.so
(Python module) links toliblua5.1.so
, shared modules loaded byrequire
do not have access to the symbols fromliblua5.1.so
. On Mac OS X this works, because symbols fromdlopen
are loaded asRTLD_GLOBAL
by default.I have experimented with modifying the Lua source (
lua-5.1.4/src/loadlib.c:69
), however it does not help, because by the timerequire
is called fromlua.so
, the symbols fromliblua5.1.so
have already been loaded locally forlua.so
. This is whyluasocket
does not see them.Fortunately, Python allows you to change the
dlopen
semantics using thesys
module. This allows you to force to load modules withRTLD_GLOBAL
, which is exactly what is needed. Try running the following code and see if it works for you: