【问题标题】:Linker Error Lunatic Python lua.require('socket') -> undefined symbol: lua_getmetatable链接器错误 Lua.require('socket') -> 未定义符号:lua_getmetatable
【发布时间】:2012-01-11 18:48:57
【问题描述】:

我有一个依赖于一些 lua 文件的 python 项目,其中一个需要“socket”。当我尝试从 python 2.7 请求该 lua 文件时,加载 socket.core "undefined symbol: 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

我使用recent Lunatic Python branch 清理了 Py_ssize_t 警告,以及 Ubuntu 11.04 上的 liblua5.1-socket2

如果我使用主要的 lunatic-python 源代码和/或升级到 luasocket 2.0.2,我会遇到同样的错误。

编辑:是什么导致了这个错误,我该如何解决?

edit #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'

【问题讨论】:

  • 问题是什么? ;)
  • 是什么导致了这个错误,我该如何解决?
  • 符号未正确从 lua 模块导出,可以在它需要的模块中使用。能否也贴一下编译阶段的日志,主要是最后的链接部分?
  • @MichalKottman 将编译和链接输出添加到原始问题。
  • 你试过运行ldconfig吗?如果/usr/lib/lua/5.1 是符号链接,那么echo "/path/to/lue5.1/lib" &gt; /etc/ld.so.conf.d/lua51.conf &amp;&amp; ldconfig

标签: python c ubuntu lua


【解决方案1】:

问题不在于luasocket,而在于共享库中符号的处理方式。

问题在于lua.so(Python 模块)链接到liblua5.1.so,由require 加载的共享模块无法访问来自liblua5.1.so 的符号。在 Mac OS X 上这是可行的,因为来自 dlopen 的符号默认加载为 RTLD_GLOBAL

我已经尝试修改 Lua 源 (lua-5.1.4/src/loadlib.c:69),但它没有帮助,因为当从 lua.so 调用 require 时,来自 liblua5.1.so 的符号已经在本地为 @ 加载987654333@。这就是luasocket 看不到它们的原因。

幸运的是,Python 允许您使用 sys 模块更改 dlopen 语义。这允许您强制使用 RTLD_GLOBAL 加载模块,这正是需要的。尝试运行以下代码,看看它是否适合您:

$ 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 sys, DLFCN
>>> sys.setdlopenflags(DLFCN.RTLD_NOW | DLFCN.RTLD_GLOBAL)
>>> import lua
>>> lua.require("socket")
<Lua table at 0x22ccef0>

【讨论】:

  • 哇...也感谢您的精彩解释。对于好奇的人,您可以通过“man ldload”和Python docs for the sys module 了解有关 ldload 的更多信息。 sys.setdlopenflags( n ) 仅适用于 unix。
  • 我遇到了类似的问题,除了在 lua 端而不是 python 端。我尝试使用-export-dynamic 重建疯子,希望它所依赖的符号对稍后加载的后续模块可见——它不起作用。出于好奇,为什么windows上不会出现这个问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-08
  • 1970-01-01
  • 2022-01-15
  • 2021-03-07
  • 2015-09-19
  • 2012-03-10
相关资源
最近更新 更多