Search code examples
clualinkerdlopen

Undefined symbol when calling from Lua


I have a lib, called "test.so" that uses functions from two libraries that reference each other. If I call the functions of test.so within a C program, it works just fine, so I assume there's no error in C functions.

However, when I call it from Lua, it throws a Seg Fault error due to an "undefined symbol". The problem is, the symbol is defined, I can see it when I run nm test.so.

Reading the thread below

Lua: C++ modules can't reference eachother, undefined symbol

I tried to creating a new module that would load test.so using dlopen, as described by Rena.

#include <lua.h>                               
#include <lauxlib.h>                           
#include <lualib.h>

#include <stdio.h>
#include <dlfcn.h>

int luaopen_drmaa(lua_State *L){
    printf("Chamou luaopen_test\n");
    if( dlopen("/home/erica/Downloads/test.so", RTLD_NOW | RTLD_GLOBAL) == NULL)
        printf("%s\n", dlerror());
    else
        printf("Chamou dlopen e teve retorno nao null\n");
    return 0;
}

I compiled it:

gcc -g drmaa_lib.c -shared -fpic -I /usr/include/lua5.1 -I /usr/local/include/ -L /usr/local/lib/m -llua5.1 -o drmaa.so

But when I run, I get:

$ lua5.1
Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
> require "drmaa"
Chamou luaopen_test
Chamou dlopen e teve retorno nao null
> submitJob()
stdin:1: attempt to call global 'submitJob' (a nil value)
stack traceback:
    stdin:1: in main chunk
    [C]: ?

Then I tried inserting in main function

luaopen_test(L);  

and above the main function

extern int luaopen_test(lua_State *L);

to actually open the lib, but I get this error:

$ lua5.1
Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
> require "drmaa"
error loading module 'drmaa' from file './drmaa.so':
    ./drmaa.so: undefined symbol: luaopen_test
stack traceback:
    [C]: ?
    [C]: in function 'require'
    stdin:1: in main chunk
    [C]: ?

The author of the referenced question doesn't show details of the development of the solution. Does anyone has a clue of what may make it work?

Thanks in advance.


Solution

  • I was obviously doing it wrong, to get the function that actually opens the library I should have used ldsym function. The new code for drmaa lib (the one that loads test.so) is

    #include <lua.h>                               
    #include <lauxlib.h>                           
    #include <lualib.h>
    
    #include <stdio.h>
    #include <dlfcn.h>
    
    typedef void Register(lua_State*);
    
    int luaopen_drmaa(lua_State *L){
    
        void* lib = dlopen("/home/erica/Downloads/test.so", RTLD_NOW | RTLD_GLOBAL);
        if(!lib)
        {
            printf("%s\n", dlerror());
            return 1;
        }
    
        Register* loadFunc = (Register*)dlsym(lib, "luaopen_test");
        if(!loadFunc)
        {
            printf("%s\n", dlerror());
            return 1;
        }
    
        loadFunc(L);
    
        return 0;
    }
    

    This answer was base in some code of this thread:

    Lua shared object loading with C++ segfaults