How call function in lua library with dlsym - c

I am trying call a lua library runtime, so I made a lua lib in C
static int my_new(lua_State *L) {
printf("test_new");
}
LUALIB_API int luaopen_my(lua_State *L) {
static const luaL_Reg R[] =
{
{ "new", my_new },
{ NULL, NULL }
};
luaL_newmetatable(L,myNAME);
luaL_setfuncs(L,R,0);
lua_pushliteral(L,"version"); /** version */
lua_pushliteral(L,MYVERSION);
lua_settable(L,-3);
lua_pushliteral(L,"__index");
lua_pushvalue(L,-2);
lua_settable(L,-3);
return 1;
}
So I built it as a dynamic library, and I tried call doing it:
void *handle;
lua_CFunction fnc_call;
handle = dlopen("mylib.so", RTLD_LOCAL | RTLD_LAZY);
if (!handle) {
printf("error call lib");
exit(-1);
}
fnc_call = (lua_CFunction) dlsym(handle, "luaopen_my");
if (fnc_call == NULL) {
printf("error call func");
exit(-1);
}
luaL_requiref(L, "my", fnc_call, 1);
lua_pop(L, 1);
But when I call the Lua code that uses that I have a segmentation fault.
test = my.new()
How should I call a lib lua in my program, I know that is possible put my lib in some lua path and lua api call my libs, but I need to call it using dlopen.
Thanks,

I wager that since you are not returning a value from my_new, the function is returning a random value which tells Lua that there is some (random, possibly very high) number of objects returned on the stack. Since this is not true, when Lua clears that stack from return values it removes objects from the stack although none were added, likely removing more objects than there are on the stack, thus corrupting memory.
Add return 0 to my_new.

Related

c will a const *char function memory leak? [duplicate]

I am using json-c library to send json-object to client.And I notice there is no native function to release the memory which json_object_to_json_string allocate.Does the library release it automaticlly? OR I have to "free(str)" to avoid memory leak?
I tried to read its source code but it makes me unconscious...So anybody know this?
It seems that you don't need to free it manually.
I see that this buffer comes from within the json_object (see the last line of this function):
const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
{
if (!jso)
return "null";
if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
return NULL;
printbuf_reset(jso->_pb);
if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
return NULL;
return jso->_pb->buf;
}
The delete function frees this buffer:
static void json_object_generic_delete(struct json_object* jso)
{
#ifdef REFCOUNT_DEBUG
MC_DEBUG("json_object_delete_%s: %p\n",
json_type_to_name(jso->o_type), jso);
lh_table_delete(json_object_table, jso);
#endif /* REFCOUNT_DEBUG */
printbuf_free(jso->_pb);
free(jso);
}
It is important to understand that this buffer is only valid while the object is valid. If the object reaches 0 reference count, the string is also freed and if you are using it after it is freed the results are unpredictable.

set different memory allocation function in lua

I'm doing the exercises from the third edition of "Programming in Lua" book by Roberto Ierusalimschy. I have a problem with a bug in my solution to exercise 32.1. The statement is provided as comment in the code.
/*
Exercise 32.1:
Write a library that allows a script to limit the total amount of memory
used by its Lua state. It may offer a single function, setlimit, to set that
limit.
The library should set its own allocation funciton. This function, before
calling the original allocator, checks the total memory in use and returns
NULL if the requested memory exeeds the limit.
(Hint: the library can use lua_gc to initialize its byte count when it
starts. It also can use the user data of the allocation function to keep its
state: the byte count, the current memory limit, etc.; remember to use the
original user data when calling the original allocation function.)
*/
#ifdef WIN32
#define LUA_EXPORT __declspec(dllexport)
#else
#define LUA_EXPORT
#endif
#include <lauxlib.h>
typedef struct MemLimitUData
{
size_t mem_limit;
size_t currently_used;
lua_Alloc original_alloc;
void *original_ud;
}
MemLimitUData;
static int l_setlimit(lua_State *L)
{
MemLimitUData *ud;
size_t mem_limit = luaL_checkinteger(L, 1);
lua_getallocf(L, &ud);
ud->mem_limit = mem_limit;
return 0;
}
static int l_getlimit(lua_State *L)
{
MemLimitUData *ud;
lua_getallocf(L, &ud);
lua_pushnumber(L, ud->mem_limit);
return 1;
}
static void *l_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
MemLimitUData *udata = (MemLimitUData*)ud;
if (udata->mem_limit != 0 &&
udata->mem_limit < udata->currently_used - osize + nsize)
{
return NULL;
}
udata->currently_used += nsize - osize;
return udata->original_alloc(udata->original_ud, ptr, osize, nsize);
}
static const luaL_Reg memlimit[] =
{
{ "setlimit", l_setlimit },
{ "getlimit", l_getlimit },
{ NULL, NULL }
};
int LUA_EXPORT luaopen_memlimit(lua_State *L)
{
MemLimitUData *ud =
(MemLimitUData*)lua_newuserdata(L, sizeof(MemLimitUData));
ud->mem_limit = 0;
ud->currently_used =
lua_gc(L, LUA_GCCOUNT, 0) * 1024 + lua_gc(L, LUA_GCCOUNTB, 0);
ud->original_alloc = lua_getallocf(L, &ud->original_ud);
lua_setallocf(L, l_alloc, ud);
luaL_newlib(L, memlimit);
return 1;
}
When I build the source as memlimit.dll and use it from Lua script,
local memlimit = require"memlimit" the program crashes when the script ends. When I use debugger to look for the problem, the problematic statement seems to be in Lua internals. The file is lmem.c line 84:
newblock = (*g->frealloc)(g->ud, block, osize, nsize);
The used version of Lua is 5.2.3.
What wrong I do to break the Lua memory management ?
I haven't tried your code but here is what caught my attention when I read it:
The ud in luaopen_memlimit is created as userdata but is not anchored in Lua. Passing it to lua_getallocf does not count as anchoring. ud is probably being collected when the program ends via lua_close when it tries to free all data using your l_alloc. You should probably use plain malloc or the original allocf to create ud.

How to retrieve a returned string by C function in Lua script?

I have a Lua script which is calling a C function.
Currently this function is returning nothing.
I want to change this function to return a string, so at the end of this function in C I will push the string into Stack.
Inside the calling Lua script I need to get back the pushed string value.
C initialization and registration with Lua
void cliInitLua( void )
{
void* ud = NULL;
Task task;
// Create a new Lua state
L = lua_newstate(&luaAlloc, ud);
/* load various Lua libraries */
luaL_openlibs(L);
/*Register the function to be called from LUA script to execute commands*/
lua_register(L,"CliCmd",cli_handle_lua_commands);
//lua_close(L);
return;
}
This is my c Function to return a string:
static int cli_handle_lua_commands(lua_State *L){
...
...
char* str = ....; /*Char pointer to some string*/
lua_pushstring(L, str);
retun 1;
}
This is my Lua script
cliCmd("Anything here doesn't matter");
# I want to retreive the string str pushed in the c function.
In C you have something like
static int foo (lua_State *L) {
int n = lua_gettop(L);
//n is the number of arguments, use if needed
lua_pushstring(L, str); //str is the const char* that points to your string
return 1; //we are returning one value, the string
}
In Lua
lua_string = foo()
This assumes you have already registered your function with lua_register
Pleas see the great documentation for more examples on these sorts of tasks.

File IO in the apache portable runtime library

While working through Zed Shaw's learn C the Hard Way, I encountered the function apr_dir_make_recursive() which according to the documentation here has the type signature
apr_status_t apr_dir_make_recursive(const char *path, apr_fileperms_t perm, apr_pool_t *pool)
Which makes the directory, identical to the Unix command mkdir -p.
Why would the IO function need a memory pool in order to operate?
My first thought was that it was perhaps an optional argument to populate the newly made directory, however the code below uses an initialized but presumptively empty memory pool. Does this mean that the IO function itself needs a memory pool, that we are passing in for it to use? But that doesn't seem likely either; couldn't the function simply create a local memory pool for it to use which is then destroyed upon return or error?
So, what use is the memory pool? The documentation linked is unhelpful on this point.
Code shortened and shown below, for the curious.
int DB_init()
{
apr_pool_t *p = NULL;
apr_pool_initialize();
apr_pool_create(&p, NULL);
if(access(DB_DIR, W_OK | X_OK) == -1) {
apr_status_t rc = apr_dir_make_recursive(DB_DIR,
APR_UREAD | APR_UWRITE | APR_UEXECUTE |
APR_GREAD | APR_GWRITE | APR_GEXECUTE, p);
}
if(access(DB_FILE, W_OK) == -1) {
FILE *db = DB_open(DB_FILE, "w");
check(db, "Cannot open database: %s", DB_FILE);
DB_close(db);
}
apr_pool_destroy(p);
return 0;
}
If you pull up the source, you'll see: apr_dir_make_recursive() calls path_remove_last_component():
static char *path_remove_last_component (const char *path, apr_pool_t *pool)
{
const char *newpath = path_canonicalize (path, pool);
int i;
for (i = (strlen(newpath) - 1); i >= 0; i--) {
if (path[i] == PATH_SEPARATOR)
break;
}
return apr_pstrndup (pool, path, (i < 0) ? 0 : i);
}
This function is creating copies of the path in apr_pstrndup(), each representing a smaller component of it.
To answer your question - because of how it was implemented. Would it be possible to do the same without allocating memory, yes. I think in this case everything came out cleaner and more readable by copying the necessary path components.
The implementation of the function (found here) shows that the pool is used to allocate strings representing the individual components of the path.
The reason the function does not create its own local pool is because the pool may be reused across multiple calls to the apr_*() functions. It just so happens that DB_init() does not have a need to reuse an apr_pool_t.

Preventing too many LoadLibrary/FreeLibrary

I'm writing a proxy library (called Library A) that is just an interface to another DLL (called Library B) that may be present or not on the system.
The idea is that a program would link to this library A instead of the original library B ; and Library A would handle the errors if Library B wasn't installed on the system.
So a typical proxy function would look like this:
int function(int arg1, int arg2)
{
HINSTANCE hinstLib;
UINT errormode = SetErrorMode(SEM_FAILCRITICALERRORS);
SetErrorMode(errormode | SEM_FAILCRITICALERRORS);
hinstLib = LoadLibrary(TEXT(ORIGINAL_DLL));
SetErrorMode (errormode);
if (hinstLib != NULL)
{
ProcAdd = (void *) GetProcAddress(hinstLib, TEXT("function"));
if (NULL != ProcAdd)
{
return (ProcAdd) (arg1, arg2);
}
FreeLibrary(hinstLib);
}
return ERROR;
}
Now, I would do this for all original entries in Library B. There could be a lot of calls to it.
So loading / unloading the DLL so frequently is certainly going to have an impact speed-wise.
I was wondering if it would be acceptable to use a global variable hinstLib ; something like
HINSTANCE hinstLib = LoadLibrary(TEXT(ORIGINAL_DLL));
int function(int arg1, int arg2)
{
if (hinstLib != NULL)
{
ProcAdd = (void *) GetProcAddress(hinstLib, TEXT("function"));
if (NULL != ProcAdd)
{
return (ProcAdd) (arg1, arg2);
}
}
return ERROR;
}
And let Windows automatically unload the DLL when the program exits (assuming it does unload it).
Thanks in advance for your wise remarks...
Jean-Yves
Unless the unloading is particular use case, then this is fine. However I would implement some thread safety to ensure that there are no race conditions through this code using a Critical Section.
This is simillar example to the one from the wikipedia article
/* Sample C/C++, Windows, link to kernel32.dll */
#include <windows.h>
static CRITICAL_SECTION cs;
static HINSTANCE hinstLib = LoadLibrary(TEXT(ORIGINAL_DLL));
/* Initialize the critical section before entering multi-threaded context. */
InitializeCriticalSection(&cs);
void f() {
/* Enter the critical section -- other threads are locked out */
__try {
EnterCriticalSection(&cs);
if (hinstLib != NULL) {
ProcAdd = (void *) GetProcAddress(hinstLib, TEXT("function"));
} __finally {
LeaveCriticalSection(&cs);
}
if (NULL != ProcAdd) {
return (ProcAdd) (arg1, arg2);
}
}
.
.
.
/* Release system object when all finished -- usually at the end of the cleanup code */
DeleteCriticalSection(&cs);

Resources