ports/108699: problem using user libraries with lua-5.0
Douglas Wells
sysmaint at contek.com
Fri Feb 2 21:50:20 UTC 2007
>Number: 108699
>Category: ports
>Synopsis: problem using user libraries with lua-5.0
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-ports-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Fri Feb 02 21:50:20 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator: Douglas Wells
>Release: FreeBSD 6.2-RELEASE i386
>Organization:
Connection Technoloties
>Environment:
System: FreeBSD flame.contek.com 6.2-RELEASE FreeBSD 6.2-RELEASE #0: Fri Jan 12 16:08:49 EST 2007 root at flame.contek.com:/var/obj/other5/src.6.2/sys/FLAME i386
I am using lua-5.0, updated today (lua-5.0.2_3). I have also
today loaded lua-5.1, but I haven't gotten the problem to work
yet. So, I am reporting the problem against 5.0, where I ran
into it.
>Description:
I am new to lua and recently loaded lua-5.0 on my system.
I noted that the standard language timing capabilities
were fairly poor port (one second resolution) and attempted
to write an extension to provide higher resolution. I
tried to follow the documentation (from manual.html), but
found that I was unable to load my library (via loadlib).
Chasing down the problem, I discovered that the default
interpreter (lua-5.0) was not able to resolve the lua API
functions while doing a dlopen. If, however, I did explicit
lookups of the functions, I could get my extension to
work.
Today I looked at the ports mail archives, and it appears
to me that use of shared libraries might be fairly new.
In any case, it seems to be that the lua interpreted is
likely loading the shared library with the lua language
APIs with the default loading parameters. I might guess
that it would be better if it were to use the RTLD_GLOBAL
flag to dlopen. I think that would allow the loadlib
function to resolve the lua APIs in my extension from the
language shared library.
>How-To-Repeat:
I include a test program and my extension code (in C). If
USE_DLOPEN is set to 0, the program fails; if it is set
to 1, the program works (at least according to my definition
of works):
Create the extension library:
gcc -c -I -I "/usr/local/include/lua50" c_funcs.c
gcc -shared -o libcfuncs.so c_funcs.o
Run the program:
lua-5.0 uclock.lua
The program should print out an array of current times
with appx. microsecond precision. Instead it aborts with
error message:
./libcfuncs.so: Undefined symbol "lua_pushnil" open
----------------- uclock.lua ---------------
#! /usr/local/bin/lua-5.0
print ("len of arg", table.getn (arg))
limit = tonumber (arg [1] or '20')
readuclock, err1, err2 = loadlib ("./libcfuncs.so", "readuclock")
print (readuclock, err1, err2)
assert (readuclock, "no libcfuncs.so / readuclock")
io.write ("Time values:\n")
tarr = {}
for i = 1, limit, 1 do
tarr[i] = readuclock()
end
prevval = 0
for i = 1, limit, 1 do
local thisval = tarr[i]
if (thisval ~= prevval) then
diff = thisval - prevval
io.write (string.format ("%d: %f usecs\n", i, diff * 1e6))
end
prevval = thisval
end
------------------ c_funcs.c -----------------------------
#define USE_DLOPEN 0
#include <stdio.h>
#include <unistd.h>
#include "lua.h"
#if USE_DLOPEN
# include <dlfcn.h>
# define LUALIBDIR "/usr/local/lib/lua50"
# define LUALIB "liblua.so"
#endif
#if USE_DLOPEN
typedef int (Lgettop_tp (lua_State *L));
typedef void (Lpushnil_tp (lua_State *L));
typedef void (Lpushnumber_tp (lua_State *L, lua_Number n));
typedef void (Lpushstring_tp (lua_State *L, const char *s));
void *
get_lualibhndl (void)
{
static const char *lualibpath = LUALIBDIR "/" LUALIB;
static void *libhndl;
if (libhndl == NULL)
{
libhndl = dlopen (lualibpath, RTLD_LAZY);
if (libhndl == NULL)
fprintf (stderr, "Loading %s\n", lualibpath);
}
return libhndl;
}
#endif
int
return_error (lua_State *L, const char *msg)
{
#if USE_DLOPEN
void *libhndl = get_lualibhndl ();
Lpushnil_tp *pushnilp = NULL;
Lpushstring_tp *pushstrp = NULL;
if (libhndl == NULL)
{
fprintf (stderr, "%s\n", msg);
return 0;
}
pushnilp = dlsym (libhndl, "lua_pushnil");
if (pushnilp == NULL)
{
fprintf (stderr, "%s\n", msg);
return 0;
}
pushstrp = dlsym (libhndl, "lua_pushstring");
if (pushstrp == NULL)
{
fprintf (stderr, "%s\n", msg);
return 0;
}
pushstrp (L, msg);
pushnilp (L);
#else
lua_pushnil (L);
lua_pushstring (L, msg);
#endif
return 2;
}
int
readuclock (lua_State *L)
{
#if USE_DLOPEN
void *libhndl = get_lualibhndl ();
Lgettop_tp *gettopp = NULL;
Lpushnumber_tp *pushnump = NULL;
int numargs;
#else
int numargs = lua_gettop (L);
#endif
double counter;
struct timeval tv;
#if USE_DLOPEN
if (libhndl == NULL)
return return_error (L, "no library");
gettopp = dlsym (libhndl, "lua_gettop");
if (gettopp == NULL)
return return_error (L, "Locating lua_gettop");
numargs = gettopp (L);
#endif
/* fprintf (stderr, "readuclock called\n"); */
gettimeofday (&tv);
counter = tv.tv_sec + (tv.tv_usec / 1e6);
#if USE_DLOPEN
pushnump = dlsym (libhndl, "lua_pushnumber");
if (pushnump == NULL)
if (gettopp == NULL)
return return_error (L, "Locating lua_pushnumber");
/* fprintf (stderr, "readuclock => %f\n", counter); */
pushnump (L, counter);
#else
lua_pushnumber (L, counter);
#endif
return 1;
}
----------------------------------------------------------
>Fix:
(Untested): Perhaps or in RTLD_GLOBAL in the call to dlopen in loadlib?
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-ports-bugs
mailing list