lunarmodules / luasocket

Network support for the Lua language
http://lunarmodules.github.io/luasocket/
MIT License
1.85k stars 629 forks source link

lua 5.1 got this "Symbol not found: _luaL_openlib" #146

Closed idevz closed 9 years ago

idevz commented 9 years ago

like the title, In my lua 5.1 script, I wrote like this

local socket = require("socket.core")

then I get a Symbol mistake like

dlopen(/usr/local/luarocks-2.2.2/lib/lua/5.1/socket/core.so, 2): Symbol not found: _luaL_openlib

I install luasocket use the following command

luarocks install luasocket
luarocks list luasocket
Installed rocks:
----------------

luasocket
   3.0rc1-2 (installed) - /usr/local/luarocks-2.2.2/lib/luarocks/rocks
idevz commented 9 years ago

I couldn't load socket.core.so through all version of lua,here is my execute process

 /usr/local/luarocks-2.2.2/lib/lua/5.1/ [master] lua
Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
> local socket = require("socket.core")
error loading module 'socket.core' from file './socket/core.so':
    dlopen(./socket/core.so, 2): Symbol not found: _luaL_openlib
  Referenced from: ./socket/core.so
  Expected in: flat namespace
 in ./socket/core.so
stack traceback:
    [C]: ?
    [C]: in function 'require'
    stdin:1: in main chunk
    [C]: ?
> ^D
 /usr/local/luarocks-2.2.2/lib/lua/5.1/ [master] /usr/local/lua-5.2.3/bin/lua
Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> local socket = require("socket.core")
error loading module 'socket.core' from file './socket/core.so':
    dlopen(./socket/core.so, 6): Symbol not found: _luaL_prepbuffer
  Referenced from: ./socket/core.so
  Expected in: flat namespace
 in ./socket/core.so
stack traceback:
    [C]: in ?
    [C]: in function 'require'
    stdin:1: in main chunk
    [C]: in ?
> ^D
 /usr/local/luarocks-2.2.2/lib/lua/5.1/ [master] /usr/local/lua-5.3.1/bin/lua
Lua 5.3.1  Copyright (C) 1994-2015 Lua.org, PUC-Rio
> local socket = require("socket.core")
error loading module 'socket.core' from file './socket/core.so':
    dlopen(./socket/core.so, 6): Symbol not found: _luaL_openlib
  Referenced from: ./socket/core.so
  Expected in: flat namespace
 in ./socket/core.so
stack traceback:
    [C]: in ?
    [C]: in function 'require'
    stdin:1: in main chunk
    [C]: in ?
> ^D
 /usr/local/luarocks-2.2.2/lib/lua/5.1/ [master] tree ./socket
./socket
├── core.so
├── serial.so
└── unix.so

0 directories, 3 files
siffiejoe commented 9 years ago

A C extension module compiled for Lua 5.1 won't work with Lua 5.2 or 5.3, so no surprise for your last two attempts. The first one should have worked, though. One possible reason why it didn't: LuaSocket uses the luaL_openlib function from Lua 5.0. It should also be available on Lua 5.1 (and 5.2) if certain compatibility flags are defined in luaconf.h while building the Lua executable. This is the default when you build from source, but my guess is that your executable was built without it. For Lua 5.1 the define's name is LUA_COMPAT_OPENLIB. You can get the location of luaconf.h from the compiler command line when building LuaSocket or from site_config.lua in the LuaRocks directory tree (look for LUA_INCDIR).

@diegonehab: Is Lua 5.0 still supported by LuaSocket? If not, the use of luaL_openlib probably should be replaced by luaL_register ...

idevz commented 9 years ago

hi @siffiejoe thanks a lot for your detailed answer, But i still don't know how to fix this. I install luasocket through luarocks like luarocks install luasocket, and I also found LUA_COMPAT_OPENLIB in my luaconf.h , but I don't know how to make this compatibility flags work while building this Lua executable, What shoud I do then ?

diegonehab commented 9 years ago

I haven't tried with Lua 5.0 for a while. Maybe it works? It works well with 5.1, 5.2, and 5.3. It only uses luaL_openlib if LUA_COMPAT_MODULE is defined. Otherwise it uses lua_setfuncs. Take a look at luasocket.c.

siffiejoe commented 9 years ago

@idevz: First make sure that this is indeed the problem. Type

readelf -a /path/to/lua/exec | grep openlib

If it finds luaL_openlib, then this is not the problem. If it finds luaI_openlib (with a capital i) instead, you'll have to compile Lua yourself. You seem to have done so already for the newer Lua versions, so that shouldn't be a problem. You don't have to change anything in the Lua source code, LUA_COMPAT_OPENLIB is enabled by default (my guess is that your distribution disabled it).

@diegonehab: luaL_setfuncs is available in Lua 5.2+, luaL_openlib is available in Lua 5.0. Lua 5.1 has luaL_register instead (luaL_openlib is also available in 5.1 if LUA_COMPAT_OPENLIB was defined when building Lua, which is the default).

idevz commented 9 years ago

hi @siffiejoe @diegonehab ,thanks all of you guys, I met this mistake in my osx 10.10.4, under my lua 5.1,and install luasokect through luarocks2.2, I can find _luaL_openlib in my socket/core.so like this

 ~/Downloads/luasocket-master/ nm /usr/local/luarocks-2.2.2/lib/lua/5.1/socket/core.so | grep luaL_openlib
                 U _luaL_openlib

@diegonehab I found many compatibly works in luasocket like

 ~/Downloads/luasocket-master/ grep -nr luaL_openlib ./*
./gem/gem.c:52:    luaL_openlib(L, "gem", func, 0);
./src/except.c:123:    luaL_openlib(L, NULL, func, 0);
./src/inet.c:47:    luaL_openlib(L, NULL, func, 0);
./src/luasocket.c:90:        luaL_openlib(L, "socket", func, 0);
./src/mime.c:88:    luaL_openlib(L, "mime", func, 0);
./src/select.c:46:    luaL_openlib(L, NULL, func, 0);
./src/serial.c:79:    luaL_openlib(L, "socket", func, 0);
./src/tcp.c:114:    luaL_openlib(L, NULL, func, 0);
./src/timeout.c:150:    luaL_openlib(L, NULL, func, 0);
./src/udp.c:126:    luaL_openlib(L, NULL, func, 0);
./src/unix.c:97:    luaL_openlib(L, "socket", func, 0);

e.g as ./src/mime.c:88,

#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE)
    lua_newtable(L);
    luaL_setfuncs(L, func, 0);
#else
    luaL_openlib(L, "mime", func, 0);
#endif

it means when lua version big than 5.1 and !defined(LUA_COMPAT_MODULE) will use lua_setfuncs, my lua5.1 will use luaL_openlib? it's dependence on my lua5.1 was builded with LUA_COMPAT_OPENLIB defined? @siffiejoe you mean LUA_COMPAT_OPENLIB is a default defined val when lua 5.1 building?

siffiejoe commented 9 years ago

@Idevz: Yes, LUA_COMPAT_OPENLIB is the default when you compile Lua 5.1 from source. But I suspect that OSX, or Homebrew, or whatever, changed that. The nm trick is a good idea, but we already knew from the error message that socket/core.so has an undefined reference to luaL_openlib (that's what the U stands for). We want to know whether the Lua executable provides that function. nm /path/to/lua/executable | grep openlib should give you that information unless the executable was stripped, in which case you need the readelf command line I gave above (I'm not sure however, whether readelf is installed by default on OSX), or something equivalent that can read the exported symbols of a stripped ELF file.

idevz commented 9 years ago

@siffiejoe thank you for your enthusiastic answers, here is my Lua executable infos about luaL_openlib; using nm:

 // nm /usr/local/lua-5.1.5/bin/lua | grep luaL_openlib
0000000100022240 T _luaL_openlibs

using gobjdump:

 // gobjdump -ST /usr/local/lua-5.1.5/bin/lua| grep openlib
00000001000184e0      d  24 FUN    01 0000 _luaI_openlib
0000000100022240      d  24 FUN    01 0000 _luaL_openlibs
00000001000184e0 g       0f SECT   01 0000 [.text] _luaI_openlib
0000000100022240 g       0f SECT   01 0000 [.text] _luaL_openlibs
   100000fb3:   e8 88 12 02 00          callq  100022240 <_luaL_openlibs>
   1000184d7:   e9 04 00 00 00          jmpq   1000184e0 <_luaI_openlib>
00000001000184e0 <_luaI_openlib>:
   1000184fd:   0f 84 d5 00 00 00       je     1000185d8 <_luaI_openlib+0xf8>
   10001850a:   74 21                   je     10001852d <_luaI_openlib+0x4d>
   10001852b:   75 f3                   jne    100018520 <_luaI_openlib+0x40>
   100018566:   74 56                   je     1000185be <_luaI_openlib+0xde>
   10001858b:   74 14                   je     1000185a1 <_luaI_openlib+0xc1>
   1000185dc:   74 5c                   je     10001863a <_luaI_openlib+0x15a>
   1000185f9:   7e 14                   jle    10001860f <_luaI_openlib+0x12f>
   10001860d:   75 f1                   jne    100018600 <_luaI_openlib+0x120>
   100018638:   75 b6                   jne    1000185f0 <_luaI_openlib+0x110>
0000000100022240 <_luaL_openlibs>:

And I also found that LUA_COMPAT_OPENLIB was undefined in my builded lua 5.1:

 /usr/local/lua-5.1.5/include/ [master] tail /usr/local/lua-5.1.5/include/luaconf.h

#undef LUA_COMPAT_VARARG
#undef LUA_COMPAT_MOD
#undef LUA_COMPAT_LSTR
#undef LUA_COMPAT_GFIND
#undef LUA_COMPAT_OPENLIB

#endif

This is the real cause problem? I installed my lua5.1 by source code.

idevz commented 9 years ago

Hi @siffiejoe @diegonehab thank you very much for your guys warmhearted, After your advices, I finally solved this problem, The real cause this is the lua5.1 I use was build without compatibility with Lua 5.0, like I pasted above

 /usr/local/lua-5.1.5/include/ [master] tail /usr/local/lua-5.1.5/include/luaconf.h

#undef LUA_COMPAT_VARARG
#undef LUA_COMPAT_MOD
#undef LUA_COMPAT_LSTR
#undef LUA_COMPAT_GFIND
#undef LUA_COMPAT_OPENLIB

#endif

http://lua-users.org strongly recommend that Lua 5.1.5 be build without compatibility with Lua 5.0, this cause the problem, also to see this

diegonehab commented 9 years ago

Can you try the new push? I simplified the code.

diegonehab commented 9 years ago

BTW, Lua 5.0 is out. It would be too much of a pain to replace uses of # and ...

idevz commented 9 years ago

Hi @diegonehab , I reinstall luasocket with your new push based lua5.1,but i got another mistake:

 /Users/zj-lapis/ lapis
/usr/local/lua-5.1.5/bin/lua: ...cal/luarocks-2.2.2/share/lua/5.1/luarocks/loader.lua:117: error loading module 'socket.core' from file '/usr/local/luarocks-2.2.2/lib/lua/5.1/socket/core.so':
    dlopen(/usr/local/luarocks-2.2.2/lib/lua/5.1/socket/core.so, 2): Symbol not found: _luaL_setfuncs
  Referenced from: /usr/local/luarocks-2.2.2/lib/lua/5.1/socket/core.so
  Expected in: flat namespace
 in /usr/local/luarocks-2.2.2/lib/lua/5.1/socket/core.so
stack traceback:
    [C]: in function 'a_loader'
    ...cal/luarocks-2.2.2/share/lua/5.1/luarocks/loader.lua:117: in function <...cal/luarocks-2.2.2/share/lua/5.1/luarocks/loader.lua:114>
    (tail call): ?
    [C]: in function 'require'
    /usr/local/luarocks-2.2.2/share/lua/5.1/socket.lua:12: in main chunk
    [C]: in function 'require'
    ...sr/local/luarocks-2.2.2/share/lua/5.1/socket/url.lua:13: in main chunk
    [C]: in function 'require'
    ...sr/local/luarocks-2.2.2/share/lua/5.1/lapis/util.lua:1: in main chunk
    [C]: in function 'require'
    ...ocal/luarocks-2.2.2/share/lua/5.1/lapis/cmd/util.lua:7: in main chunk
    [C]: in function 'require'
    ...l/luarocks-2.2.2/share/lua/5.1/lapis/cmd/actions.lua:3: in main chunk
    [C]: in function 'require'
    ...cks-2.2.2/lib/luarocks/rocks/lapis/1.3.0-1/bin/lapis:7: in main chunk
    [C]: ?

here is my install command:

luarocks install https://raw.githubusercontent.com/diegonehab/luasocket/master/luasocket-scm-0.rockspec

My lua version is 5.1, but _luaL_setfuncs is used in lua 5.2, so...

diegonehab commented 9 years ago

Ah, I forgot to modify the rockspec. Just updated it. Can you try again? I don't use luarocks...

idevz commented 9 years ago

Hi @diegonehab, after you update the rockspec, I try it again, and it works, so awesome.