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