6

I'm having troubles trying to link my shared library(an erlang nif), to another shared library(libpurple), that loads other shared libraries(plugins) using dlopen.

The issue is that mylib.so links to libpurple.so, libpurple.so loads plugins.so using dlopen, and plugins.so can't find symbols from libpurple.so

1> mylib:init().
ok
2> /usr/lib/erlang/erts-6.3/bin/beam.smp: symbol lookup error: /usr/lib/purple-2/libmyspace.so: undefined symbol: purple_account_option_string_new

I'm compiling like:

gcc -fPIC -shared `pkg-config --cflags --libs purple` -I /usr/lib/erlang/erts-6.3/include -o priv/mylib.so c_src/mylib.c

It looks like the problem is with dlopen called on erlang:load_nif, this code has the same problem as the erlang nif, RTLD_NOW | RTLD_GLOBAL fixes it, but i can't change how erlang calls dlopen...

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

void (*purple_util_set_user_dir)(const char *dir);
void (*purple_debug_set_enabled)(gboolean enabled);
gboolean (*purple_core_init)(const char *ui);

int main()
{
  void* lib = dlopen("/usr/lib/libpurple.so", RTLD_LAZY);
  purple_util_set_user_dir = dlsym(lib, "purple_util_set_user_dir");
  purple_debug_set_enabled = dlsym(lib, "purple_debug_set_enabled");
  purple_core_init = dlsym(lib, "purple_core_init");

  purple_util_set_user_dir("/tmp/purpletest");
  purple_debug_set_enabled(TRUE);
  purple_core_init("test");

  return 0;
}

The only workaround that i get to work is calling erlang like LD_PRELOAD=/usr/lib/libpurple.so erl but is far from ideal.

Looks like the same problem, solved using RTLD_GLOBAL, https://developer.pidgin.im/ticket/7872

roger
  • 141
  • 1
  • 5

1 Answers1

0

The Erlang VM doesn't load NIF libraries with global symbols exposed for good reason - it would pollute the global namespace irretrievably.

Theoretically, and I don't know if this will always be true, the plugins should be able to dynamically load their parent library to look up its symbols without causing the OS to load another image of the library.

TedB
  • 346
  • 2
  • 5