Ошибка компоновщика Lunatic Python lua.require ('socket') -> неопределенный символ: lua_getmetatable - PullRequest
5 голосов
/ 02 декабря 2011

У меня есть проект на python, основанный на некоторых файлах lua, один из которых требует 'socket'. Я получаю сообщение об ошибке при загрузке socket.core "undefined symbol: lua_getmetatable", когда пытаюсь запросить этот файл lua из python 2.7.

Простой репродуктор:

$ 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.1-socket2 в Ubuntu 11.04

Я получаю ту же ошибку, если использую основной исходный код lunatic-python и / или обновляюсь до luasocket 2.0.2 .

edit: Что вызывает эту ошибку и как ее исправить?

edit # 2: Вот вывод сборки luasocket-2.0.2. Марка по умолчанию не собирала 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'

1 Ответ

6 голосов
/ 06 декабря 2011

Проблема не в 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), но это не помогло, потому что к моменту вызова require из lua.so символы из liblua5.1.so уже были загружены локально для lua.so. Вот почему luasocket их не видит.

К счастью, Python позволяет изменять семантику dlopen с помощью модуля sys. Это позволяет принудительно загружать модули с 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...